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 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.