Skip to content

Commit dc63398

Browse files
olsajiriIngo Molnar
authored andcommitted
perf: Do not POLLHUP event if it has children
Currently we return POLLHUP in event polling if the monitored process is done, but we didn't consider possible children, that might be still running and producing data. Before returning POLLHUP making sure that: 1) the monitored task has exited and that 2) we don't have any children to monitor Also adding parent wakeup when the child event is gone. Suggested-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: http://lkml.kernel.org/r/1410520708-19275-1-git-send-email-jolsa@kernel.org Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Stephane Eranian <eranian@google.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Stephane Eranian <eranian@google.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 4f7cf3a commit dc63398

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

kernel/events/core.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3587,6 +3587,19 @@ static int perf_event_read_one(struct perf_event *event,
35873587
return n * sizeof(u64);
35883588
}
35893589

3590+
static bool is_event_hup(struct perf_event *event)
3591+
{
3592+
bool no_children;
3593+
3594+
if (event->state != PERF_EVENT_STATE_EXIT)
3595+
return false;
3596+
3597+
mutex_lock(&event->child_mutex);
3598+
no_children = list_empty(&event->child_list);
3599+
mutex_unlock(&event->child_mutex);
3600+
return no_children;
3601+
}
3602+
35903603
/*
35913604
* Read the performance event - simple non blocking version for now
35923605
*/
@@ -3632,7 +3645,7 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
36323645

36333646
poll_wait(file, &event->waitq, wait);
36343647

3635-
if (event->state == PERF_EVENT_STATE_EXIT)
3648+
if (is_event_hup(event))
36363649
return events;
36373650

36383651
/*
@@ -7579,6 +7592,12 @@ static void sync_child_event(struct perf_event *child_event,
75797592
list_del_init(&child_event->child_list);
75807593
mutex_unlock(&parent_event->child_mutex);
75817594

7595+
/*
7596+
* Make sure user/parent get notified, that we just
7597+
* lost one event.
7598+
*/
7599+
perf_event_wakeup(parent_event);
7600+
75827601
/*
75837602
* Release the parent event, if this was the last
75847603
* reference to it.

0 commit comments

Comments
 (0)