From patchwork Fri Aug 16 02:30:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 13765371 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8F7632BCFF; Fri, 16 Aug 2024 02:30:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723775457; cv=none; b=uOwwx6rgyM4jrWZEIVJEQUJBOQVBaiUh/2T42FrdME8CHH4QU2nuCJTRHF5TU+sEE6GpL0j1q581SOxurNRiKpTTmvQIe8hgSPa7dDt0MlD3j9r9fSeQYhVuyUYgT+PMtB3hXh8+g+gZsY4Y91Dfxd8XAOb2hPxwhSn8/GeTsUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723775457; c=relaxed/simple; bh=PduHRgfMp3qDtlIlUMaJZfdj3y/ud8IXpCM0H4jkdiM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=twZjXFz04MCF0A/6gtUEC+E2MoBLH764/+wle8cmnGcUaRCE8dUWMYZr01a+ai87k70iFQolvB4SD8dfXQ/XpQp05rhVjSSmobsjVBfhnhU2uCLzcrXOODd5DHD/vHabuujM/wnIHbO/4LXKCBh4MROwBYZI7FNOmD+ouXPxN/A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iAbccZYx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iAbccZYx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69CEDC32786; Fri, 16 Aug 2024 02:30:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723775457; bh=PduHRgfMp3qDtlIlUMaJZfdj3y/ud8IXpCM0H4jkdiM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iAbccZYxaWhaeFcViKGQa+wUCLMNoc8ursc+Lr4Ivmk2rK8yLbGn8aPY5ieGIDCdi mX9lKVtEWem4jqhGff9axGQrzOwoIVMLaxRUOMqhoRZrHm0X7VJ1en4FRdP4m2TmEr ienbRwIs5DawHuz2Sd7UV2xtDRUTEz06zX4ExEgU2qtJK1/V/q1f93KtqbqObPNQGB JJtqbO92xmEWtwiOfj/uTnHsTEzJYrUU1PhD5+tdaLFwLgxgRj8WX75EcaWrhsh/Vu R3U721rRpDYX/RcqielLLDUHkL0GzbNcWKvcOXq3g+dKbhmUVhGe8zIzrrggnvVfNH +NrzOGRyvCA/A== From: "Masami Hiramatsu (Google)" To: Steven Rostedt , Shuah Khan Cc: Masami Hiramatsu , Tom Zanussi , Mathieu Desnoyers , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v4 1/3] tracing/hist: Add poll(POLLIN) support on hist file Date: Fri, 16 Aug 2024 11:30:53 +0900 Message-Id: <172377545331.67914.17102541159174518930.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <172377544331.67914.7474878424159759789.stgit@devnote2> References: <172377544331.67914.7474878424159759789.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Masami Hiramatsu (Google) Add poll syscall support on the `hist` file. The Waiter will be waken up when the histogram is updated with POLLIN. Currently, there is no way to wait for a specific event in userspace. So user needs to peek the `trace` periodicaly, or wait on `trace_pipe`. But that is not good idea to peek the `trace` for the event randomely happens. And `trace_pipe` is not coming back until a page is filled with events. This allows user to wait for a specific events on `hist` file. User can set a histogram trigger on the event which they want to monitor. And poll() on its `hist` file. Since this poll() returns POLLIN, the next poll() will return soon unless you do read() on hist file. NOTE: To read the hist file again, you must set the file offset to 0, but just for monitoring the event, you may not need to read the histogram. Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi --- include/linux/trace_events.h | 5 +++ kernel/trace/trace_events.c | 18 +++++++++ kernel/trace/trace_events_hist.c | 76 +++++++++++++++++++++++++++++++++++++- 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 42bedcddd511..f3ec67d34097 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -663,6 +663,11 @@ struct trace_event_file { struct trace_subsystem_dir *system; struct list_head triggers; +#ifdef CONFIG_HIST_TRIGGERS + struct irq_work hist_work; + wait_queue_head_t hist_wq; +#endif + /* * 32 bit flags: * bit 0: enabled diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 7266ec2a4eea..0f077b32eea4 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2972,6 +2972,20 @@ static bool event_in_systems(struct trace_event_call *call, return !*p || isspace(*p) || *p == ','; } +#ifdef CONFIG_HIST_TRIGGERS +/* + * Wake up waiter on the hist_wq from irq_work because the hist trigger + * may happen in any context. + */ +static void hist_event_irq_work(struct irq_work *work) +{ + struct trace_event_file *event_file; + + event_file = container_of(work, struct trace_event_file, hist_work); + wake_up_all(&event_file->hist_wq); +} +#endif + static struct trace_event_file * trace_create_new_event(struct trace_event_call *call, struct trace_array *tr) @@ -3004,6 +3018,10 @@ trace_create_new_event(struct trace_event_call *call, INIT_LIST_HEAD(&file->triggers); list_add(&file->list, &tr->events); refcount_set(&file->ref, 1); +#ifdef CONFIG_HIST_TRIGGERS + init_irq_work(&file->hist_work, hist_event_irq_work); + init_waitqueue_head(&file->hist_wq); +#endif return file; } diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 5f9119eb7c67..d27b60f54f68 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -5314,6 +5314,9 @@ static void event_hist_trigger(struct event_trigger_data *data, if (resolve_var_refs(hist_data, key, var_ref_vals, true)) hist_trigger_actions(hist_data, elt, buffer, rec, rbe, key, var_ref_vals); + + if (hist_data->event_file && wq_has_sleeper(&hist_data->event_file->hist_wq)) + irq_work_queue(&hist_data->event_file->hist_work); } static void hist_trigger_stacktrace_print(struct seq_file *m, @@ -5593,15 +5596,36 @@ static void hist_trigger_show(struct seq_file *m, n_entries, (u64)atomic64_read(&hist_data->map->drops)); } +struct hist_file_data { + struct file *file; + u64 last_read; +}; + +static u64 get_hist_hit_count(struct trace_event_file *event_file) +{ + struct hist_trigger_data *hist_data; + struct event_trigger_data *data; + u64 ret = 0; + + list_for_each_entry(data, &event_file->triggers, list) { + if (data->cmd_ops->trigger_type == ETT_EVENT_HIST) { + hist_data = data->private_data; + ret += atomic64_read(&hist_data->map->hits); + } + } + return ret; +} + static int hist_show(struct seq_file *m, void *v) { + struct hist_file_data *hist_file = m->private; struct event_trigger_data *data; struct trace_event_file *event_file; int n = 0, ret = 0; mutex_lock(&event_mutex); - event_file = event_file_file(m->private); + event_file = event_file_file(hist_file->file); if (unlikely(!event_file)) { ret = -ENODEV; goto out_unlock; @@ -5611,6 +5635,7 @@ static int hist_show(struct seq_file *m, void *v) if (data->cmd_ops->trigger_type == ETT_EVENT_HIST) hist_trigger_show(m, data, n++); } + hist_file->last_read = get_hist_hit_count(event_file); out_unlock: mutex_unlock(&event_mutex); @@ -5618,24 +5643,69 @@ static int hist_show(struct seq_file *m, void *v) return ret; } +static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wait) +{ + struct trace_event_file *event_file; + struct seq_file *m = file->private_data; + struct hist_file_data *hist_file = m->private; + __poll_t ret = 0; + + mutex_lock(&event_mutex); + + event_file = event_file_data(file); + if (!event_file) { + ret = EPOLLERR; + goto out_unlock; + } + + poll_wait(file, &event_file->hist_wq, wait); + + if (hist_file->last_read != get_hist_hit_count(event_file)) + ret = EPOLLIN | EPOLLRDNORM; + +out_unlock: + mutex_unlock(&event_mutex); + + return ret; +} + +static int event_hist_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = file->private_data; + struct hist_file_data *hist_file = m->private; + + kfree(hist_file); + return tracing_single_release_file_tr(inode, file); +} + static int event_hist_open(struct inode *inode, struct file *file) { + struct hist_file_data *hist_file; int ret; ret = tracing_open_file_tr(inode, file); if (ret) return ret; + hist_file = kzalloc(sizeof(*hist_file), GFP_KERNEL); + if (!hist_file) + return -ENOMEM; + hist_file->file = file; + /* Clear private_data to avoid warning in single_open() */ file->private_data = NULL; - return single_open(file, hist_show, file); + ret = single_open(file, hist_show, hist_file); + if (ret) + kfree(hist_file); + return ret; } const struct file_operations event_hist_fops = { .open = event_hist_open, .read = seq_read, .llseek = seq_lseek, - .release = tracing_single_release_file_tr, + .release = event_hist_release, + .poll = event_hist_poll, }; #ifdef CONFIG_HIST_TRIGGERS_DEBUG From patchwork Fri Aug 16 02:31:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 13765380 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F189F4EB45; Fri, 16 Aug 2024 02:31:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723775467; cv=none; b=ZY2N0s4vXAdJBwUS0GHlqFUzJ2k9/45w9sv32J0AeUW+Z5sBdXF+IfFGZTwJCid8pa/pX101D54bqqYMIBWZaBbtE5cQPpN/fFqa83TZo+yuQHywXIT/wifggYYdxEjZ8H05XI9nZ/aUgST3JXKBBq8ZchaF1rbvCg8TzHTbA8U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723775467; c=relaxed/simple; bh=Jur8XeuZlryZD5nLURpFedzGOoXyD7Nm8ATeE/V8NpA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=Wm0cLOX6Fx+/6E5rCG8VBw5y1lWnBvzzzRYecqVvboyceIV+OHb1U4Wre92HBHbIzg8eYmg/uV2IGP9b5ZskDWQvqXXNrpu86y6z856h3pC0CncDTu2SrT17RlBSXUgVlRPEXsAxBJFC092YLusYtqIdLUYzF52JrmITuh8++2M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KGlDJ1+C; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KGlDJ1+C" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AE88CC32786; Fri, 16 Aug 2024 02:31:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723775466; bh=Jur8XeuZlryZD5nLURpFedzGOoXyD7Nm8ATeE/V8NpA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KGlDJ1+Cg4gN6XQQH5zqKRQjexUvaBNEzaseDRQzSOS7qvBbYxIoQwL8IN2976/qr 6qbq+87LWNizZfkmG6bHYYNw+TdtZvVLJ3JlYRaLqf67kb81CVFAGyQaR4hhL9ed1j 5eeuJTsBfbWbeKtBR39dxPptLlAe/aZzFT8N2vNBV6b5Rs8PUHNROHm1ORNnMe669M 7EiA/M5mtUtv5sTqSsoEVtiUalFoxUu3mGGux+JrSvWV32R7/BgWPwTFZHaJsDFfPg dAR6SCkpjAJzvc0OVhG7HetjW4UV5G5THYXgVOzTsV4c/SUdJ9JQTOvR2Kx9xtI4dN u4wPd+SDTH0iA== From: "Masami Hiramatsu (Google)" To: Steven Rostedt , Shuah Khan Cc: Masami Hiramatsu , Tom Zanussi , Mathieu Desnoyers , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v4 2/3] tracing/hist: Support POLLPRI event for poll on histogram Date: Fri, 16 Aug 2024 11:31:02 +0900 Message-Id: <172377546253.67914.2712199451353378352.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <172377544331.67914.7474878424159759789.stgit@devnote2> References: <172377544331.67914.7474878424159759789.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Masami Hiramatsu (Google) Since POLLIN will not be flashed until read the hist file, user needs to repeat read() and poll() on hist for monitoring the event continuously. But the read() is somewhat redundant only for monitoring events. This add POLLPRI poll event on hist, this event returns when a histogram is updated after open(), poll() or read(). Thus it is possible to wait next event without read(). Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi --- kernel/trace/trace_events_hist.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index d27b60f54f68..d64aa34892e7 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -5599,6 +5599,7 @@ static void hist_trigger_show(struct seq_file *m, struct hist_file_data { struct file *file; u64 last_read; + u64 last_act; }; static u64 get_hist_hit_count(struct trace_event_file *event_file) @@ -5636,6 +5637,11 @@ static int hist_show(struct seq_file *m, void *v) hist_trigger_show(m, data, n++); } hist_file->last_read = get_hist_hit_count(event_file); + /* + * Update last_act too so that poll()/POLLPRI can wait for the next + * event after any syscall on hist file. + */ + hist_file->last_act = hist_file->last_read; out_unlock: mutex_unlock(&event_mutex); @@ -5649,6 +5655,7 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai struct seq_file *m = file->private_data; struct hist_file_data *hist_file = m->private; __poll_t ret = 0; + u64 cnt; mutex_lock(&event_mutex); @@ -5660,8 +5667,13 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai poll_wait(file, &event_file->hist_wq, wait); - if (hist_file->last_read != get_hist_hit_count(event_file)) - ret = EPOLLIN | EPOLLRDNORM; + cnt = get_hist_hit_count(event_file); + if (hist_file->last_read != cnt) + ret |= EPOLLIN | EPOLLRDNORM; + if (hist_file->last_act != cnt) { + hist_file->last_act = cnt; + ret |= EPOLLPRI; + } out_unlock: mutex_unlock(&event_mutex); @@ -5680,6 +5692,7 @@ static int event_hist_release(struct inode *inode, struct file *file) static int event_hist_open(struct inode *inode, struct file *file) { + struct trace_event_file *event_file; struct hist_file_data *hist_file; int ret; @@ -5690,13 +5703,25 @@ static int event_hist_open(struct inode *inode, struct file *file) hist_file = kzalloc(sizeof(*hist_file), GFP_KERNEL); if (!hist_file) return -ENOMEM; + + mutex_lock(&event_mutex); + event_file = event_file_data(file); + if (!event_file) { + ret = -ENODEV; + goto out_unlock; + } + hist_file->file = file; + hist_file->last_act = get_hist_hit_count(event_file); /* Clear private_data to avoid warning in single_open() */ file->private_data = NULL; ret = single_open(file, hist_show, hist_file); + +out_unlock: if (ret) kfree(hist_file); + mutex_unlock(&event_mutex); return ret; } From patchwork Fri Aug 16 02:31:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 13765381 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6337F6F303; Fri, 16 Aug 2024 02:31:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723775476; cv=none; b=Wwwomj/GS5J9wd2ipDgKbjxH2iF5DQ/6cWWx6+TLcTpU62rC5uXA1ff83+FhtUI3InMyM8/0EArvsC7spmuJqlJLr5EG3phet1ajAvQQD/nz0qQ2fghQrYKvu8N34+VKtnBAGR6u9PVbHTFoLU0Rnf16ms/f3xO5W3g0KHKZYeo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723775476; c=relaxed/simple; bh=eUqdbegloJVRhI7Abq4RTqVSpN1p8gz7njIesM5pElQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=bb7Zrh0eWYf6csOsrK/2XHCEMy+RaDhXug+aQd9ucSQMYy+OAFC1Y5sYwzIKgZn2E6f0fau+SZm7Uh5bpHwbpRkiJ6GoTEQJ0Gge0BJj2gxeODCSXZxF+VQNGkkgHGNJrRok9O3GAOmKc8cXJ2gK7NrhvAXAMu9RjKcltokMTaA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PRUgkJj8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PRUgkJj8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C29DC32786; Fri, 16 Aug 2024 02:31:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723775476; bh=eUqdbegloJVRhI7Abq4RTqVSpN1p8gz7njIesM5pElQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PRUgkJj86sVaa0pGfe/ECCfRRiXC2m0LcDD4BeBrjxmyqaGqjQZ1R7DPMqI5hPXwM Zp+HobtI5ZLpcxR11CqmRZuTKpWVbZS6WaG90xMlz6u52sfJgBrDgZ9MzUgxEbZi5Z vLw8TgeSXeoKyTMTyCxd2a5JPiKs8cRp6lFaaxqpqaEVkDK3t1Z4g7uA/Fi/dncSnQ 5/kYp6fGRCRwM0w2DNSlYs+FelNWufcGjEk/1jQiWB4DqvoPq5oyVPJbR0CxGM5UK4 N0a6OHYjn02sKUVfVU/TQFPJsIY0k2sivTyixV85Ctrb/WP8kLgZC/sXahVJpJRGgd bar8Iz4v9o8dw== From: "Masami Hiramatsu (Google)" To: Steven Rostedt , Shuah Khan Cc: Masami Hiramatsu , Tom Zanussi , Mathieu Desnoyers , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v4 3/3] selftests/tracing: Add hist poll() support test Date: Fri, 16 Aug 2024 11:31:12 +0900 Message-Id: <172377547205.67914.494998437883733530.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <172377544331.67914.7474878424159759789.stgit@devnote2> References: <172377544331.67914.7474878424159759789.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Masami Hiramatsu (Google) Add a testcase for poll() on hist file. This introduces a helper binary to the ftracetest, because there is no good way to reliably execute poll() on hist file. Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Shuah Khan --- Changes in v4: - Use getopt() in poll.c (command options are changed) - Update test code according to the new command options. Changes in v2: - Update poll command to support both of POLLIN and POLLPRI, and timeout. - Identify unsupported stable kernel if poll-in returns soon. - Test both of POLLIN and POLLPRI. --- tools/testing/selftests/ftrace/Makefile | 2 + tools/testing/selftests/ftrace/poll.c | 74 ++++++++++++++++++++ .../ftrace/test.d/trigger/trigger-hist-poll.tc | 74 ++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 tools/testing/selftests/ftrace/poll.c create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile index a1e955d2de4c..49d96bb16355 100644 --- a/tools/testing/selftests/ftrace/Makefile +++ b/tools/testing/selftests/ftrace/Makefile @@ -6,4 +6,6 @@ TEST_PROGS := ftracetest-ktap TEST_FILES := test.d settings EXTRA_CLEAN := $(OUTPUT)/logs/* +TEST_GEN_PROGS = poll + include ../lib.mk diff --git a/tools/testing/selftests/ftrace/poll.c b/tools/testing/selftests/ftrace/poll.c new file mode 100644 index 000000000000..584f159654b1 --- /dev/null +++ b/tools/testing/selftests/ftrace/poll.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Simple poll on a file. + * + * Copyright (c) 2024 Google LLC. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 4096 + +/* + * Usage: + * poll [-I|-P] [-t timeout] FILE + */ +int main(int argc, char *argv[]) +{ + struct pollfd pfd = {.events = POLLIN}; + char buf[BUFSIZE]; + int timeout = -1; + int ret, opt; + + while ((opt = getopt(argc, argv, "IPt:")) != -1) { + switch (opt) { + case 'I': + pfd.events = POLLIN; + break; + case 'P': + pfd.events = POLLPRI; + break; + case 't': + timeout = atoi(optarg); + break; + default: + fprintf(stderr, "Usage: %s [-I|-P] [-t timeout] FILE\n", + argv[0]); + return -1; + } + } + if (optind >= argc) { + fprintf(stderr, "Error: Polling file is not specified\n"); + return -1; + } + + pfd.fd = open(argv[optind], O_RDONLY); + if (pfd.fd < 0) { + fprintf(stderr, "failed to open %s", argv[optind]); + perror("open"); + return -1; + } + + /* Reset poll by read if POLLIN is specified. */ + if (pfd.events & POLLIN) + do {} while (read(pfd.fd, buf, BUFSIZE) == BUFSIZE); + + ret = poll(&pfd, 1, timeout); + if (ret < 0 && errno != EINTR) { + perror("poll"); + return -1; + } + close(pfd.fd); + + /* If timeout happned, return code is 0 */ + if (ret == 0) + return 1; + + return 0; +} diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc new file mode 100644 index 000000000000..cbd01a71ecad --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc @@ -0,0 +1,74 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: event trigger - test poll wait on histogram +# requires: set_event events/sched/sched_process_free/trigger events/sched/sched_process_free/hist +# flags: instance + +POLL=${FTRACETEST_ROOT}/poll + +if [ ! -x ${POLL} ]; then + echo "poll program is not compiled!" + exit_unresolved +fi + +EVENT=events/sched/sched_process_free/ + +# Check poll ops is supported. Before implementing poll on hist file, it +# returns soon with POLLIN | POLLOUT, but not POLLPRI. + +# This must wait >1 sec and return 1 (timeout). +set +e +${POLL} -I -t 1000 ${EVENT}/hist +ret=$? +set -e +if [ ${ret} != 1 ]; then + echo "poll on hist file is not supported" + exit_unsupported +fi + +# Test POLLIN +echo > trace +echo "hist:key=comm" > ${EVENT}/trigger +echo 1 > ${EVENT}/enable + +# This sleep command will exit after 2 seconds. +sleep 2 & +BGPID=$! +# if timeout happens, poll returns 1. +${POLL} -I -t 4000 ${EVENT}/hist +echo 0 > tracing_on + +if [ -d /proc/${BGPID} ]; then + echo "poll exits too soon" + kill -KILL ${BGPID} ||: + exit_fail +fi + +if ! grep -qw "sleep" trace; then + echo "poll exits before event happens" + exit_fail +fi + +# Test POLLPRI +echo > trace +echo 1 > tracing_on + +# This sleep command will exit after 2 seconds. +sleep 2 & +BGPID=$! +# if timeout happens, poll returns 1. +${POLL} -P -t 4000 ${EVENT}/hist +echo 0 > tracing_on + +if [ -d /proc/${BGPID} ]; then + echo "poll exits too soon" + kill -KILL ${BGPID} ||: + exit_fail +fi + +if ! grep -qw "sleep" trace; then + echo "poll exits before event happens" + exit_fail +fi + +exit_pass