Skip to content

Commit 66fc6f5

Browse files
mhiramatrostedt
authored andcommitted
tracing/hist: Support POLLPRI event for poll on histogram
Since POLLIN will not be flushed until the hist file is read, the user needs to repeatedly read() and poll() on the hist file for monitoring the event continuously. But the read() is somewhat redundant when the user is only monitoring for event updates. Add POLLPRI poll event on the hist file so the event returns when a histogram is updated after open(), poll() or read(). Thus it is possible to wait for the next event without having to issue a read(). Cc: Shuah Khan <shuah@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://lore.kernel.org/173527248770.464571.2536902137325258133.stgit@devnote2 Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Reviewed-by: Tom Zanussi <zanussi@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 1bd13ed commit 66fc6f5

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

kernel/trace/trace_events_hist.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5595,6 +5595,7 @@ static void hist_trigger_show(struct seq_file *m,
55955595
struct hist_file_data {
55965596
struct file *file;
55975597
u64 last_read;
5598+
u64 last_act;
55985599
};
55995600

56005601
static u64 get_hist_hit_count(struct trace_event_file *event_file)
@@ -5630,6 +5631,11 @@ static int hist_show(struct seq_file *m, void *v)
56305631
hist_trigger_show(m, data, n++);
56315632
}
56325633
hist_file->last_read = get_hist_hit_count(event_file);
5634+
/*
5635+
* Update last_act too so that poll()/POLLPRI can wait for the next
5636+
* event after any syscall on hist file.
5637+
*/
5638+
hist_file->last_act = hist_file->last_read;
56335639

56345640
return 0;
56355641
}
@@ -5639,6 +5645,8 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai
56395645
struct trace_event_file *event_file;
56405646
struct seq_file *m = file->private_data;
56415647
struct hist_file_data *hist_file = m->private;
5648+
__poll_t ret = 0;
5649+
u64 cnt;
56425650

56435651
guard(mutex)(&event_mutex);
56445652

@@ -5648,10 +5656,15 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai
56485656

56495657
hist_poll_wait(file, wait);
56505658

5651-
if (hist_file->last_read != get_hist_hit_count(event_file))
5652-
return EPOLLIN | EPOLLRDNORM;
5659+
cnt = get_hist_hit_count(event_file);
5660+
if (hist_file->last_read != cnt)
5661+
ret |= EPOLLIN | EPOLLRDNORM;
5662+
if (hist_file->last_act != cnt) {
5663+
hist_file->last_act = cnt;
5664+
ret |= EPOLLPRI;
5665+
}
56535666

5654-
return 0;
5667+
return ret;
56555668
}
56565669

56575670
static int event_hist_release(struct inode *inode, struct file *file)
@@ -5665,23 +5678,33 @@ static int event_hist_release(struct inode *inode, struct file *file)
56655678

56665679
static int event_hist_open(struct inode *inode, struct file *file)
56675680
{
5681+
struct trace_event_file *event_file;
56685682
struct hist_file_data *hist_file;
56695683
int ret;
56705684

56715685
ret = tracing_open_file_tr(inode, file);
56725686
if (ret)
56735687
return ret;
56745688

5689+
guard(mutex)(&event_mutex);
5690+
5691+
event_file = event_file_data(file);
5692+
if (!event_file)
5693+
return -ENODEV;
5694+
56755695
hist_file = kzalloc(sizeof(*hist_file), GFP_KERNEL);
56765696
if (!hist_file)
56775697
return -ENOMEM;
5698+
56785699
hist_file->file = file;
5700+
hist_file->last_act = get_hist_hit_count(event_file);
56795701

56805702
/* Clear private_data to avoid warning in single_open() */
56815703
file->private_data = NULL;
56825704
ret = single_open(file, hist_show, hist_file);
56835705
if (ret)
56845706
kfree(hist_file);
5707+
56855708
return ret;
56865709
}
56875710

0 commit comments

Comments
 (0)