mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

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>
141 lines
4.4 KiB
C
141 lines
4.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef PMU_EVENTS_H
|
|
#define PMU_EVENTS_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
|
|
struct perf_pmu;
|
|
|
|
enum aggr_mode_class {
|
|
PerChip = 1,
|
|
PerCore
|
|
};
|
|
|
|
/**
|
|
* enum metric_event_groups - How events within a pmu_metric should be grouped.
|
|
*/
|
|
enum metric_event_groups {
|
|
/**
|
|
* @MetricGroupEvents: Default, group events within the metric.
|
|
*/
|
|
MetricGroupEvents = 0,
|
|
/**
|
|
* @MetricNoGroupEvents: Don't group events for the metric.
|
|
*/
|
|
MetricNoGroupEvents = 1,
|
|
/**
|
|
* @MetricNoGroupEventsNmi:
|
|
* Don't group events for the metric if the NMI watchdog is enabled.
|
|
*/
|
|
MetricNoGroupEventsNmi = 2,
|
|
/**
|
|
* @MetricNoGroupEventsSmt:
|
|
* Don't group events for the metric if SMT is enabled.
|
|
*/
|
|
MetricNoGroupEventsSmt = 3,
|
|
/**
|
|
* @MetricNoGroupEventsThresholdAndNmi:
|
|
* Don't group events for the metric thresholds and if the NMI watchdog
|
|
* is enabled.
|
|
*/
|
|
MetricNoGroupEventsThresholdAndNmi = 4,
|
|
};
|
|
/*
|
|
* Describe each PMU event. Each CPU has a table of PMU events.
|
|
*/
|
|
struct pmu_event {
|
|
const char *name;
|
|
const char *compat;
|
|
const char *event;
|
|
const char *desc;
|
|
const char *topic;
|
|
const char *long_desc;
|
|
const char *pmu;
|
|
const char *unit;
|
|
const char *retirement_latency_mean;
|
|
const char *retirement_latency_min;
|
|
const char *retirement_latency_max;
|
|
bool perpkg;
|
|
bool deprecated;
|
|
};
|
|
|
|
struct pmu_metric {
|
|
const char *pmu;
|
|
const char *metric_name;
|
|
const char *metric_group;
|
|
const char *metric_expr;
|
|
const char *metric_threshold;
|
|
const char *unit;
|
|
const char *compat;
|
|
const char *desc;
|
|
const char *long_desc;
|
|
const char *metricgroup_no_group;
|
|
const char *default_metricgroup_name;
|
|
enum aggr_mode_class aggr_mode;
|
|
enum metric_event_groups event_grouping;
|
|
};
|
|
|
|
struct pmu_events_table;
|
|
struct pmu_metrics_table;
|
|
|
|
#define PMU_EVENTS__NOT_FOUND -1000
|
|
#define PMU_METRICS__NOT_FOUND -1000
|
|
|
|
typedef int (*pmu_event_iter_fn)(const struct pmu_event *pe,
|
|
const struct pmu_events_table *table,
|
|
void *data);
|
|
|
|
typedef int (*pmu_metric_iter_fn)(const struct pmu_metric *pm,
|
|
const struct pmu_metrics_table *table,
|
|
void *data);
|
|
|
|
int pmu_events_table__for_each_event(const struct pmu_events_table *table,
|
|
struct perf_pmu *pmu,
|
|
pmu_event_iter_fn fn,
|
|
void *data);
|
|
/*
|
|
* Search for a table and entry matching with pmu__name_wildcard_match or any
|
|
* tables if pmu is NULL. Each matching event has fn called on it. 0 implies to
|
|
* success/continue the search while non-zero means to terminate. The special
|
|
* value PMU_EVENTS__NOT_FOUND is used to indicate no event was found in one of
|
|
* the tables which doesn't terminate the search of all tables.
|
|
*/
|
|
int pmu_events_table__find_event(const struct pmu_events_table *table,
|
|
struct perf_pmu *pmu,
|
|
const char *name,
|
|
pmu_event_iter_fn fn,
|
|
void *data);
|
|
size_t pmu_events_table__num_events(const struct pmu_events_table *table,
|
|
struct perf_pmu *pmu);
|
|
|
|
int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
|
|
void *data);
|
|
/*
|
|
* Search for a table and entry matching with pmu__name_wildcard_match or any
|
|
* tables if pmu is NULL. Each matching metric has fn called on it. 0 implies to
|
|
* success/continue the search while non-zero means to terminate. The special
|
|
* value PMU_METRICS__NOT_FOUND is used to indicate no metric was found in one
|
|
* of the tables which doesn't terminate the search of all tables.
|
|
*/
|
|
int pmu_metrics_table__find_metric(const struct pmu_metrics_table *table,
|
|
struct perf_pmu *pmu,
|
|
const char *metric,
|
|
pmu_metric_iter_fn fn,
|
|
void *data);
|
|
|
|
const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu);
|
|
const struct pmu_metrics_table *pmu_metrics_table__find(void);
|
|
const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid);
|
|
const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid);
|
|
int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data);
|
|
int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data);
|
|
|
|
const struct pmu_events_table *find_sys_events_table(const char *name);
|
|
const struct pmu_metrics_table *find_sys_metrics_table(const char *name);
|
|
int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data);
|
|
int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data);
|
|
|
|
const char *describe_metricgroup(const char *group);
|
|
|
|
#endif
|