Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf top: Expand the range of multithreaded phase

In __cmd_top(), perf_set_multithreaded() is used to enable
pthread_rwlock, thus down_read() and down_write () are not nops,
handling concurrency problems

Then 'perf top' uses perf_set_singlethreaded(), switching to the single
threaded phase, assuming that no thread concurrency will happen later.

However, a use after free problem could occur in the single threaded
phase, the concurrent procedure is this:

display_thread process_thread
-------------- --------------
thread__comm_len
-> thread__comm_str
-> __thread__comm_str(thread)
thread__delete
-> comm__free
-> comm_str__put
-> zfree(&cs->str)
-> thread->comm_len = strlen(comm);

Since in single thread phase, perf_singlethreaded is true, down_read()
and down_write() do nothing to avoid concurrency problems.

This patch moves the perf_set_singlethreaded() call to the function tail
to expand the multithreaded phase range, making display_thread() and
process_thread() concurrency safe.

Reviewed-by: Yunfeng Ye <yeyunfeng@huawei.com>
Signed-off-by: Hangliang Lai <laihangliang1@huawei.com>
Co-developed-by: Wenyu Liu <liuwenyu7@huawei.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Feilong Lin <linfeilong@huawei.com>
Cc: Hewenliang <hewenliang4@huawei.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20230411013224.2079-1-laihangliang1@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Hangliang Lai and committed by
Arnaldo Carvalho de Melo
eab50517 ed4da0d3

+2 -2
+2 -2
tools/perf/builtin-top.c
··· 1276 1276 top->evlist->core.threads, true, false, 1277 1277 top->nr_threads_synthesize); 1278 1278 1279 - if (top->nr_threads_synthesize > 1) 1280 - perf_set_singlethreaded(); 1279 + perf_set_multithreaded(); 1281 1280 1282 1281 if (perf_hpp_list.socket) { 1283 1282 ret = perf_env__read_cpu_topology_map(&perf_env); ··· 1354 1355 out_join_thread: 1355 1356 cond_signal(&top->qe.cond); 1356 1357 pthread_join(thread_process, NULL); 1358 + perf_set_singlethreaded(); 1357 1359 return ret; 1358 1360 } 1359 1361