All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] perf stat: Include PMU name and split uncore events per PMU in metric-only JSON output
@ 2026-07-15 20:30 Chun-Tse Shao
  2026-07-16  3:15 ` Ian Rogers
  0 siblings, 1 reply; 3+ messages in thread
From: Chun-Tse Shao @ 2026-07-15 20:30 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim
  Cc: Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers,
	Adrian Hunter, James Clark, linux-perf-users, linux-kernel,
	Chun-Tse Shao

When running `perf stat` with `-A` (--no-aggr) and `--metric-only` in
JSON output mode (`-j`), `perf stat` evaluates metric expressions
across all matching PMUs (including uncore PMUs like `uncore_iio_0`,
`uncore_iio_1`, etc.).

However, `perf stat` previously formatted JSON output by printing only
"cpu" : "<id>" and grouping all metric values on a single line per CPU
without identifying which PMU instance evaluated each metric. As a
result, when an uncore event spans multiple PMU boxes, `perf stat`
printed repeated, ambiguous metric keys without PMU names.

Fix this by:
1. Including "pmu" : "<pmu_name>" in print_aggr_id_json when evsel->pmu
   is a non-core or hybrid PMU in AGGR_NONE mode (-A).
2. Starting a new JSON metric line in AGGR_NONE mode (-A) whenever the
   underlying PMU instance changes across PMU events.
3. Updating perf_json_output_lint.py to recognize the new "pmu" key in
   the JSON test suite.

Example output:
  $ perf stat -M iio_bandwidth_read -a -A --metric-only -j -I 1000
  {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_0", "MB/s  iio_bandwidth_read" : "0.0"}
  {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_1", "MB/s  iio_bandwidth_read" : "0.1"}
  {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_11", "MB/s  iio_bandwidth_read" : "0.0"}
  ...
  {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_0", "MB/s  iio_bandwidth_read" : "0.0"}
  {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_1", "MB/s  iio_bandwidth_read" : "0.0"}
  {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_11", "MB/s  iio_bandwidth_read" : "0.0"}

Signed-off-by: Chun-Tse Shao <ctshao@google.com>
Assisted-by: Gemini:gemini-3.1-pro-preview
---

v2:
  - Fix print_metric_begin() initialization in print_no_aggr_metric()
    to ensure tool events always open lines cleanly.
  - Simplify and fix PMU line-split transition tracking when switching
    between different PMU instances or transitioning from tool events.
  - Add bounds check on aggr_map index in print_no_aggr_metric() to
    prevent out-of-bounds array reads if sysfs CPU topology is incomplete.

v1: lore.kernel.org/20260714174052.1826692-1-ctshao@google.com

 .../tests/shell/lib/perf_json_output_lint.py  |  1 +
 tools/perf/util/stat-display.c                | 48 ++++++++++++++-----
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/tools/perf/tests/shell/lib/perf_json_output_lint.py b/tools/perf/tests/shell/lib/perf_json_output_lint.py
index dafbde56cc76..36767905fcdb 100644
--- a/tools/perf/tests/shell/lib/perf_json_output_lint.py
+++ b/tools/perf/tests/shell/lib/perf_json_output_lint.py
@@ -64,6 +64,7 @@ def check_json_output(expected_items):
       'metric-threshold': lambda x: x in ['unknown', 'good', 'less good', 'nearly bad', 'bad'],
       'metricgroup': lambda x: True,
       'node': lambda x: True,
+      'pmu': lambda x: True,
       'pcnt-running': lambda x: isfloat(x),
       'socket': lambda x: True,
       'thread': lambda x: True,
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index f94f1324d24a..61d634f8be2e 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -397,6 +397,8 @@ static void print_aggr_id_json(struct perf_stat_config *config, struct outstate
 			json_out(os, "\"cpu\" : \"%d\"",
 				id.cpu.cpu);
 		}
+		if (evsel && evsel->pmu && (!evsel->pmu->is_core || evsel__is_hybrid(evsel)))
+			json_out(os, "\"pmu\" : \"%s\"", evsel->pmu->name);
 		break;
 	case AGGR_THREAD:
 		json_out(os, "\"thread\" : \"%s-%d\"",
@@ -1009,11 +1011,12 @@ static void print_counter_aggrdata(struct perf_stat_config *config,

 static void print_metric_begin(struct perf_stat_config *config,
 			       struct evlist *evlist,
-			       struct outstate *os, int aggr_idx)
+			       struct outstate *os, int aggr_idx,
+			       struct evsel *counter)
 {
 	struct perf_stat_aggr *aggr;
 	struct aggr_cpu_id id;
-	struct evsel *evsel;
+	struct evsel *evsel = counter ?: evlist__first(evlist);

 	os->first = true;
 	if (!config->metric_only)
@@ -1028,7 +1031,6 @@ static void print_metric_begin(struct perf_stat_config *config,
 		else
 			fprintf(config->output, "%s", os->timestamp);
 	}
-	evsel = evlist__first(evlist);
 	id = config->aggr_map->map[aggr_idx];
 	aggr = &evsel->stats->aggr[aggr_idx];
 	aggr_printout(config, os, evsel, id, aggr->nr);
@@ -1066,7 +1068,7 @@ static void print_aggr(struct perf_stat_config *config,
 	 * Without each counter has its own line.
 	 */
 	cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
-		print_metric_begin(config, evlist, os, aggr_idx);
+		print_metric_begin(config, evlist, os, aggr_idx, NULL);

 		evlist__for_each_entry(evlist, counter) {
 			print_counter_aggrdata(config, counter, aggr_idx, os);
@@ -1092,7 +1094,7 @@ static void print_aggr_cgroup(struct perf_stat_config *config,
 		os->cgrp = evsel->cgrp;

 		cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
-			print_metric_begin(config, evlist, os, aggr_idx);
+			print_metric_begin(config, evlist, os, aggr_idx, NULL);

 			evlist__for_each_entry(evlist, counter) {
 				if (counter->cgrp != os->cgrp)
@@ -1128,7 +1130,8 @@ static void print_no_aggr_metric(struct perf_stat_config *config,

 	perf_cpu_map__for_each_cpu(cpu, all_idx, evlist__core(evlist)->user_requested_cpus) {
 		struct evsel *counter;
-		bool first = true;
+		struct perf_pmu *last_pmu = NULL;
+		bool line_open = false;

 		evlist__for_each_entry(evlist, counter) {
 			u64 ena, run, val;
@@ -1143,13 +1146,34 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
 				if (config->aggr_map->map[aggr_idx].cpu.cpu == cpu.cpu)
 					break;
 			}
+			if (aggr_idx >= config->aggr_map->nr)
+				continue;

 			os->evsel = counter;
 			os->id = aggr_cpu_id__cpu(cpu, /*data=*/NULL);
-			if (first) {
-				print_metric_begin(config, evlist, os, aggr_idx);
-				first = false;
+
+			if (config->metric_only) {
+				struct perf_pmu *pmu = counter->pmu;
+
+				if (!evsel__is_tool(counter)) {
+					if (config->json_output && line_open &&
+					    (!last_pmu || pmu != last_pmu)) {
+						print_metric_end(config, os);
+						line_open = false;
+					}
+					if (!line_open) {
+						print_metric_begin(config, evlist, os,
+								   aggr_idx, counter);
+						line_open = true;
+					}
+					last_pmu = pmu;
+				} else if (!line_open) {
+					print_metric_begin(config, evlist, os,
+							   aggr_idx, counter);
+					line_open = true;
+				}
 			}
+
 			val = ps->aggr[aggr_idx].counts.val;
 			ena = ps->aggr[aggr_idx].counts.ena;
 			run = ps->aggr[aggr_idx].counts.run;
@@ -1157,7 +1181,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
 			uval = val * counter->scale;
 			printout(config, os, uval, run, ena, 1.0, aggr_idx);
 		}
-		if (!first)
+		if (line_open)
 			print_metric_end(config, os);
 	}
 }
@@ -1520,7 +1544,7 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist
 				print_metric_end(config, os);

 			os->cgrp = counter->cgrp;
-			print_metric_begin(config, evlist, os, /*aggr_idx=*/0);
+			print_metric_begin(config, evlist, os, /*aggr_idx=*/0, NULL);
 		}

 		print_counter(config, counter, os);
@@ -1570,7 +1594,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
 		} else if (config->cgroup_list) {
 			print_cgroup_counter(config, evlist, &os);
 		} else {
-			print_metric_begin(config, evlist, &os, /*aggr_idx=*/0);
+			print_metric_begin(config, evlist, &os, /*aggr_idx=*/0, NULL);
 			evlist__for_each_entry(evlist, counter) {
 				print_counter(config, counter, &os);
 			}
--
2.55.0.141.g00534a21ce-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] perf stat: Include PMU name and split uncore events per PMU in metric-only JSON output
  2026-07-15 20:30 [PATCH v2] perf stat: Include PMU name and split uncore events per PMU in metric-only JSON output Chun-Tse Shao
@ 2026-07-16  3:15 ` Ian Rogers
  2026-07-23  6:03   ` Namhyung Kim
  0 siblings, 1 reply; 3+ messages in thread
From: Ian Rogers @ 2026-07-16  3:15 UTC (permalink / raw)
  To: Chun-Tse Shao
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Adrian Hunter, James Clark, linux-perf-users, linux-kernel

On Wed, Jul 15, 2026 at 1:30 PM Chun-Tse Shao <ctshao@google.com> wrote:
>
> When running `perf stat` with `-A` (--no-aggr) and `--metric-only` in
> JSON output mode (`-j`), `perf stat` evaluates metric expressions
> across all matching PMUs (including uncore PMUs like `uncore_iio_0`,
> `uncore_iio_1`, etc.).
>
> However, `perf stat` previously formatted JSON output by printing only
> "cpu" : "<id>" and grouping all metric values on a single line per CPU
> without identifying which PMU instance evaluated each metric. As a
> result, when an uncore event spans multiple PMU boxes, `perf stat`
> printed repeated, ambiguous metric keys without PMU names.
>
> Fix this by:
> 1. Including "pmu" : "<pmu_name>" in print_aggr_id_json when evsel->pmu
>    is a non-core or hybrid PMU in AGGR_NONE mode (-A).
> 2. Starting a new JSON metric line in AGGR_NONE mode (-A) whenever the
>    underlying PMU instance changes across PMU events.
> 3. Updating perf_json_output_lint.py to recognize the new "pmu" key in
>    the JSON test suite.
>
> Example output:
>   $ perf stat -M iio_bandwidth_read -a -A --metric-only -j -I 1000
>   {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_0", "MB/s  iio_bandwidth_read" : "0.0"}
>   {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_1", "MB/s  iio_bandwidth_read" : "0.1"}
>   {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_11", "MB/s  iio_bandwidth_read" : "0.0"}
>   ...
>   {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_0", "MB/s  iio_bandwidth_read" : "0.0"}
>   {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_1", "MB/s  iio_bandwidth_read" : "0.0"}
>   {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_11", "MB/s  iio_bandwidth_read" : "0.0"}
>
> Signed-off-by: Chun-Tse Shao <ctshao@google.com>
> Assisted-by: Gemini:gemini-3.1-pro-preview

Reviewed-by: Ian Rogers <irogers@google.com>

Nit: It may be nice to include the before output (i.e., without the
PMU showing that differentiation isn't possible) in the commit
message.

Thanks,
Ian

> ---
>
> v2:
>   - Fix print_metric_begin() initialization in print_no_aggr_metric()
>     to ensure tool events always open lines cleanly.
>   - Simplify and fix PMU line-split transition tracking when switching
>     between different PMU instances or transitioning from tool events.
>   - Add bounds check on aggr_map index in print_no_aggr_metric() to
>     prevent out-of-bounds array reads if sysfs CPU topology is incomplete.
>
> v1: lore.kernel.org/20260714174052.1826692-1-ctshao@google.com
>
>  .../tests/shell/lib/perf_json_output_lint.py  |  1 +
>  tools/perf/util/stat-display.c                | 48 ++++++++++++++-----
>  2 files changed, 37 insertions(+), 12 deletions(-)
>
> diff --git a/tools/perf/tests/shell/lib/perf_json_output_lint.py b/tools/perf/tests/shell/lib/perf_json_output_lint.py
> index dafbde56cc76..36767905fcdb 100644
> --- a/tools/perf/tests/shell/lib/perf_json_output_lint.py
> +++ b/tools/perf/tests/shell/lib/perf_json_output_lint.py
> @@ -64,6 +64,7 @@ def check_json_output(expected_items):
>        'metric-threshold': lambda x: x in ['unknown', 'good', 'less good', 'nearly bad', 'bad'],
>        'metricgroup': lambda x: True,
>        'node': lambda x: True,
> +      'pmu': lambda x: True,
>        'pcnt-running': lambda x: isfloat(x),
>        'socket': lambda x: True,
>        'thread': lambda x: True,
> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
> index f94f1324d24a..61d634f8be2e 100644
> --- a/tools/perf/util/stat-display.c
> +++ b/tools/perf/util/stat-display.c
> @@ -397,6 +397,8 @@ static void print_aggr_id_json(struct perf_stat_config *config, struct outstate
>                         json_out(os, "\"cpu\" : \"%d\"",
>                                 id.cpu.cpu);
>                 }
> +               if (evsel && evsel->pmu && (!evsel->pmu->is_core || evsel__is_hybrid(evsel)))
> +                       json_out(os, "\"pmu\" : \"%s\"", evsel->pmu->name);
>                 break;
>         case AGGR_THREAD:
>                 json_out(os, "\"thread\" : \"%s-%d\"",
> @@ -1009,11 +1011,12 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
>
>  static void print_metric_begin(struct perf_stat_config *config,
>                                struct evlist *evlist,
> -                              struct outstate *os, int aggr_idx)
> +                              struct outstate *os, int aggr_idx,
> +                              struct evsel *counter)
>  {
>         struct perf_stat_aggr *aggr;
>         struct aggr_cpu_id id;
> -       struct evsel *evsel;
> +       struct evsel *evsel = counter ?: evlist__first(evlist);
>
>         os->first = true;
>         if (!config->metric_only)
> @@ -1028,7 +1031,6 @@ static void print_metric_begin(struct perf_stat_config *config,
>                 else
>                         fprintf(config->output, "%s", os->timestamp);
>         }
> -       evsel = evlist__first(evlist);
>         id = config->aggr_map->map[aggr_idx];
>         aggr = &evsel->stats->aggr[aggr_idx];
>         aggr_printout(config, os, evsel, id, aggr->nr);
> @@ -1066,7 +1068,7 @@ static void print_aggr(struct perf_stat_config *config,
>          * Without each counter has its own line.
>          */
>         cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
> -               print_metric_begin(config, evlist, os, aggr_idx);
> +               print_metric_begin(config, evlist, os, aggr_idx, NULL);
>
>                 evlist__for_each_entry(evlist, counter) {
>                         print_counter_aggrdata(config, counter, aggr_idx, os);
> @@ -1092,7 +1094,7 @@ static void print_aggr_cgroup(struct perf_stat_config *config,
>                 os->cgrp = evsel->cgrp;
>
>                 cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) {
> -                       print_metric_begin(config, evlist, os, aggr_idx);
> +                       print_metric_begin(config, evlist, os, aggr_idx, NULL);
>
>                         evlist__for_each_entry(evlist, counter) {
>                                 if (counter->cgrp != os->cgrp)
> @@ -1128,7 +1130,8 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
>
>         perf_cpu_map__for_each_cpu(cpu, all_idx, evlist__core(evlist)->user_requested_cpus) {
>                 struct evsel *counter;
> -               bool first = true;
> +               struct perf_pmu *last_pmu = NULL;
> +               bool line_open = false;
>
>                 evlist__for_each_entry(evlist, counter) {
>                         u64 ena, run, val;
> @@ -1143,13 +1146,34 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
>                                 if (config->aggr_map->map[aggr_idx].cpu.cpu == cpu.cpu)
>                                         break;
>                         }
> +                       if (aggr_idx >= config->aggr_map->nr)
> +                               continue;
>
>                         os->evsel = counter;
>                         os->id = aggr_cpu_id__cpu(cpu, /*data=*/NULL);
> -                       if (first) {
> -                               print_metric_begin(config, evlist, os, aggr_idx);
> -                               first = false;
> +
> +                       if (config->metric_only) {
> +                               struct perf_pmu *pmu = counter->pmu;
> +
> +                               if (!evsel__is_tool(counter)) {
> +                                       if (config->json_output && line_open &&
> +                                           (!last_pmu || pmu != last_pmu)) {
> +                                               print_metric_end(config, os);
> +                                               line_open = false;
> +                                       }
> +                                       if (!line_open) {
> +                                               print_metric_begin(config, evlist, os,
> +                                                                  aggr_idx, counter);
> +                                               line_open = true;
> +                                       }
> +                                       last_pmu = pmu;
> +                               } else if (!line_open) {
> +                                       print_metric_begin(config, evlist, os,
> +                                                          aggr_idx, counter);
> +                                       line_open = true;
> +                               }
>                         }
> +
>                         val = ps->aggr[aggr_idx].counts.val;
>                         ena = ps->aggr[aggr_idx].counts.ena;
>                         run = ps->aggr[aggr_idx].counts.run;
> @@ -1157,7 +1181,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
>                         uval = val * counter->scale;
>                         printout(config, os, uval, run, ena, 1.0, aggr_idx);
>                 }
> -               if (!first)
> +               if (line_open)
>                         print_metric_end(config, os);
>         }
>  }
> @@ -1520,7 +1544,7 @@ static void print_cgroup_counter(struct perf_stat_config *config, struct evlist
>                                 print_metric_end(config, os);
>
>                         os->cgrp = counter->cgrp;
> -                       print_metric_begin(config, evlist, os, /*aggr_idx=*/0);
> +                       print_metric_begin(config, evlist, os, /*aggr_idx=*/0, NULL);
>                 }
>
>                 print_counter(config, counter, os);
> @@ -1570,7 +1594,7 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
>                 } else if (config->cgroup_list) {
>                         print_cgroup_counter(config, evlist, &os);
>                 } else {
> -                       print_metric_begin(config, evlist, &os, /*aggr_idx=*/0);
> +                       print_metric_begin(config, evlist, &os, /*aggr_idx=*/0, NULL);
>                         evlist__for_each_entry(evlist, counter) {
>                                 print_counter(config, counter, &os);
>                         }
> --
> 2.55.0.141.g00534a21ce-goog
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] perf stat: Include PMU name and split uncore events per PMU in metric-only JSON output
  2026-07-16  3:15 ` Ian Rogers
