Re: [PATCH v3] perf stat: Include PMU name and split uncore events per PMU in metric-only JSON output
Chun-Tse Shao <[email protected]> Tue, 4 Aug 2026 14:09:21 -0700
| Newsgroups | org.kernel.vger.linux-perf-users,dev.linux.lists.sashiko-reviews |
|---|---|
| Message-ID | <CAJpZYjW3L-E6rhxLg8etDJYbg2XbZ--aH8pP131Gv4WECaDxLg@mail.gmail.com> |
On Fri, Jul 31, 2026 at 4:14=E2=80=AFPM Namhyung Kim <[email protected]> = wrote: > > On Wed, Jul 29, 2026 at 05:17:41PM +0000, [email protected] wrote: > > Thank you for your contribution! Sashiko AI review found 1 potential is= sue(s) to consider: > > - [Medium] Flawed line-split transition logic causes spurious empty JSO= N objects and incorrect PMU attribution for tool events. > > -- > > > > --- Patch [1]: [PATCH v3] perf stat: Include PMU name and split uncore = events per PMU in metric-only JSON output --- > > commit 20e3cd08fd5e415b458343262ee76bc1f5f6ce85 > > Author: Chun-Tse Shao <[email protected]> > > > > perf stat: Include PMU name and split uncore events per PMU in metric-o= nly JSON output > > > > This commit modifies perf stat JSON output in --metric-only and -A mode= to > > group metrics by PMU. It achieves this by adding a "pmu" key to the JSO= N > > output and starting a new JSON line when the underlying PMU instance ch= anges. > > > > > diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-di= splay.c > > > index b337cc23f4131..6785e2c442bd7 100644 > > > --- a/tools/perf/util/stat-display.c > > > +++ b/tools/perf/util/stat-display.c > > > > [ ... ] > > > > > @@ -1146,13 +1149,34 @@ static void print_no_aggr_metric(struct perf_= stat_config *config, > > > if (config->aggr_map->map[aggr_idx].cpu.c= pu =3D=3D cpu.cpu) > > > break; > > > } > > > + if (aggr_idx >=3D config->aggr_map->nr) > > > + continue; > > > > > > os->evsel =3D counter; > > > os->id =3D aggr_cpu_id__cpu(cpu, /*data=3D*/NULL)= ; > > > - if (first) { > > > - print_metric_begin(config, evlist, os, ag= gr_idx); > > > - first =3D false; > > > + > > > + if (config->metric_only) { > > > + struct perf_pmu *pmu =3D counter->pmu; > > > + > > > + if (!evsel__is_tool(counter)) { > > > + if (config->json_output && line_o= pen && > > > + (!last_pmu || pmu !=3D last_p= mu)) { > > > > [Severity: Medium] > > Does this line-split transition logic handle tool events correctly depe= nding > > on their order in the event list? > > > > If a tool event is processed first, line_open becomes true, but last_pm= u > > remains NULL. When the next event (a PMU event) is processed, the condi= tion > > (!last_pmu || pmu !=3D last_pmu) evaluates to true. This prematurely cl= oses > > the line and creates a spurious empty JSON object for the tool event. > > Something like this? > > $ sudo ./perf stat -aA -e user_time -M insn_per_cycle -j --metric-only = true > {"cpu" : "0", "pmu" : "tool"} > {"cpu" : "0", "pmu" : "cpu_core", "instructions insn_per_cycle" : "0.8= "} > {"cpu" : "1", "pmu" : "tool"} > {"cpu" : "1", "pmu" : "cpu_core", "instructions insn_per_cycle" : "0.1= "} > {"cpu" : "2", "pmu" : "tool"} > {"cpu" : "2", "pmu" : "cpu_core", "instructions insn_per_cycle" : "0.5= "} > {"cpu" : "3", "pmu" : "tool"} > {"cpu" : "3", "pmu" : "cpu_core", "instructions insn_per_cycle" : "0.3= "} > ... > > Thanks, > Namhyung Thanks for the test, I sent the v4 patch for fixing this problem: lore.kernel.org/[email protected] Test: $ perf stat -aA -e user_time -M insn_per_cycle -j --metric-only true {"cpu" : "0", "instructions insn_per_cycle" : "0.9"} {"cpu" : "1", "instructions insn_per_cycle" : "0.6"} {"cpu" : "2", "instructions insn_per_cycle" : "0.2"} {"cpu" : "3", "instructions insn_per_cycle" : "0.1"} {"cpu" : "4", "instructions insn_per_cycle" : "0.2"} {"cpu" : "5", "instructions insn_per_cycle" : "0.1"} {"cpu" : "6", "instructions insn_per_cycle" : "0.1"} {"cpu" : "7", "instructions insn_per_cycle" : "0.1"} {"cpu" : "8", "instructions insn_per_cycle" : "0.1"} {"cpu" : "9", "instructions insn_per_cycle" : "0.1"} ... -CT > > > > > Conversely, if a tool event comes after a PMU event, the else-if block = below > > is taken because !evsel__is_tool(counter) evaluates to false. This bypa= sses > > the line-splitting check entirely, causing the tool event to silently m= erge > > into the preceding PMU's JSON object and incorrectly inherit its PMU > > attribution. > > > > > + print_metric_end(config, = os); > > > + line_open =3D false; > > > + } > > > + if (!line_open) { > > > + print_metric_begin(config= , evlist, os, > > > + aggr_i= dx, counter); > > > + line_open =3D true; > > > + } > > > + last_pmu =3D pmu; > > > + } else if (!line_open) { > > > + print_metric_begin(config, evlist= , os, > > > + aggr_idx, coun= ter); > > > + line_open =3D true; > > > + } > > > } > > > > -- > > Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260729170416.= [email protected]?part=3D1