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 evlist: Refactor evlist__scnprintf_evsels()

Switch output to using a strbuf so the storage can be resized.

Add a maximum size argument to avoid too much output that may happen for
uncore events.

Rename as scnprintf is no longer used.

Committer testing:

With the patch applied:

root@number:~# perf probe -x ~/bin/perf evlist__format_evsels
Added new event:
probe_perf:evlist_format_evsels (on evlist__format_evsels in /home/acme/bin/perf)

You can now use it in all perf tools, such as:

perf record -e probe_perf:evlist_format_evsels -aR sleep 1

root@number:~# perf probe -l
probe_perf:evlist_format_evsels (on evlist__format_evsels@util/evlist.c in /home/acme/bin/perf)
root@number:~# perf trace -e probe_perf:*/max-stack=10/ perf record -e cycles,instructions,cache-misses /tmp/bla
Failed to collect 'cycles,instructions,cache-misses' for the '/tmp/bla' workload: Permission denied
0.000 perf/3893011 probe_perf:evlist_format_evsels(__probe_ip: 6183397)
evlist__format_evsels (/home/acme/bin/perf)
__cmd_record (/home/acme/bin/perf)
cmd_record (/home/acme/bin/perf)
run_builtin (/home/acme/bin/perf)
handle_internal_command (/home/acme/bin/perf)
run_argv (/home/acme/bin/perf)
main (/home/acme/bin/perf)
__libc_start_call_main (/usr/lib64/libc.so.6)
__libc_start_main@@GLIBC_2.34 (/usr/lib64/libc.so.6)
_start (/home/acme/bin/perf)
root@number:~#

Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Dominique Martinet <asmadeus@codewreck.org>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Levi Yun <yeoreum.yun@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Weilin Wang <weilin.wang@intel.com>
Link: https://lore.kernel.org/r/20250402201549.4090305-4-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
f0f245ea a5efaf90

+21 -14
+6 -3
tools/perf/builtin-record.c
··· 51 51 #include "util/clockid.h" 52 52 #include "util/off_cpu.h" 53 53 #include "util/bpf-filter.h" 54 + #include "util/strbuf.h" 54 55 #include "asm/bug.h" 55 56 #include "perf.h" 56 57 #include "cputopo.h" ··· 2792 2791 record__auxtrace_snapshot_exit(rec); 2793 2792 2794 2793 if (forks && workload_exec_errno) { 2795 - char msg[STRERR_BUFSIZE], strevsels[2048]; 2794 + char msg[STRERR_BUFSIZE]; 2796 2795 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); 2796 + struct strbuf sb = STRBUF_INIT; 2797 2797 2798 - evlist__scnprintf_evsels(rec->evlist, sizeof(strevsels), strevsels); 2798 + evlist__format_evsels(rec->evlist, &sb, 2048); 2799 2799 2800 2800 pr_err("Failed to collect '%s' for the '%s' workload: %s\n", 2801 - strevsels, argv[0], emsg); 2801 + sb.buf, argv[0], emsg); 2802 + strbuf_release(&sb); 2802 2803 err = -1; 2803 2804 goto out_child; 2804 2805 }
+13 -10
tools/perf/util/evlist.c
··· 35 35 #include "util/util.h" 36 36 #include "util/env.h" 37 37 #include "util/intel-tpebs.h" 38 + #include "util/strbuf.h" 38 39 #include <signal.h> 39 40 #include <unistd.h> 40 41 #include <sched.h> ··· 2468 2467 return NULL; 2469 2468 } 2470 2469 2471 - int evlist__scnprintf_evsels(struct evlist *evlist, size_t size, char *bf) 2470 + void evlist__format_evsels(struct evlist *evlist, struct strbuf *sb, size_t max_length) 2472 2471 { 2473 2472 struct evsel *evsel; 2474 - int printed = 0; 2473 + bool first = true; 2475 2474 2476 2475 evlist__for_each_entry(evlist, evsel) { 2477 2476 if (evsel__is_dummy_event(evsel)) 2478 2477 continue; 2479 - if (size > (strlen(evsel__name(evsel)) + (printed ? 2 : 1))) { 2480 - printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "," : "", evsel__name(evsel)); 2481 - } else { 2482 - printed += scnprintf(bf + printed, size - printed, "%s...", printed ? "," : ""); 2483 - break; 2484 - } 2485 - } 2486 2478 2487 - return printed; 2479 + if (!first) 2480 + strbuf_addch(sb, ','); 2481 + 2482 + if (sb->len > max_length) { 2483 + strbuf_addstr(sb, "..."); 2484 + return; 2485 + } 2486 + strbuf_addstr(sb, evsel__name(evsel)); 2487 + first = false; 2488 + } 2488 2489 } 2489 2490 2490 2491 void evlist__check_mem_load_aux(struct evlist *evlist)
+2 -1
tools/perf/util/evlist.h
··· 20 20 struct thread_map; 21 21 struct perf_cpu_map; 22 22 struct record_opts; 23 + struct strbuf; 23 24 struct target; 24 25 25 26 /* ··· 431 430 432 431 struct evsel *evlist__find_evsel(struct evlist *evlist, int idx); 433 432 434 - int evlist__scnprintf_evsels(struct evlist *evlist, size_t size, char *bf); 433 + void evlist__format_evsels(struct evlist *evlist, struct strbuf *sb, size_t max_length); 435 434 void evlist__check_mem_load_aux(struct evlist *evlist); 436 435 void evlist__warn_user_requested_cpus(struct evlist *evlist, const char *cpu_list); 437 436 void evlist__uniquify_name(struct evlist *evlist);