perf record: Filter out POLLHUP'ed file descriptors

So that we don't continue polling on vanished file descriptors, i.e.
file descriptors for events monitoring threads that exited.

I.e. the following 'perf record' command now exits as expected, instead
of staying in an eternal loop:

  $ sleep 5s &
  $ perf record -p `pidof sleep`
Reported-by: default avatarJiri Olsa <jolsa@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-8dg8o21t2ntzly2bfh53p3sg@git.kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e4b356b5
...@@ -308,7 +308,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) ...@@ -308,7 +308,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
struct record_opts *opts = &rec->opts; struct record_opts *opts = &rec->opts;
struct perf_data_file *file = &rec->file; struct perf_data_file *file = &rec->file;
struct perf_session *session; struct perf_session *session;
bool disabled = false; bool disabled = false, draining = false;
rec->progname = argv[0]; rec->progname = argv[0];
...@@ -457,7 +457,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) ...@@ -457,7 +457,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
} }
if (hits == rec->samples) { if (hits == rec->samples) {
if (done) if (done || draining)
break; break;
err = perf_evlist__poll(rec->evlist, -1); err = perf_evlist__poll(rec->evlist, -1);
/* /*
...@@ -467,6 +467,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) ...@@ -467,6 +467,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
if (err > 0 || (err < 0 && errno == EINTR)) if (err > 0 || (err < 0 && errno == EINTR))
err = 0; err = 0;
waking++; waking++;
if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
draining = true;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment