Messages in this thread Patch in this message | | | Subject | [PATCH v2 12/15] perf record: introduce thread local variable for trace streaming | From | Alexey Budankov <> | Date | Wed, 21 Oct 2020 19:07:00 +0300 |
| |
Introduce thread local variable and use it for threaded trace streaming.
Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com> --- tools/perf/builtin-record.c | 71 ++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 9 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 89cb8e913fb3..3b7e9026f25b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -101,6 +101,8 @@ struct thread_data { u64 bytes_written; }; +static __thread struct thread_data *thread; + struct record { struct perf_tool tool; struct record_opts opts; @@ -587,7 +589,11 @@ static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size) } } - rec->samples++; + if (thread) + thread->samples++; + else + rec->samples++; + return record__write(rec, map, bf, compressed); } @@ -1258,6 +1264,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, int i; int rc = 0; struct mmap *maps; + int nr_mmaps; int trace_fd = rec->data.file.fd; off_t off = 0; @@ -1265,6 +1272,14 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, return 0; maps = overwrite ? evlist->overwrite_mmap : evlist->mmap; + nr_mmaps = evlist->core.nr_mmaps; + + if (thread) { + bytes_written = thread->bytes_written; + maps = thread->maps; + nr_mmaps = thread->nr_mmaps; + } + if (!maps) return 0; @@ -1274,7 +1289,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, if (record__aio_enabled(rec)) off = record__aio_get_pos(trace_fd); - for (i = 0; i < evlist->core.nr_mmaps; i++) { + for (i = 0; i < nr_mmaps; i++) { u64 flush = 0; struct mmap *map = &maps[i]; @@ -1323,7 +1338,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, * because per-cpu maps and files have data * sorted by kernel. */ - if (!record__threads_enabled(rec) && bytes_written != rec->bytes_written) + if (!thread && bytes_written != rec->bytes_written) rc = record__write(rec, NULL, &finished_round_event, sizeof(finished_round_event)); if (overwrite) @@ -1343,6 +1358,15 @@ static int record__mmap_read_all(struct record *rec, bool synch) return record__mmap_read_evlist(rec, rec->evlist, true, synch); } +static void record__thread_munmap_filtered(struct fdarray *fda, int fd, + void *arg __maybe_unused) +{ + struct perf_mmap *map = fda->priv[fd].ptr; + + if (map) + perf_mmap__put(map); +} + static void record__init_features(struct record *rec) { struct perf_session *session = rec->session; @@ -2020,7 +2044,12 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) trigger_ready(&switch_output_trigger); perf_hooks__invoke_record_start(); for (;;) { - unsigned long long hits = rec->samples; + unsigned long long hits0, hits1; + + if (thread) + hits0 = thread->samples; + else + hits0 = rec->samples; /* * rec->evlist->bkw_mmap_state is possible to be @@ -2089,20 +2118,44 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) alarm(rec->switch_output.time); } - if (hits == rec->samples) { + if (thread) + hits1 = thread->samples; + else + hits1 = rec->samples; + + if (hits0 == hits1) { if (done || draining) break; - err = evlist__poll(rec->evlist, -1); + + if (thread) + err = fdarray__poll(&thread->pollfd, -1); + else + err = evlist__poll(rec->evlist, -1); /* * Propagate error, only if there's any. Ignore positive * number of returned events and interrupt error. */ if (err > 0 || (err < 0 && errno == EINTR)) err = 0; - waking++; - if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) - draining = true; + if (thread) { + thread->waking++; + if (thread->ctlfd_pos != -1) { + evlist__ctlfd_update(rec->evlist, + &(thread->pollfd.entries[thread->ctlfd_pos])); + } + } else { + waking++; + } + + if (thread) { + if (fdarray__filter(&thread->pollfd, POLLERR | POLLHUP, + record__thread_munmap_filtered, NULL) == 0) + draining = true; + } else { + if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0) + draining = true; + } } if (evlist__ctlfd_process(rec->evlist, &cmd) > 0) { -- 2.24.1
| |