From: kan.liang@linux.intel.com
To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org,
linux-kernel@vger.kernel.org
Cc: mark.rutland@arm.com, alexander.shishkin@linux.intel.com,
jolsa@kernel.org, namhyung@kernel.org, irogers@google.com,
adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com,
Kan Liang <kan.liang@linux.intel.com>
Subject: [PATCH 6/6] perf tools: Support PERF_SAMPLE_BRANCH_EVENT_IDS
Date: Mon, 10 Apr 2023 13:43:52 -0700 [thread overview]
Message-ID: <20230410204352.1098067-6-kan.liang@linux.intel.com> (raw)
In-Reply-To: <20230410204352.1098067-1-kan.liang@linux.intel.com>
From: Kan Liang <kan.liang@linux.intel.com>
Support new sample type PERF_SAMPLE_BRANCH_EVENT_IDS.
It's used with the branch event feature together. If the legacy kernel
doesn't support either of them, switching off them together.
The sampling event may not be the event logged by a branch. Apply the
PERF_SAMPLE_BRANCH_EVENT_IDS for all events if the branch events logging
feature is detected.
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---
tools/perf/util/branch.h | 5 +++++
tools/perf/util/evsel.c | 22 ++++++++++++++++++++--
tools/perf/util/perf_event_attr_fprintf.c | 2 +-
tools/perf/util/record.c | 13 +++++++++++++
tools/perf/util/sample.h | 1 +
tools/perf/util/session.c | 17 +++++++++++++++++
tools/perf/util/synthetic-events.c | 12 ++++++++++++
7 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h
index 5feb79ccd698..761b686e7730 100644
--- a/tools/perf/util/branch.h
+++ b/tools/perf/util/branch.h
@@ -51,6 +51,11 @@ struct branch_stack {
struct branch_entry entries[];
};
+struct branch_event_ids {
+ u64 nr;
+ u64 ids[];
+};
+
/*
* The hw_idx is only available when PERF_SAMPLE_BRANCH_HW_INDEX is applied.
* Otherwise, the output format of a sample with branch stack is
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1888552f41f9..91bd989c8491 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1850,8 +1850,10 @@ static int __evsel__prepare_open(struct evsel *evsel, struct perf_cpu_map *cpus,
static void evsel__disable_missing_features(struct evsel *evsel)
{
- if (perf_missing_features.branch_event)
+ if (perf_missing_features.branch_event) {
evsel->core.attr.branch_sample_type &= ~PERF_SAMPLE_BRANCH_EVENT;
+ evsel__reset_sample_bit(evsel, BRANCH_EVENT_IDS);
+ }
if (perf_missing_features.read_lost)
evsel->core.attr.read_format &= ~PERF_FORMAT_LOST;
if (perf_missing_features.weight_struct) {
@@ -1906,7 +1908,8 @@ bool evsel__detect_missing_features(struct evsel *evsel)
* perf_event_attr interface.
*/
if (!perf_missing_features.branch_event &&
- (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_EVENT)) {
+ ((evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_EVENT) ||
+ (evsel->core.attr.sample_type & PERF_SAMPLE_BRANCH_EVENT_IDS))) {
perf_missing_features.branch_event = true;
pr_debug2("switching off branch event support\n");
return true;
@@ -2710,6 +2713,21 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
array = (void *)array + sz;
}
+ if (type & PERF_SAMPLE_BRANCH_EVENT_IDS) {
+ const u64 max_branch_nr = UINT64_MAX / sizeof(u64);
+
+ OVERFLOW_CHECK_u64(array);
+ data->branch_event_ids = (struct branch_event_ids *)array++;
+
+ if (data->branch_event_ids->nr > max_branch_nr)
+ return -EFAULT;
+
+ sz = data->branch_event_ids->nr * sizeof(u64);
+
+ OVERFLOW_CHECK(array, sz, max_size);
+ array = (void *)array + sz;
+ }
+
return 0;
}
diff --git a/tools/perf/util/perf_event_attr_fprintf.c b/tools/perf/util/perf_event_attr_fprintf.c
index 96f0aafc962d..5eadcdaba12e 100644
--- a/tools/perf/util/perf_event_attr_fprintf.c
+++ b/tools/perf/util/perf_event_attr_fprintf.c
@@ -36,7 +36,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value)
bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC),
bit_name(WEIGHT), bit_name(PHYS_ADDR), bit_name(AUX),
bit_name(CGROUP), bit_name(DATA_PAGE_SIZE), bit_name(CODE_PAGE_SIZE),
- bit_name(WEIGHT_STRUCT),
+ bit_name(WEIGHT_STRUCT), bit_name(BRANCH_EVENT_IDS),
{ .name = NULL, }
};
#undef bit_name
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 9eb5c6a08999..640ba5243209 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -98,6 +98,7 @@ void evlist__config(struct evlist *evlist, struct record_opts *opts, struct call
bool use_sample_identifier = false;
bool use_comm_exec;
bool sample_id = opts->sample_id;
+ bool has_branch_events = false;
if (perf_cpu_map__cpu(evlist->core.user_requested_cpus, 0).cpu < 0)
opts->no_inherit = true;
@@ -108,6 +109,8 @@ void evlist__config(struct evlist *evlist, struct record_opts *opts, struct call
evsel__config(evsel, opts, callchain);
if (evsel->tracking && use_comm_exec)
evsel->core.attr.comm_exec = 1;
+ if (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_EVENT)
+ has_branch_events = true;
}
/* Configure leader sampling here now that the sample type is known */
@@ -139,6 +142,16 @@ void evlist__config(struct evlist *evlist, struct record_opts *opts, struct call
evsel__set_sample_id(evsel, use_sample_identifier);
}
+ if (has_branch_events) {
+ /*
+ * The sampling event may not be the event logged by a
+ * branch. Apply the BRANCH_EVENT_IDS for all events if
+ * the branch events logging feature is detected.
+ */
+ evlist__for_each_entry(evlist, evsel)
+ evsel__set_sample_bit(evsel, BRANCH_EVENT_IDS);
+ }
+
evlist__set_id_pos(evlist);
}
diff --git a/tools/perf/util/sample.h b/tools/perf/util/sample.h
index 33b08e0ac746..b0979571c8af 100644
--- a/tools/perf/util/sample.h
+++ b/tools/perf/util/sample.h
@@ -101,6 +101,7 @@ struct perf_sample {
void *raw_data;
struct ip_callchain *callchain;
struct branch_stack *branch_stack;
+ struct branch_event_ids *branch_event_ids;
struct regs_dump user_regs;
struct regs_dump intr_regs;
struct stack_dump user_stack;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ce6d9349ec42..cc53a4ddfe6d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1203,6 +1203,20 @@ static void branch_stack__printf(struct perf_sample *sample, bool callstack)
}
}
+static void branch_event_ids__printf(struct branch_event_ids *br_event)
+{
+ u64 i;
+
+ printf("%s: nr:%" PRIu64 "\n", "... branch event IDs", br_event->nr);
+
+ for (i = 0; i < br_event->nr; i++) {
+ if (br_event->ids[i] != -1ULL)
+ printf("..... %2"PRIu64": %016" PRIx64 "\n", i, br_event->ids[i]);
+ else
+ printf("..... %2"PRIu64": N/A\n", i);
+ }
+}
+
static void regs_dump__printf(u64 mask, u64 *regs, const char *arch)
{
unsigned rid, i = 0;
@@ -1364,6 +1378,9 @@ static void dump_sample(struct evsel *evsel, union perf_event *event,
if (evsel__has_br_stack(evsel))
branch_stack__printf(sample, evsel__has_branch_callstack(evsel));
+ if (sample_type & PERF_SAMPLE_BRANCH_EVENT_IDS)
+ branch_event_ids__printf(sample->branch_event_ids);
+
if (sample_type & PERF_SAMPLE_REGS_USER)
regs_user__printf(sample, arch);
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
index 9ab9308ee80c..f4c47979e7c1 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
@@ -1543,6 +1543,11 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
result += sample->aux_sample.size;
}
+ if (type & PERF_SAMPLE_BRANCH_EVENT_IDS) {
+ result += sizeof(u64);
+ result += sample->branch_event_ids->nr * sizeof(u64);
+ }
+
return result;
}
@@ -1757,6 +1762,13 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
array = (void *)array + sz;
}
+ if (type & PERF_SAMPLE_BRANCH_EVENT_IDS) {
+ sz = sizeof(u64);
+ sz += sample->branch_event_ids->nr * sizeof(u64);
+ memcpy(array, sample->branch_event_ids, sz);
+ array = (void *)array + sz;
+ }
+
return 0;
}
--
2.35.1
prev parent reply other threads:[~2023-04-10 20:44 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-10 20:43 [PATCH 1/6] perf/x86/intel: Add Grand Ridge and Sierra Forest kan.liang
2023-04-10 20:43 ` [PATCH 2/6] perf: Support branch events logging kan.liang
2023-04-14 10:38 ` Peter Zijlstra
2023-04-14 13:35 ` Liang, Kan
2023-04-14 14:53 ` Peter Zijlstra
2023-04-14 15:56 ` Liang, Kan
2023-04-14 16:09 ` Peter Zijlstra
2023-04-14 17:53 ` Liang, Kan
2023-04-14 19:24 ` Peter Zijlstra
2023-04-14 20:34 ` Liang, Kan
2023-04-14 22:01 ` Peter Zijlstra
2023-04-14 22:47 ` Andi Kleen
2023-04-17 11:46 ` Peter Zijlstra
2023-04-17 13:37 ` Andi Kleen
2023-04-17 14:07 ` Liang, Kan
2023-04-17 11:55 ` Peter Zijlstra
2023-04-17 13:41 ` Andi Kleen
2023-04-10 20:43 ` [PATCH 3/6] perf/x86/intel: Support LBR event logging kan.liang
2023-04-10 20:43 ` [PATCH 4/6] tools headers UAPI: Sync include/uapi/linux/perf_event.h header with the kernel kan.liang
2023-04-10 20:43 ` [PATCH 5/6] perf tools: Add branch event knob kan.liang
2023-04-10 20:43 ` kan.liang [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230410204352.1098067-6-kan.liang@linux.intel.com \
--to=kan.liang@linux.intel.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=eranian@google.com \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox