From: kan.liang@linux.intel.com
To: acme@kernel.org, namhyung@kernel.org, irogers@google.com,
jolsa@kernel.org, adrian.hunter@intel.com
Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
Kan Liang <kan.liang@linux.intel.com>
Subject: [PATCH] perf env: Find correct branch counter info on hybrid
Date: Mon, 9 Sep 2024 11:42:00 -0700 [thread overview]
Message-ID: <20240909184201.553519-1-kan.liang@linux.intel.com> (raw)
From: Kan Liang <kan.liang@linux.intel.com>
No event is printed in the "Branch Counter" column on hybrid machines.
For example,
$perf record -e "{cpu_core/branch-instructions/pp,cpu_core/branches/}:S"
-j any,counter
$perf report --total-cycles
# Branch counter abbr list:
# cpu_core/branch-instructions/pp = A
# cpu_core/branches/ = B
# '-' No event occurs
# '+' Event occurrences may be lost due to branch counter saturated
#
# Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles Branch Counter
# ............... .............. ........... .......... ..............
44.54% 727.1K 0.00% 1 |+ |+ |
36.31% 592.7K 0.00% 2 |+ |+ |
17.83% 291.1K 0.00% 1 |+ |+ |
The branch counter information (br_cntr_width and br_cntr_nr) in the
perf_env is retrieved from the CPU_PMU_CAPS. However, the CPU_PMU_CAPS
is not available on hybrid machines. Without the width information, the
number of occurrences of an event cannot be calculated.
For a hybrid machine, the caps information should be retrieved from the
PMU_CAPS, and stored in the perf_env->pmu_caps.
Add a perf_env__find_br_cntr_info() to return the correct branch counter
information from the corresponding fields.
Fixes: 6f9d8d1de2c6 ("perf script: Add branch counters")
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---
tools/perf/builtin-script.c | 5 +++--
tools/perf/util/annotate.c | 5 +++--
tools/perf/util/env.c | 15 +++++++++++++++
tools/perf/util/env.h | 3 +++
tools/perf/util/session.c | 6 ++++--
5 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index dbe792b52c5c..a644787fa9e1 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1241,10 +1241,11 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
}
if (PRINT_FIELD(BRCNTR)) {
- unsigned int width = evsel__env(evsel)->br_cntr_width;
- unsigned int i = 0, j, num, mask = (1L << width) - 1;
struct evsel *pos = evsel__leader(evsel);
+ unsigned int i = 0, j, num, mask, width;
+ perf_env__find_br_cntr_info(evsel__env(evsel), NULL, &width);
+ mask = (1L << width) - 1;
printed += fprintf(fp, "br_cntr: ");
evlist__for_each_entry_from(evsel->evlist, pos) {
if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS))
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 4990c70b1794..c6ebde9d40a8 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -333,14 +333,15 @@ static int symbol__account_br_cntr(struct annotated_branch *branch,
{
unsigned int br_cntr_nr = evsel__leader(evsel)->br_cntr_nr;
unsigned int base = evsel__leader(evsel)->br_cntr_idx;
- unsigned int width = evsel__env(evsel)->br_cntr_width;
unsigned int off = offset * evsel->evlist->nr_br_cntr;
- unsigned int i, mask = (1L << width) - 1;
u64 *branch_br_cntr = branch->br_cntr;
+ unsigned int i, mask, width;
if (!br_cntr || !branch_br_cntr)
return 0;
+ perf_env__find_br_cntr_info(evsel__env(evsel), NULL, &width);
+ mask = (1L << width) - 1;
for (i = 0; i < br_cntr_nr; i++) {
u64 cntr = (br_cntr >> i * width) & mask;
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index a459374d0a1a..1edbccfc3281 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -624,3 +624,18 @@ char *perf_env__find_pmu_cap(struct perf_env *env, const char *pmu_name,
free(cap_eq);
return NULL;
}
+
+void perf_env__find_br_cntr_info(struct perf_env *env,
+ unsigned int *nr,
+ unsigned int *width)
+{
+ if (nr) {
+ *nr = env->cpu_pmu_caps ? env->br_cntr_nr :
+ env->pmu_caps->br_cntr_nr;
+ }
+
+ if (width) {
+ *width = env->cpu_pmu_caps ? env->br_cntr_width :
+ env->pmu_caps->br_cntr_width;
+ }
+}
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 2a2c37cc40b7..51b36c36019b 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -192,4 +192,7 @@ char *perf_env__find_pmu_cap(struct perf_env *env, const char *pmu_name,
const char *cap);
bool perf_env__has_pmu_mapping(struct perf_env *env, const char *pmu_name);
+void perf_env__find_br_cntr_info(struct perf_env *env,
+ unsigned int *nr,
+ unsigned int *width);
#endif /* __PERF_ENV_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b492300ec959..dbaf07bf6c5f 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -856,7 +856,6 @@ static void branch_stack__printf(struct perf_sample *sample,
struct branch_entry *entries = perf_sample__branch_entries(sample);
bool callstack = evsel__has_branch_callstack(evsel);
u64 *branch_stack_cntr = sample->branch_stack_cntr;
- struct perf_env *env = evsel__env(evsel);
uint64_t i;
if (!callstack) {
@@ -900,8 +899,11 @@ static void branch_stack__printf(struct perf_sample *sample,
}
if (branch_stack_cntr) {
+ unsigned int br_cntr_width, br_cntr_nr;
+
+ perf_env__find_br_cntr_info(evsel__env(evsel), &br_cntr_nr, &br_cntr_width);
printf("... branch stack counters: nr:%" PRIu64 " (counter width: %u max counter nr:%u)\n",
- sample->branch_stack->nr, env->br_cntr_width, env->br_cntr_nr);
+ sample->branch_stack->nr, br_cntr_width, br_cntr_nr);
for (i = 0; i < sample->branch_stack->nr; i++)
printf("..... %2"PRIu64": %016" PRIx64 "\n", i, branch_stack_cntr[i]);
}
--
2.38.1
next reply other threads:[~2024-09-09 18:41 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-09 18:42 kan.liang [this message]
2024-09-09 20:42 ` [PATCH] perf env: Find correct branch counter info on hybrid Ian Rogers
2024-09-11 14:19 ` Arnaldo Carvalho de Melo
2024-09-11 15:41 ` Liang, Kan
2024-09-11 15:58 ` Arnaldo Carvalho de Melo
2024-09-11 16:00 ` Liang, Kan
2024-09-11 16:01 ` Arnaldo Carvalho de Melo
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=20240909184201.553519-1-kan.liang@linux.intel.com \
--to=kan.liang@linux.intel.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=namhyung@kernel.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