Commit 3500eeeb authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

perf evsel: Fix missing exclude_{host,guest} setting

The current logic for the perf missing feature has a bug that it can
wrongly clear some modifiers like G or H.  Actually some PMUs don't
support any filtering or exclusion while others do.  But we check it as
a global feature.

For example, the cycles event can have 'G' modifier to enable it only in
the guest mode on x86.  When you don't run any VMs it'll return 0.

  # perf stat -a -e cycles:G sleep 1

    Performance counter stats for 'system wide':

                    0      cycles:G

          1.000721670 seconds time elapsed

But when it's used with other pmu events that don't support G modifier,
it'll be reset and return non-zero values.

  # perf stat -a -e cycles:G,msr/tsc/ sleep 1

    Performance counter stats for 'system wide':

          538,029,960      cycles:G
       16,924,010,738      msr/tsc/

          1.001815327 seconds time elapsed

This is because of the missing feature detection logic being global.
Add a hashmap to set pmu-specific exclude_host/guest features.

Committer notes:

Fix 'perf test python' by adding a stub for evsel__find_pmu() in
tools/perf/util/python.c, document that it is used so far only for the
above reasons so that if anybody needs this in the python binding
usecases, we can revisit this.
Reported-by: default avatarStephane Eranian <eranian@google.com>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Link: http://lore.kernel.org/lkml/20211105205847.120950-1-namhyung@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 88c42f4d
...@@ -1824,7 +1824,7 @@ static void evsel__disable_missing_features(struct evsel *evsel) ...@@ -1824,7 +1824,7 @@ static void evsel__disable_missing_features(struct evsel *evsel)
evsel->open_flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC; evsel->open_flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC;
if (perf_missing_features.mmap2) if (perf_missing_features.mmap2)
evsel->core.attr.mmap2 = 0; evsel->core.attr.mmap2 = 0;
if (perf_missing_features.exclude_guest) if (evsel->pmu && evsel->pmu->missing_features.exclude_guest)
evsel->core.attr.exclude_guest = evsel->core.attr.exclude_host = 0; evsel->core.attr.exclude_guest = evsel->core.attr.exclude_host = 0;
if (perf_missing_features.lbr_flags) if (perf_missing_features.lbr_flags)
evsel->core.attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | evsel->core.attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS |
...@@ -1917,10 +1917,27 @@ bool evsel__detect_missing_features(struct evsel *evsel) ...@@ -1917,10 +1917,27 @@ bool evsel__detect_missing_features(struct evsel *evsel)
perf_missing_features.mmap2 = true; perf_missing_features.mmap2 = true;
pr_debug2_peo("switching off mmap2\n"); pr_debug2_peo("switching off mmap2\n");
return true; return true;
} else if (!perf_missing_features.exclude_guest && } else if ((evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host) &&
(evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host)) { (evsel->pmu == NULL || evsel->pmu->missing_features.exclude_guest)) {
perf_missing_features.exclude_guest = true; if (evsel->pmu == NULL) {
pr_debug2_peo("switching off exclude_guest, exclude_host\n"); evsel->pmu = evsel__find_pmu(evsel);
if (evsel->pmu)
evsel->pmu->missing_features.exclude_guest = true;
else {
/* we cannot find PMU, disable attrs now */
evsel->core.attr.exclude_host = false;
evsel->core.attr.exclude_guest = false;
}
}
if (evsel->exclude_GH) {
pr_debug2_peo("PMU has no exclude_host/guest support, bailing out\n");
return false;
}
if (!perf_missing_features.exclude_guest) {
perf_missing_features.exclude_guest = true;
pr_debug2_peo("switching off exclude_guest, exclude_host\n");
}
return true; return true;
} else if (!perf_missing_features.sample_id_all) { } else if (!perf_missing_features.sample_id_all) {
perf_missing_features.sample_id_all = true; perf_missing_features.sample_id_all = true;
......
...@@ -22,6 +22,7 @@ struct target; ...@@ -22,6 +22,7 @@ struct target;
struct hashmap; struct hashmap;
struct bperf_leader_bpf; struct bperf_leader_bpf;
struct bperf_follower_bpf; struct bperf_follower_bpf;
struct perf_pmu;
typedef int (evsel__sb_cb_t)(union perf_event *event, void *data); typedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
...@@ -153,6 +154,9 @@ struct evsel { ...@@ -153,6 +154,9 @@ struct evsel {
}; };
unsigned long open_flags; unsigned long open_flags;
int precise_ip_original; int precise_ip_original;
/* for missing_features */
struct perf_pmu *pmu;
}; };
struct perf_missing_features { struct perf_missing_features {
......
...@@ -49,6 +49,10 @@ struct perf_pmu { ...@@ -49,6 +49,10 @@ struct perf_pmu {
struct list_head caps; /* HEAD struct perf_pmu_caps -> list */ struct list_head caps; /* HEAD struct perf_pmu_caps -> list */
struct list_head list; /* ELEM */ struct list_head list; /* ELEM */
struct list_head hybrid_list; struct list_head hybrid_list;
struct {
bool exclude_guest;
} missing_features;
}; };
extern struct perf_pmu perf_pmu__fake; extern struct perf_pmu perf_pmu__fake;
......
...@@ -69,6 +69,18 @@ void perf_stat__collect_metric_expr(struct evlist *evsel_list) ...@@ -69,6 +69,18 @@ void perf_stat__collect_metric_expr(struct evlist *evsel_list)
{ {
} }
/*
* This one is needed not to drag the PMU bandwagon, jevents generated
* pmu_sys_event_tables, etc and evsel__find_pmu() is used so far just for
* doing per PMU perf_event_attr.exclude_guest handling, not really needed, so
* far, for the perf python binding known usecases, revisit if this become
* necessary.
*/
struct perf_pmu *evsel__find_pmu(struct evsel *evsel __maybe_unused)
{
return NULL;
}
/* /*
* Add this one here not to drag util/metricgroup.c * Add this one here not to drag util/metricgroup.c
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment