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

perf metricgroups: Add NO_THRESHOLD_AND_NMI constraint

Thresholds can increase the number of counters a metric needs. The NMI
watchdog can take away a counter (hopefully the buddy watchdog will
become the default and this will no longer be true). Add a new
constraint for the case that a metric and its thresholds would fit in
counters but only if the NMI watchdog isn't enabled. Either the
threshold or the NMI watchdog should be disabled to make the metric
fit. Wire this up into the metric__group_events logic.

Signed-off-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250719030517.1990983-16-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
fcc7cc31 8dcd27b1

+23 -8
+1
tools/perf/pmu-events/jevents.py
··· 235 235 'NO_GROUP_EVENTS_NMI': '2', 236 236 'NO_NMI_WATCHDOG': '2', 237 237 'NO_GROUP_EVENTS_SMT': '3', 238 + 'NO_THRESHOLD_AND_NMI': '4', 238 239 } 239 240 return metric_constraint_to_enum[metric_constraint] 240 241
+10 -4
tools/perf/pmu-events/pmu-events.h
··· 25 25 */ 26 26 MetricNoGroupEvents = 1, 27 27 /** 28 - * @MetricNoGroupEventsNmi: Don't group events for the metric if the NMI 29 - * watchdog is enabled. 28 + * @MetricNoGroupEventsNmi: 29 + * Don't group events for the metric if the NMI watchdog is enabled. 30 30 */ 31 31 MetricNoGroupEventsNmi = 2, 32 32 /** 33 - * @MetricNoGroupEventsSmt: Don't group events for the metric if SMT is 34 - * enabled. 33 + * @MetricNoGroupEventsSmt: 34 + * Don't group events for the metric if SMT is enabled. 35 35 */ 36 36 MetricNoGroupEventsSmt = 3, 37 + /** 38 + * @MetricNoGroupEventsThresholdAndNmi: 39 + * Don't group events for the metric thresholds and if the NMI watchdog 40 + * is enabled. 41 + */ 42 + MetricNoGroupEventsThresholdAndNmi = 4, 37 43 }; 38 44 /* 39 45 * Describe each PMU event. Each CPU has a table of PMU events.
+12 -4
tools/perf/util/metricgroup.c
··· 179 179 " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); 180 180 } 181 181 182 - static bool metric__group_events(const struct pmu_metric *pm) 182 + static bool metric__group_events(const struct pmu_metric *pm, bool metric_no_threshold) 183 183 { 184 184 switch (pm->event_grouping) { 185 185 case MetricNoGroupEvents: ··· 191 191 return false; 192 192 case MetricNoGroupEventsSmt: 193 193 return !smt_on(); 194 + case MetricNoGroupEventsThresholdAndNmi: 195 + if (metric_no_threshold) 196 + return true; 197 + if (!sysctl__nmi_watchdog_enabled()) 198 + return true; 199 + metric__watchdog_constraint_hint(pm->metric_name, /*foot=*/false); 200 + return false; 194 201 case MetricGroupEvents: 195 202 default: 196 203 return true; ··· 219 212 static struct metric *metric__new(const struct pmu_metric *pm, 220 213 const char *modifier, 221 214 bool metric_no_group, 215 + bool metric_no_threshold, 222 216 int runtime, 223 217 const char *user_requested_cpu_list, 224 218 bool system_wide) ··· 254 246 } 255 247 m->pctx->sctx.runtime = runtime; 256 248 m->pctx->sctx.system_wide = system_wide; 257 - m->group_events = !metric_no_group && metric__group_events(pm); 249 + m->group_events = !metric_no_group && metric__group_events(pm, metric_no_threshold); 258 250 m->metric_refs = NULL; 259 251 m->evlist = NULL; 260 252 ··· 839 831 * This metric is the root of a tree and may reference other 840 832 * metrics that are added recursively. 841 833 */ 842 - root_metric = metric__new(pm, modifier, metric_no_group, runtime, 843 - user_requested_cpu_list, system_wide); 834 + root_metric = metric__new(pm, modifier, metric_no_group, metric_no_threshold, 835 + runtime, user_requested_cpu_list, system_wide); 844 836 if (!root_metric) 845 837 return -ENOMEM; 846 838