@ 2026-07-23  6:03   ` Namhyung Kim
  0 siblings, 0 replies; 3+ messages in thread
From: Namhyung Kim @ 2026-07-23  6:03 UTC (permalink / raw)
  To: Ian Rogers, Chun-Tse Shao
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Adrian Hunter,
	James Clark, linux-perf-users, linux-kernel

On Wed, Jul 15, 2026 at 08:15:46PM -0700, Ian Rogers wrote:
> On Wed, Jul 15, 2026 at 1:30 PM Chun-Tse Shao <ctshao@google.com> wrote:
> >
> > When running `perf stat` with `-A` (--no-aggr) and `--metric-only` in
> > JSON output mode (`-j`), `perf stat` evaluates metric expressions
> > across all matching PMUs (including uncore PMUs like `uncore_iio_0`,
> > `uncore_iio_1`, etc.).
> >
> > However, `perf stat` previously formatted JSON output by printing only
> > "cpu" : "<id>" and grouping all metric values on a single line per CPU
> > without identifying which PMU instance evaluated each metric. As a
> > result, when an uncore event spans multiple PMU boxes, `perf stat`
> > printed repeated, ambiguous metric keys without PMU names.
> >
> > Fix this by:
> > 1. Including "pmu" : "<pmu_name>" in print_aggr_id_json when evsel->pmu
> >    is a non-core or hybrid PMU in AGGR_NONE mode (-A).
> > 2. Starting a new JSON metric line in AGGR_NONE mode (-A) whenever the
> >    underlying PMU instance changes across PMU events.
> > 3. Updating perf_json_output_lint.py to recognize the new "pmu" key in
> >    the JSON test suite.
> >
> > Example output:
> >   $ perf stat -M iio_bandwidth_read -a -A --metric-only -j -I 1000
> >   {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_0", "MB/s  iio_bandwidth_read" : "0.0"}
> >   {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_1", "MB/s  iio_bandwidth_read" : "0.1"}
> >   {"interval" : 1.000314908, "cpu" : "0", "pmu" : "uncore_iio_11", "MB/s  iio_bandwidth_read" : "0.0"}
> >   ...
> >   {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_0", "MB/s  iio_bandwidth_read" : "0.0"}
> >   {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_1", "MB/s  iio_bandwidth_read" : "0.0"}
> >   {"interval" : 1.000314908, "cpu" : "56", "pmu" : "uncore_iio_11", "MB/s  iio_bandwidth_read" : "0.0"}
> >
> > Signed-off-by: Chun-Tse Shao <ctshao@google.com>
> > Assisted-by: Gemini:gemini-3.1-pro-preview
> 
> Reviewed-by: Ian Rogers <irogers@google.com>
> 
> Nit: It may be nice to include the before output (i.e., without the
> PMU showing that differentiation isn't possible) in the commit
> message.

Hi CT, can you please update the commit message?  It'd be very helpful
for others to understand the problem.

Thanks,
Namhyung


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-23  6:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-15 20:30 [PATCH v2] perf stat: Include PMU name and split uncore events per PMU in metric-only JSON output Chun-Tse Shao
2026-07-16  3:15 ` Ian Rogers
2026-07-23  6:03   ` Namhyung Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.