From nobody Sat Feb 7 17:56:01 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 330FF1A08B2; Tue, 13 Aug 2024 16:01:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564900; cv=none; b=ZlaYAxP9kbffz3AlBts1l9SEvfUQ3qQzeoXs03tQmcNuNMf9xpmxeFWYLXGGYVJpEGttSFrBh6PXvGQd+ICfpFkhL3QzNrrrhzLSI72T3T0K6+kTldb4c5Eya62jFPPbxBIkSzwAYZsu6nPJwxQTqLM5ZmRbliNxaM1ktXVQlx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564900; c=relaxed/simple; bh=uaqPUDHCk+yLcH1dAcO1xohze5+IXSI+7YEmes/BJck=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qj/phGuKDy6r7AkTj2JO84HxRu/DAeeU1NqS0ThvTYtcLNaa47g7txUqZte0L6TWvYXNZlkwMVBy8F3ntot0MMssrnX7ik1+CVCoRWZK6HSDENihLSKKoMbnJ5FKsGhbBGb/MZVgFfy5LZlTp9OeY5bziwExUIpB4veImkAREgQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FB7K8sCv; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FB7K8sCv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564898; x=1755100898; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uaqPUDHCk+yLcH1dAcO1xohze5+IXSI+7YEmes/BJck=; b=FB7K8sCvXT4ekeclUBAHTzmZbaxYxCqpz6G+s2G49b9AmKyij617AzMd 1pzPeEyo0i6YQz4jYwAcWDWriU4/Zc0UoVx/pU9k5yWT7On28YBjZvQ9b N0hT3N5s3fgc6e2dVZd02k6nRG6svB6sTOAQeMujdT6MKZp0dZJLr+aj1 lWqa/jUAEwaX0tIt12flC3yCQhQTy/bRtVx/LBNZEvER71d70MCFwy73T q335R89GGni/AuQxHrbIIr8Pyig95lgM0bKBDRMcgHxOiPyXWV3v8p37A IoaUYlv3gJiCPE2tu8Dxoob/mh77VmrNXNP5Azu25wiRYzUiAhFaVz/e/ w==; X-CSE-ConnectionGUID: OfKD106ORguMj4BrzroJeQ== X-CSE-MsgGUID: x4aTjU0EQs+5/6mIKj1HCw== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383200" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383200" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:36 -0700 X-CSE-ConnectionGUID: fyigixwAQKaBfC8Dz9wKhQ== X-CSE-MsgGUID: 3FVWG5zCQbyunyVueRDEQQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479739" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:36 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V3 1/9] perf report: Fix --total-cycles --stdio output error Date: Tue, 13 Aug 2024 09:02:00 -0700 Message-Id: <20240813160208.2493643-2-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang The --total-cycles may output wrong information with the --stdio. For example, perf record -e "{cycles,instructions}",cache-misses -b sleep 1 perf report --total-cycles --stdio The total cycles output of {cycles,instructions} and cache-misses are almost the same. # Samples: 938 of events 'anon group { cycles, instructions }' # Event count (approx.): 938 # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles # ............... .............. ........... .......... ..................................................> # 11.19% 2.6K 0.10% 21 [perf_iterate_ctx+48 -> > 5.79% 1.4K 0.45% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_> 5.11% 1.2K 0.33% 71 [native_write_msr+0 ->> # Samples: 293 of event 'cache-misses' # Event count (approx.): 293 # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles [> # ............... .............. ........... .......... ..................................................> # 11.19% 2.6K 0.13% 21 [perf_iterate_ctx+48 -> > 5.79% 1.4K 0.59% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_> 5.11% 1.2K 0.43% 71 [native_write_msr+0 ->> With the symbol_conf.event_group, the perf report should only report the block information of the leader event in a group. However, the current implementation retrieves the next event's block information, rather than the next group leader's block information. Make sure the index is updated even if the event is skipped. With the patch, # Samples: 293 of event 'cache-misses' # Event count (approx.): 293 # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles [> # ............... .............. ........... .......... ..................................................> # 37.98% 9.0K 4.05% 299 [perf_event_addr_filters_exec+0 -> perf_event_a> 11.19% 2.6K 0.28% 21 [perf_iterate_ctx+48 -> > 5.79% 1.4K 1.32% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_> Fixes: 6f7164fa231a ("perf report: Sort by sampled cycles percent per block= for stdio") Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/builtin-report.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index dfb47fa85e5c..04b9a5c1bc7e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -565,6 +565,7 @@ static int evlist__tty_browse_hists(struct evlist *evli= st, struct report *rep, c struct hists *hists =3D evsel__hists(pos); const char *evname =3D evsel__name(pos); =20 + i++; if (symbol_conf.event_group && !evsel__is_group_leader(pos)) continue; =20 @@ -574,7 +575,7 @@ static int evlist__tty_browse_hists(struct evlist *evli= st, struct report *rep, c hists__fprintf_nr_sample_events(hists, rep, evname, stdout); =20 if (rep->total_cycles_mode) { - report__browse_block_hists(&rep->block_reports[i++].hist, + report__browse_block_hists(&rep->block_reports[i - 1].hist, rep->min_percent, pos, NULL); continue; } --=20 2.38.1 From nobody Sat Feb 7 17:56:01 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36B151A0AFB; Tue, 13 Aug 2024 16:01:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564900; cv=none; b=DQ902Yu3sgZIVYWpqQQFg0B37N5ECeTGmZQHS1ZAxAa1cfDse4XL9us48zXNbRli9kdJ96k6qRkyYCWFWH4GV2ESLaPhhEuFhjrrDRurJq7qCpqKGL8KDUC/6PKW+6/r4umgJnByZel7d7+PKM5hipOf3JhDVp9u91USLYzMtrk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564900; c=relaxed/simple; bh=FDjqNGvQWk2iGBvMXFfIW/8LAWoDEIsvar4aK8Z6710=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=c/OtkD8bOLnh7cyUz/+ss5qriimSAbNVpJFTie0M8uFZiae5BIvYQkl5aypbZV64SMrkVSJWgg72FGvWAdBteLTR3RQxGAGBWos9YHIf2BA7ieKfFehWxI8YIcf4GT8F8EC+HJDAfqLvj6AOREqCStEwKYqTT8o8H3TrkmqRGXs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=A3SIjKEM; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="A3SIjKEM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564899; x=1755100899; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FDjqNGvQWk2iGBvMXFfIW/8LAWoDEIsvar4aK8Z6710=; b=A3SIjKEMnG6fdYgM98+FGlQHj9bidKbcfJoq8uaAFKL8fs5sA4n6j/vL Qdk8x0Ol5oBLGTWr0QqLACGuS79f4J2ToFkP8SaRTmv6hwKivIAzNWnr/ DpYU9OknCBccpe/sWerVB7QO9qGVQxOK9rDSeq/m9dOSWhqLgmVylBy+n 8FaHOgmEnonEymBZoy4ULD54GkVmLBj3/phe9/lp7Oiwl2srOj7tTKTL/ 2TeSbVTGVHGdLGJuNV+LmWLKOHpJJQqtc685Q5Cc+X1KR1tzw+vw2UMkP 5BKj1YxcUIomoKIeZKcQa6O9KGL4PrHLcswBYd4r1KpQ2qBg3dK4zM7fT g==; X-CSE-ConnectionGUID: 5XkOPQEuQFycb6DcZbFLSA== X-CSE-MsgGUID: wM1OgvvBQZafRO0GUKgcVQ== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383203" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383203" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:36 -0700 X-CSE-ConnectionGUID: 04XYeosvQ9Ovfc6/eRseTQ== X-CSE-MsgGUID: bzAvRzlkSMG4o8nNdChdYg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479741" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:36 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V3 2/9] perf report: Remove the first overflow check for branch counters Date: Tue, 13 Aug 2024 09:02:01 -0700 Message-Id: <20240813160208.2493643-3-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang A false overflow warning is triggered if a sample doesn't have any LBRs recorded and the branch counters feature is enabled. The current code does OVERFLOW_CHECK_u64() at the very beginning when reading the information of branch counters. It assumes that there is at least one LBR in the PEBS record. But it is a valid case that 0 LBR is recorded especially in a high context switch. Remove the OVERFLOW_CHECK_u64(). The later OVERFLOW_CHECK() should be good enough to check the overflow when reading the information of the branch counters. Fixes: 9fbb4b02302b ("perf tools: Add branch counter knob") Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/util/evsel.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d607056b73c9..f22f402d54cc 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2884,8 +2884,6 @@ int evsel__parse_sample(struct evsel *evsel, union pe= rf_event *event, array =3D (void *)array + sz; =20 if (evsel__has_branch_counters(evsel)) { - OVERFLOW_CHECK_u64(array); - data->branch_stack_cntr =3D (u64 *)array; sz =3D data->branch_stack->nr * sizeof(u64); =20 --=20 2.38.1 From nobody Sat Feb 7 17:56:01 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB5781A0B08; Tue, 13 Aug 2024 16:01:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564901; cv=none; b=JSPWP47L2qprjIJrsPc05FF5nUqiuwn/XTaBNndAsb9GYBgjopYVOExCBNAlNrnBPmuUdovO98Neb1nq2V2kDtB0K63AE0K9yiqU62BopH8hqEKQNnyZORA6q09GSXMtfxr8UIXNzWNvaovUyX/+U2uVfrB0Td1ZrNOfug6Bfiw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564901; c=relaxed/simple; bh=pneJEcUH4/z6oWAJB8GpXJKIgE0ymwirioZOdmucSGw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=K8v49t/olFQuPJHV9RNYFxGgGhyErYTkdeBgqInAgkGi44zpx4L1Mv/2CQyLOXpxScDEAEqJvJsAGJp7wd5SUXZ7vcdvKfZrbbQMrLixER7kb3n7DNv9jEH1qo+7IUIrjcbcBirQ+RtrbKwElQKfqrh42ODNJhN6MNYcKbgg9D0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=RIlUN/P5; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="RIlUN/P5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564900; x=1755100900; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pneJEcUH4/z6oWAJB8GpXJKIgE0ymwirioZOdmucSGw=; b=RIlUN/P53XL9fZG56gTLeAiZqHnunWhCdnohN1jTBmKBcXqse7qGBupP R9hJcKMtbNwXVbp8JiW/0mZ4F9ExQ+cXGCDWaxHEypc6zqX915IUp888+ KUC7mQTvOQ3mJkdaouRJw/wrDnqwzSKVnwOHkCPkW426CAD+YHxIMJhr9 0n5XcpVBiKRggnt6ue8TA+5uzRkZVWb7HZoG+XQF588rbzD5qJFRQnGK7 4S5cZqc6xFpYsiwmt2aOkWirDFjF6viAJ35vpNpPLOURtLlg8gh6Ld5mH qo3pTwvSoNnbZOwA9cb8ce1Q7C7Z/gzD2IRRJ7izERyg/SaMfUNyUlH7N g==; X-CSE-ConnectionGUID: qQ3zUo/4Rcq4jHd45URreQ== X-CSE-MsgGUID: WTz4acKqSsS3QhWdrJRB5g== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383207" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383207" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:36 -0700 X-CSE-ConnectionGUID: DtkpWr44RHimK8HdvPlBcg== X-CSE-MsgGUID: mkiOy+IWTtqdUBai4eNJzQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479744" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:36 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V3 3/9] perf evlist: Save branch counters information Date: Tue, 13 Aug 2024 09:02:02 -0700 Message-Id: <20240813160208.2493643-4-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang The branch counters logging (A.K.A LBR event logging) introduces a per-counter indication of precise event occurrences in LBRs. The kernel only dumps the number of occurrences into a record. The perf tool has to map the number to the corresponding event. Add evlist__update_br_cntr() to go through the evlist to pick the events that are configured to be logged. Assign a logical idx to track them, and add the total number of the events in the leader event. The total number will be used to allocate the space to save the branch counters for a block. The logical idx will be used to locate the corresponding event quickly in the following patches. It only needs to iterate the evlist once. The evsel__has_branch_counters() is also optimized. Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/util/evlist.c | 15 +++++++++++++++ tools/perf/util/evlist.h | 2 ++ tools/perf/util/evsel.c | 13 +++++++------ tools/perf/util/evsel.h | 8 ++++++++ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4b2538e4f679..68bbd3ea771b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -79,6 +79,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_= map *cpus, evlist->ctl_fd.fd =3D -1; evlist->ctl_fd.ack =3D -1; evlist->ctl_fd.pos =3D -1; + evlist->nr_br_cntr =3D -1; } =20 struct evlist *evlist__new(void) @@ -1264,6 +1265,20 @@ u64 evlist__combined_branch_type(struct evlist *evli= st) return branch_type; } =20 +void evlist__update_br_cntr(struct evlist *evlist) +{ + struct evsel *evsel; + int i =3D 0; + + evlist__for_each_entry(evlist, evsel) { + if (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) { + evsel->br_cntr_idx =3D i++; + evsel__leader(evsel)->br_cntr_nr++; + } + } + evlist->nr_br_cntr =3D i; +} + bool evlist__valid_read_format(struct evlist *evlist) { struct evsel *first =3D evlist__first(evlist), *pos =3D first; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index cccc34da5a02..b46f1a320783 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -57,6 +57,7 @@ struct evlist { bool enabled; int id_pos; int is_pos; + int nr_br_cntr; u64 combined_sample_type; enum bkw_mmap_state bkw_mmap_state; struct { @@ -219,6 +220,7 @@ int evlist__apply_filters(struct evlist *evlist, struct= evsel **err_evsel, u64 __evlist__combined_sample_type(struct evlist *evlist); u64 evlist__combined_sample_type(struct evlist *evlist); u64 evlist__combined_branch_type(struct evlist *evlist); +void evlist__update_br_cntr(struct evlist *evlist); bool evlist__sample_id_all(struct evlist *evlist); u16 evlist__id_hdr_size(struct evlist *evlist); =20 diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f22f402d54cc..38a74d6dde49 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2636,17 +2636,18 @@ u64 evsel__bitfield_swap_branch_flags(u64 value) =20 static inline bool evsel__has_branch_counters(const struct evsel *evsel) { - struct evsel *cur, *leader =3D evsel__leader(evsel); + struct evsel *leader =3D evsel__leader(evsel); =20 /* The branch counters feature only supports group */ if (!leader || !evsel->evlist) return false; =20 - evlist__for_each_entry(evsel->evlist, cur) { - if ((leader =3D=3D evsel__leader(cur)) && - (cur->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) - return true; - } + if (evsel->evlist->nr_br_cntr < 0) + evlist__update_br_cntr(evsel->evlist); + + if (leader->br_cntr_nr > 0) + return true; + return false; } =20 diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a5da4b03bb1c..a393dae1dc96 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -148,6 +148,14 @@ struct evsel { */ __u64 synth_sample_type; =20 + /* + * Store the branch counter related information. + * br_cntr_idx: The idx of the branch counter event in the evlist + * br_cntr_nr: The number of the branch counter event in the group + * (Only available for the leader event) + */ + int br_cntr_idx; + int br_cntr_nr; /* * bpf_counter_ops serves two use cases: * 1. perf-stat -b counting events used byBPF programs --=20 2.38.1 From nobody Sat Feb 7 17:56:01 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 78C821A0B1E; Tue, 13 Aug 2024 16:01:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564902; cv=none; b=SPjCokUbw6HPNAR1IZLA4YqlHNVPP9F0/w9yGLgwsePHsBjN4jR31vVbMJVmavklTumulG75pHBfawL07Vi4qhD2eK2jcyGrph3zsiO2XMbaex/axQmBipGdvlXwl6mZTN5E24Dj9CDRNkZQvgkkbPm6SYD6o0jbTLf5z9Qigo0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564902; c=relaxed/simple; bh=Ph5KwKnno7foh1DN9iqmyFy82JRkinAvPiWd5IiGz68=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Pmzbi8+h0sNXZoDtL6WQAvrRf6vAyFgw3qvkIZ1CREFPC0CZB4fyvFJPgb9oGb3Ebf4G00ZYRfx3vnD6M5sH+X1tX7xzAW2ARGvU3h2szx6hK6ZVGY7rkZvPinuTY1a1xMeHOYX7RsXAdlaYS3NUSNxRiFhYZPxPmZapIR363dk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=eLZzwkI5; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="eLZzwkI5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564901; x=1755100901; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ph5KwKnno7foh1DN9iqmyFy82JRkinAvPiWd5IiGz68=; b=eLZzwkI5ezFbLWPliWWYdkE+3g1aNHXv8o+22HHesfnY+UZDe2OQl1/F Z992ZVjauoR6SxhIgnWhMMxeMMMZG+tcXmMY1GOx2EiqKtr8agNg1x43+ 83Aji26KH57T5dKaBJ3fMliermXhFeJ7iETslkAqWE8dAWwDwHgBrVOfT F9+i/aVQardeGmE6frsd42lIKqsXYkFXyvQCGwQxgG0IEIbY5hKlQUoD4 GNFN+E2YBwSTsDW+U2cWfliqgYan31ss/IhLkzuyAcqBBwUAPyIJuIJO5 0MOgKHSyoF6HUffqv24b7FrE1Vz9rjX8Ia8SVYRm1lBILgPcbmgdbi30M g==; X-CSE-ConnectionGUID: 3T6IUcJTRHSFTkRaZBX+5Q== X-CSE-MsgGUID: DHzPuZwNTHG02IMIVvIAoQ== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383211" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383211" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:36 -0700 X-CSE-ConnectionGUID: af7tkjICRAuNQ/UGGDWYew== X-CSE-MsgGUID: ytfN6cAYRwCEY4FtX5arDw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479747" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:36 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V3 4/9] perf annotate: Save branch counters for each block Date: Tue, 13 Aug 2024 09:02:03 -0700 Message-Id: <20240813160208.2493643-5-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang When annotating a basic block, it's useful to display the occurrences of other events in the block. The branch counter feature is only available for newer Intel platforms. So a dedicated option to display the branch counters is not introduced. Reuse the existing --total-cycles option, which triggers the annotation of a basic block and displays the cycle-related annotation. When the branch counters information is available, the branch counters are automatically appended after all the cycle-related annotation. Accounting the branch counters as well when accounting the cycles in hist__account_cycles(). In struct annotated_branch, introduce a br_cntr array to save the accumulation of each branch counter. In a sample, all the branch counters for a branch are saved in a u64 space. Because the saturation of a branch counter is small, e.g., for Intel Sierra Forest, the saturation is only 3. Add ANNOTATION__BR_CNTR_SATURATED_FLAG to indicate if a branch counter once saturated. That can be used to indicate a potential event lost because of the saturation. Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/builtin-annotate.c | 3 +- tools/perf/builtin-diff.c | 4 +-- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-top.c | 4 +-- tools/perf/util/annotate.c | 68 ++++++++++++++++++++++++++++------- tools/perf/util/annotate.h | 10 +++++- tools/perf/util/branch.h | 1 + tools/perf/util/hist.c | 5 +-- tools/perf/util/hist.h | 2 +- tools/perf/util/machine.c | 3 ++ 10 files changed, 80 insertions(+), 22 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index d6f6ba5a569d..9b4a8a379b5b 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -221,7 +221,8 @@ static int process_branch_callback(struct evsel *evsel, if (a.map !=3D NULL) dso__set_hit(map__dso(a.map)); =20 - hist__account_cycles(sample->branch_stack, al, sample, false, NULL); + hist__account_cycles(sample->branch_stack, al, sample, false, + NULL, evsel); =20 ret =3D hist_entry_iter__add(&iter, &a, PERF_MAX_STACK_DEPTH, ann); out: diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 28c5208fcdc9..6983b5373372 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -431,8 +431,8 @@ static int diff__process_sample_event(const struct perf= _tool *tool, goto out; } =20 - hist__account_cycles(sample->branch_stack, &al, sample, false, - NULL); + hist__account_cycles(sample->branch_stack, &al, sample, + false, NULL, evsel); break; =20 case COMPUTE_STREAM: diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 04b9a5c1bc7e..ab450644e5b3 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -328,7 +328,7 @@ static int process_sample_event(const struct perf_tool = *tool, if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) { hist__account_cycles(sample->branch_stack, &al, sample, rep->nonany_branch_mode, - &rep->total_cycles); + &rep->total_cycles, evsel); } =20 ret =3D hist_entry_iter__add(&iter, &al, rep->max_stack, rep); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1cdac4e190e9..881b861c35ee 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -735,8 +735,8 @@ static int hist_iter__top_callback(struct hist_entry_it= er *iter, perf_top__record_precise_ip(top, iter->he, iter->sample, evsel, al->addr= ); =20 hist__account_cycles(iter->sample->branch_stack, al, iter->sample, - !(top->record_opts.branch_stack & PERF_SAMPLE_BRANCH_ANY), - NULL); + !(top->record_opts.branch_stack & PERF_SAMPLE_BRANCH_ANY), + NULL, evsel); return 0; } =20 diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index a87d2e97e10d..c269758d47c8 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -266,22 +266,30 @@ struct annotated_branch *annotation__get_branch(struc= t annotation *notes) return notes->branch; } =20 -static struct cyc_hist *symbol__cycles_hist(struct symbol *sym) +static struct annotated_branch *symbol__find_branch_hist(struct symbol *sy= m, + unsigned int br_cntr_nr) { struct annotation *notes =3D symbol__annotation(sym); struct annotated_branch *branch; + const size_t size =3D symbol__size(sym); =20 branch =3D annotation__get_branch(notes); if (branch =3D=3D NULL) return NULL; =20 if (branch->cycles_hist =3D=3D NULL) { - const size_t size =3D symbol__size(sym); - branch->cycles_hist =3D calloc(size, sizeof(struct cyc_hist)); + if (!branch->cycles_hist) + return NULL; + } + + if (br_cntr_nr && branch->br_cntr =3D=3D NULL) { + branch->br_cntr =3D calloc(br_cntr_nr * size, sizeof(u64)); + if (!branch->br_cntr) + return NULL; } =20 - return branch->cycles_hist; + return branch; } =20 struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists) @@ -316,16 +324,44 @@ static int symbol__inc_addr_samples(struct map_symbol= *ms, return src ? __symbol__inc_addr_samples(ms, src, evsel->core.idx, addr, s= ample) : 0; } =20 -static int symbol__account_cycles(u64 addr, u64 start, - struct symbol *sym, unsigned cycles) +static int symbol__account_br_cntr(struct annotated_branch *branch, + struct evsel *evsel, + unsigned offset, + u64 br_cntr) +{ + unsigned int br_cntr_nr =3D evsel__leader(evsel)->br_cntr_nr; + unsigned int base =3D evsel__leader(evsel)->br_cntr_idx; + unsigned int width =3D evsel__env(evsel)->br_cntr_width; + unsigned int off =3D offset * evsel->evlist->nr_br_cntr; + unsigned int i, mask =3D (1L << width) - 1; + u64 *branch_br_cntr =3D branch->br_cntr; + + if (!br_cntr || !branch_br_cntr) + return 0; + + for (i =3D 0; i < br_cntr_nr; i++) { + u64 cntr =3D (br_cntr >> i * width) & mask; + + branch_br_cntr[off + i + base] +=3D cntr; + if (cntr =3D=3D mask) + branch_br_cntr[off + i + base] |=3D ANNOTATION__BR_CNTR_SATURATED_FLAG; + } + + return 0; +} + +static int symbol__account_cycles(u64 addr, u64 start, struct symbol *sym, + unsigned cycles, struct evsel *evsel, + u64 br_cntr) { - struct cyc_hist *cycles_hist; + struct annotated_branch *branch; unsigned offset; + int ret; =20 if (sym =3D=3D NULL) return 0; - cycles_hist =3D symbol__cycles_hist(sym); - if (cycles_hist =3D=3D NULL) + branch =3D symbol__find_branch_hist(sym, evsel->evlist->nr_br_cntr); + if (!branch) return -ENOMEM; if (addr < sym->start || addr >=3D sym->end) return -ERANGE; @@ -337,15 +373,22 @@ static int symbol__account_cycles(u64 addr, u64 start, start =3D 0; } offset =3D addr - sym->start; - return __symbol__account_cycles(cycles_hist, + ret =3D __symbol__account_cycles(branch->cycles_hist, start ? start - sym->start : 0, offset, cycles, !!start); + + if (ret) + return ret; + + return symbol__account_br_cntr(branch, evsel, offset, br_cntr); } =20 int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, struct addr_map_symbol *start, - unsigned cycles) + unsigned cycles, + struct evsel *evsel, + u64 br_cntr) { u64 saddr =3D 0; int err; @@ -371,7 +414,7 @@ int addr_map_symbol__account_cycles(struct addr_map_sym= bol *ams, start ? start->addr : 0, ams->ms.sym ? ams->ms.sym->start + map__start(ams->ms.map) : 0, saddr); - err =3D symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles); + err =3D symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles, = evsel, br_cntr); if (err) pr_debug2("account_cycles failed %d\n", err); return err; @@ -412,6 +455,7 @@ static void annotated_branch__delete(struct annotated_b= ranch *branch) { if (branch) { zfree(&branch->cycles_hist); + free(branch->br_cntr); free(branch); } } diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 0e52558baa01..6b3023f3b18f 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -14,6 +14,7 @@ #include "spark.h" #include "hashmap.h" #include "disasm.h" +#include "branch.h" =20 struct hist_browser_timer; struct hist_entry; @@ -288,6 +289,9 @@ struct annotated_source { struct annotation_line *annotated_source__get_line(struct annotated_source= *src, s64 offset); =20 +/* A branch counter once saturated */ +#define ANNOTATION__BR_CNTR_SATURATED_FLAG (1ULL << 63) + /** * struct annotated_branch - basic block and IPC information for a symbol. * @@ -297,6 +301,7 @@ struct annotation_line *annotated_source__get_line(stru= ct annotated_source *src, * @cover_insn: Number of distinct, actually executed instructions. * @cycles_hist: Array of cyc_hist for each instruction. * @max_coverage: Maximum number of covered basic block (used for block-ra= nge). + * @br_cntr: Array of the occurrences of events (branch counters) during a= block. * * This struct is used by two different codes when the sample has branch s= tack * and cycles information. annotation__compute_ipc() calculates average I= PC @@ -313,6 +318,7 @@ struct annotated_branch { unsigned int cover_insn; struct cyc_hist *cycles_hist; u64 max_coverage; + u64 *br_cntr; }; =20 struct LOCKABLE annotation { @@ -383,7 +389,9 @@ struct annotated_branch *annotation__get_branch(struct = annotation *notes); =20 int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, struct addr_map_symbol *start, - unsigned cycles); + unsigned cycles, + struct evsel *evsel, + u64 br_cntr); =20 int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample= *sample, struct evsel *evsel, u64 addr); diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h index 87704d713ff6..b80c12c74bbb 100644 --- a/tools/perf/util/branch.h +++ b/tools/perf/util/branch.h @@ -34,6 +34,7 @@ struct branch_info { struct addr_map_symbol from; struct addr_map_symbol to; struct branch_flags flags; + u64 branch_stack_cntr; char *srcline_from; char *srcline_to; }; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index c8c1b511f8a7..0f554febf9a1 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2677,7 +2677,7 @@ int hists__unlink(struct hists *hists) =20 void hist__account_cycles(struct branch_stack *bs, struct addr_location *a= l, struct perf_sample *sample, bool nonany_branch_mode, - u64 *total_cycles) + u64 *total_cycles, struct evsel *evsel) { struct branch_info *bi; struct branch_entry *entries =3D perf_sample__branch_entries(sample); @@ -2701,7 +2701,8 @@ void hist__account_cycles(struct branch_stack *bs, st= ruct addr_location *al, for (int i =3D bs->nr - 1; i >=3D 0; i--) { addr_map_symbol__account_cycles(&bi[i].from, nonany_branch_mode ? NULL : prev, - bi[i].flags.cycles); + bi[i].flags.cycles, evsel, + bi[i].branch_stack_cntr); prev =3D &bi[i].to; =20 if (total_cycles) diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 5273f5c37050..30c13fc8cbe4 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -742,7 +742,7 @@ unsigned int hists__overhead_width(struct hists *hists); =20 void hist__account_cycles(struct branch_stack *bs, struct addr_location *a= l, struct perf_sample *sample, bool nonany_branch_mode, - u64 *total_cycles); + u64 *total_cycles, struct evsel *evsel); =20 struct option; int parse_filter_percentage(const struct option *opt, const char *arg, int= unset); diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 706be5e4a076..c08774d06d14 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2141,6 +2141,7 @@ struct branch_info *sample__resolve_bstack(struct per= f_sample *sample, unsigned int i; const struct branch_stack *bs =3D sample->branch_stack; struct branch_entry *entries =3D perf_sample__branch_entries(sample); + u64 *branch_stack_cntr =3D sample->branch_stack_cntr; struct branch_info *bi =3D calloc(bs->nr, sizeof(struct branch_info)); =20 if (!bi) @@ -2150,6 +2151,8 @@ struct branch_info *sample__resolve_bstack(struct per= f_sample *sample, ip__resolve_ams(al->thread, &bi[i].to, entries[i].to); ip__resolve_ams(al->thread, &bi[i].from, entries[i].from); bi[i].flags =3D entries[i].flags; + if (branch_stack_cntr) + bi[i].branch_stack_cntr =3D branch_stack_cntr[i]; } return bi; } --=20 2.38.1 From nobody Sat Feb 7 17:56:01 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C5461A2553; Tue, 13 Aug 2024 16:01:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564902; cv=none; b=f+ywtGFNYGzd0zb5HCQW6G1EdRps4sHXTXE7pVFH8vm2GQgQk+U5XMiXjO8v3kt53eGVh7Mrns+SdRdxdYRf4Gptfrc3FMYR3ruMwCOF03m7tYV3dvbBwWgSJlWDKBTMqJuW93u+djjFtZfGI0RoYZLVX6WRJ3GCfiGRQc/NiX4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564902; c=relaxed/simple; bh=RGx8KZ0mPU+21hMxzYjjPTeGX0Yn/dEoOCKNO8974xA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iCkJcaU8ff4XVyQW9aRdjEpMXy9O9oKt+Q0J+O4+mUS/Dl8pDIbVvAvc0Cv3h5ILs6FIuZ3kNzEEvvh8VdmH9jzw7skF8yFMsRinRlkqFw1ZX7jUb98KUGEP+2/9d1vu8NnmIT1/92RFBY45AzLuXLQPUxGEfzhFNgAfZv/EilA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=XgeB+BbH; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="XgeB+BbH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564901; x=1755100901; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RGx8KZ0mPU+21hMxzYjjPTeGX0Yn/dEoOCKNO8974xA=; b=XgeB+BbHxwtEibMx4wkHIxgb+TquE9o+ODvlQL9lCFbtRmgspJRLcpV0 tXylJBynbinc1EsWkc8LUaJeAkbsUQBqA4DgFqJRCjPaaogdxf/wEdg1Q Ynr0jxNKHvRz7DbhGLMlYr5JJ7m4lyISFhQv7mYG2zMeo0FNOARC22Lu5 1VeM5Y5NlcbkzWQ0WX/zIaIp7C82awKoapubNxh3h+IRv2fpUD4d8CXJu D9wo7GhfX8KbVN+Y7VVwypP1O7ZIRcx/r3Rvvgysoq+Nq1xUKejQhsiOP cbw3EZ3xq3oDioJWYPhItittW8TL3joQlixXkelzbwN8lQmUiRrOrgPzl w==; X-CSE-ConnectionGUID: yzdImREJS5CLV1c9ngVNZg== X-CSE-MsgGUID: l/0mBFwVQk6cMoszCJc2Wg== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383214" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383214" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:37 -0700 X-CSE-ConnectionGUID: /T59vsbtS3K/EhZSM77mgg== X-CSE-MsgGUID: /XYrNTUOTLaRHI5VY+3xhg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479750" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:36 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V3 5/9] perf evsel: Assign abbr name for the branch counter events Date: Tue, 13 Aug 2024 09:02:04 -0700 Message-Id: <20240813160208.2493643-6-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang There could be several branch counter events. If perf tool output the result via the format "event name + a number", the line could be very long and hard to read. An abbreviation is introduced to replace the full event name in the display. The abbreviation starts from 'A' to 'Z9', which can support up to 286 events. The same abbreviation will be assigned if the same events are found in the evlist. The next patch will utilize the abbreviation name to show the branch counter events in the output. Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/util/evlist.c | 55 +++++++++++++++++++++++++++++++++++++++- tools/perf/util/evsel.h | 6 +++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 68bbd3ea771b..c0379fa1ccfe 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -33,6 +33,7 @@ #include "util/bpf-filter.h" #include "util/stat.h" #include "util/util.h" +#include "util/env.h" #include "util/intel-tpebs.h" #include #include @@ -1265,15 +1266,67 @@ u64 evlist__combined_branch_type(struct evlist *evl= ist) return branch_type; } =20 +static struct evsel * +evlist__find_dup_event_from_prev(struct evlist *evlist, struct evsel *even= t) +{ + struct evsel *pos; + + evlist__for_each_entry(evlist, pos) { + if (event =3D=3D pos) + break; + if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) && + !strcmp(pos->name, event->name)) + return pos; + } + return NULL; +} + +#define MAX_NR_ABBR_NAME (26 * 11) + +/* + * The abbr name is from A to Z9. If the number of event + * which requires the branch counter > MAX_NR_ABBR_NAME, + * return NA. + */ +static void evlist__new_abbr_name(char *name) +{ + static int idx; + int i =3D idx / 26; + + if (idx >=3D MAX_NR_ABBR_NAME) { + name[0] =3D 'N'; + name[1] =3D 'A'; + name[2] =3D '\0'; + return; + } + + name[0] =3D 'A' + (idx % 26); + + if (!i) + name[1] =3D '\0'; + else { + name[1] =3D '0' + i - 1; + name[2] =3D '\0'; + } + + idx++; +} + void evlist__update_br_cntr(struct evlist *evlist) { - struct evsel *evsel; + struct evsel *evsel, *dup; int i =3D 0; =20 evlist__for_each_entry(evlist, evsel) { if (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) { evsel->br_cntr_idx =3D i++; evsel__leader(evsel)->br_cntr_nr++; + + dup =3D evlist__find_dup_event_from_prev(evlist, evsel); + if (dup) + memcpy(evsel->abbr_name, dup->abbr_name, 3 * sizeof(char)); + else + evlist__new_abbr_name(evsel->abbr_name); } } evlist->nr_br_cntr =3D i; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a393dae1dc96..4316992f6a69 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -153,9 +153,15 @@ struct evsel { * br_cntr_idx: The idx of the branch counter event in the evlist * br_cntr_nr: The number of the branch counter event in the group * (Only available for the leader event) + * abbr_name: The abbreviation name assigned to an event which is + * logged by the branch counter. + * The abbr name is from A to Z9. NA is applied if out + * of the range. */ int br_cntr_idx; int br_cntr_nr; + char abbr_name[3]; + /* * bpf_counter_ops serves two use cases: * 1. perf-stat -b counting events used byBPF programs --=20 2.38.1 From nobody Sat Feb 7 17:56:01 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 835A41A2569; Tue, 13 Aug 2024 16:01:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564903; cv=none; b=J1f+aVQ6jKk1U25dmrxPhqFt7/FQFCpYIsq0fBmfJuJqgCfzpFBZ2+MEJe46gzHkYfax+eKJ+GcuGrN//YJjPyjrvzBVj5PUuRDJpcPBlxjGDBnk9SPA6aVNaMa4YYNoHtLtFaTwVfYgr0d2JWyPBgTaU10kmJP3ESe1HoHlUGY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564903; c=relaxed/simple; bh=M/jzHVsxW955W7J05m7n0H6Gn/rEO0/Qy07AQKfAgl4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Shxr7eE8ig//zpY9UrISfdZ4lLU4bs0N9omB3wq76I7EN21REpfY+tze0dAlYqYGhX1imgZtImqmC6yaRoAl2eI/j3pNeI1RGewzMIiw8pOpXMEju0vjyIwqR0FzzT03IfRNiSJaFe6LmfcSJoqGQhcUlwOlqmKhS65R15TGiCU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=QjF7dUsM; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="QjF7dUsM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564902; x=1755100902; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=M/jzHVsxW955W7J05m7n0H6Gn/rEO0/Qy07AQKfAgl4=; b=QjF7dUsM5N2KV7YEaC1gyDcuRYTQN8oZgnHQFcSUmrtbJopnPx6U9nSP h/tTCn7v4O0+LNzJFzRAgZAqW0v0iUE0BpnSnchsLhaYXkwM9LSR8DYh3 seUWAFvUBNw43Ga7crqijfD+evS10V+3al2mEezB0ZocQLtjWDi+EY66A 7zITT+6nXJv3H7GhKAS5L2LE6K8dcNu1poIvXF17783GI2L0JZc6ofWoo y85e4x8/AWBTCyVHn9orz1ofcWmTEBw79BrhMg7KteAUuAknpB9yijklu w90UMR1WJsbq4AbGel8izu5q3Am/sb3hf8lt9qP3pns6GwnOvjXebZGcs w==; X-CSE-ConnectionGUID: PQUrBJEBRMGc3G9Zns7nHA== X-CSE-MsgGUID: LA3mo4D1Q7WPyzAlyiJSiQ== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383217" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383217" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:37 -0700 X-CSE-ConnectionGUID: mqWuTVORQAavNY76DhxTYw== X-CSE-MsgGUID: OxdFghRRT22mRxXb62Wn/Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479753" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:37 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V3 6/9] perf report: Display the branch counter histogram Date: Tue, 13 Aug 2024 09:02:05 -0700 Message-Id: <20240813160208.2493643-7-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang Reusing the existing --total-cycles option to display the branch counters. Add a new PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER to display the logged branch counter events. They are shown right after all the cycle-related annotations. Extend the struct block_info to store and pass the branch counter related information. The annotation_br_cntr_entry() is to print the histogram of each branch counter event. If the number of logged events is less than 4, the exact number of the abbr name is printed. Otherwise, using '+' to stands for more than 3 events. Assume the number of logged events is less than 4. The annotation_br_cntr_abbr_list() prints the branch counter's abbreviation list. Press 'B' to display the list in the TUI mode. $perf record -e "{branch-instructions:ppp,branch-misses}:S" -j any,counter $perf report --total-cycles --stdio # To display the perf.data header info, please use --header/--header-only = options. # # # Total Lost Samples: 0 # # Samples: 1M of events 'anon group { branch-instructions:ppp, branch-miss= es }' # Event count (approx.): 1610046 # # Branch counter abbr list: # branch-instructions:ppp =3D A # branch-misses =3D B # '-' No event occurs # '+' Event occurrences may be lost due to branch counter saturated # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles Branch= Counter [Program Block Range] # ............... .............. ........... .......... ..............= ........ .................. # 57.55% 2.5M 0.00% 3 |A = |- | ... 25.27% 1.1M 0.00% 2 |AA = |- | ... 15.61% 667.2K 0.00% 1 |A = |- | ... 0.16% 6.9K 0.81% 575 |A = |- | ... 0.16% 6.8K 1.38% 977 |AA = |- | ... 0.16% 6.8K 0.04% 28 |AA = |B | ... 0.15% 6.6K 1.33% 946 |A = |- | ... 0.11% 4.5K 0.06% 46 |AAA= +|- | ... 0.10% 4.4K 0.88% 624 |A = |- | ... 0.09% 3.7K 0.74% 524 |AAA= +|B | ... With -v applied, # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles Branch= Counter [Program Block Range] # ............... .............. ........... .......... ..............= ........ .................. # 57.55% 2.5M 0.00% 3 A= =3D1 ,B=3D- ... 25.27% 1.1M 0.00% 2 A= =3D2 ,B=3D- ... 15.61% 667.2K 0.00% 1 A= =3D1 ,B=3D- ... 0.16% 6.9K 0.81% 575 A= =3D1 ,B=3D- ... 0.16% 6.8K 1.38% 977 A= =3D2 ,B=3D- ... 0.16% 6.8K 0.04% 28 A= =3D2 ,B=3D1 ... 0.15% 6.6K 1.33% 946 A= =3D1 ,B=3D- ... 0.11% 4.5K 0.06% 46 A= =3D3+,B=3D- ... 0.10% 4.4K 0.88% 624 A= =3D1 ,B=3D- ... 0.09% 3.7K 0.74% 524 A= =3D3+,B=3D1 ... Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/Documentation/perf-report.txt | 1 + tools/perf/builtin-diff.c | 4 +- tools/perf/builtin-report.c | 20 +++- tools/perf/ui/browsers/hists.c | 17 ++- tools/perf/util/annotate.c | 145 +++++++++++++++++++++++ tools/perf/util/annotate.h | 3 + tools/perf/util/block-info.c | 66 +++++++++-- tools/perf/util/block-info.h | 8 +- 8 files changed, 246 insertions(+), 18 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Document= ation/perf-report.txt index d2b1593ef700..7c66d81ab978 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -614,6 +614,7 @@ include::itrace.txt[] 'Avg Cycles%' - block average sampled cycles / sum of total block ave= rage sampled cycles 'Avg Cycles' - block average sampled cycles + 'Branch Counter' - block branch counter histogram (with -v showing the n= umber) =20 --skip-empty:: Do not print 0 results in the --stat output. diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 6983b5373372..23326dd20333 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -691,7 +691,7 @@ static void hists__precompute(struct hists *hists) if (compute =3D=3D COMPUTE_CYCLES) { bh =3D container_of(he, struct block_hist, he); init_block_hist(bh); - block_info__process_sym(he, bh, NULL, 0); + block_info__process_sym(he, bh, NULL, 0, 0); } =20 data__for_each_file_new(i, d) { @@ -714,7 +714,7 @@ static void hists__precompute(struct hists *hists) pair_bh =3D container_of(pair, struct block_hist, he); init_block_hist(pair_bh); - block_info__process_sym(pair, pair_bh, NULL, 0); + block_info__process_sym(pair, pair_bh, NULL, 0, 0); =20 bh =3D container_of(he, struct block_hist, he); =20 diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index ab450644e5b3..1643113616f4 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -575,6 +575,13 @@ static int evlist__tty_browse_hists(struct evlist *evl= ist, struct report *rep, c hists__fprintf_nr_sample_events(hists, rep, evname, stdout); =20 if (rep->total_cycles_mode) { + char *buf; + + if (!annotation_br_cntr_abbr_list(&buf, pos, true)) { + fprintf(stdout, "%s", buf); + fprintf(stdout, "#\n"); + free(buf); + } report__browse_block_hists(&rep->block_reports[i - 1].hist, rep->min_percent, pos, NULL); continue; @@ -1119,18 +1126,23 @@ static int __cmd_report(struct report *rep) report__output_resort(rep); =20 if (rep->total_cycles_mode) { - int block_hpps[6] =3D { + int nr_hpps =3D 4; + int block_hpps[PERF_HPP_REPORT__BLOCK_MAX_INDEX] =3D { PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT, PERF_HPP_REPORT__BLOCK_LBR_CYCLES, PERF_HPP_REPORT__BLOCK_CYCLES_PCT, PERF_HPP_REPORT__BLOCK_AVG_CYCLES, - PERF_HPP_REPORT__BLOCK_RANGE, - PERF_HPP_REPORT__BLOCK_DSO, }; =20 + if (session->evlist->nr_br_cntr > 0) + block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER; + + block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_RANGE; + block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_DSO; + rep->block_reports =3D block_info__create_report(session->evlist, rep->total_cycles, - block_hpps, 6, + block_hpps, nr_hpps, &rep->nr_block_reports); if (!rep->block_reports) return -1; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b7219df51236..970f7f349298 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3684,8 +3684,10 @@ int block_hists_tui_browse(struct block_hist *bh, st= ruct evsel *evsel, struct hist_browser *browser; int key =3D -1; struct popup_action action; + char *br_cntr_text =3D NULL; static const char help[] =3D - " q Quit \n"; + " q Quit \n" + " B Branch counter abbr list (Optional)\n"; =20 browser =3D hist_browser__new(hists); if (!browser) @@ -3703,6 +3705,8 @@ int block_hists_tui_browse(struct block_hist *bh, str= uct evsel *evsel, =20 memset(&action, 0, sizeof(action)); =20 + annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false); + while (1) { key =3D hist_browser__run(browser, "? - help", true, 0); =20 @@ -3723,6 +3727,16 @@ int block_hists_tui_browse(struct block_hist *bh, st= ruct evsel *evsel, action.ms.sym =3D browser->selection->sym; do_annotate(browser, &action); continue; + case 'B': + if (br_cntr_text) { + ui__question_window("Branch counter abbr list", + br_cntr_text, "Press any key...", 0); + } else { + ui__question_window("Branch counter abbr list", + "\n The branch counter is not available.\n", + "Press any key...", 0); + } + continue; default: break; } @@ -3730,5 +3744,6 @@ int block_hists_tui_browse(struct block_hist *bh, str= uct evsel *evsel, =20 out: hist_browser__delete(browser); + free(br_cntr_text); return 0; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c269758d47c8..5200cafe20e7 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -41,6 +41,7 @@ #include "namespaces.h" #include "thread.h" #include "hashmap.h" +#include "strbuf.h" #include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include =20 /* FIXME: For the HE_COLORSET */ #include "ui/browser.h" @@ -1719,6 +1721,149 @@ static void ipc_coverage_string(char *bf, int size,= struct annotation *notes) ipc, coverage); } =20 +int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool hea= der) +{ + struct evsel *pos; + struct strbuf sb; + + if (evsel->evlist->nr_br_cntr <=3D 0) + return -ENOTSUP; + + strbuf_init(&sb, /*hint=3D*/ 0); + + if (header && strbuf_addf(&sb, "# Branch counter abbr list:\n")) + goto err; + + evlist__for_each_entry(evsel->evlist, pos) { + if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) + continue; + if (header && strbuf_addf(&sb, "#")) + goto err; + + if (strbuf_addf(&sb, " %s =3D %s\n", pos->name, pos->abbr_name)) + goto err; + } + + if (header && strbuf_addf(&sb, "#")) + goto err; + if (strbuf_addf(&sb, " '-' No event occurs\n")) + goto err; + + if (header && strbuf_addf(&sb, "#")) + goto err; + if (strbuf_addf(&sb, " '+' Event occurrences may be lost due to branch co= unter saturated\n")) + goto err; + + *str =3D strbuf_detach(&sb, NULL); + + return 0; +err: + strbuf_release(&sb); + return -ENOMEM; +} + +/* Assume the branch counter saturated at 3 */ +#define ANNOTATION_BR_CNTR_SATURATION 3 + +int annotation_br_cntr_entry(char **str, int br_cntr_nr, + u64 *br_cntr, int num_aggr, + struct evsel *evsel) +{ + struct evsel *pos =3D evsel ? evlist__first(evsel->evlist) : NULL; + bool saturated =3D false; + int i, j, avg, used; + struct strbuf sb; + + strbuf_init(&sb, /*hint=3D*/ 0); + for (i =3D 0; i < br_cntr_nr; i++) { + used =3D 0; + avg =3D ceil((double)(br_cntr[i] & ~ANNOTATION__BR_CNTR_SATURATED_FLAG) / + (double)num_aggr); + + /* + * A histogram with the abbr name is displayed by default. + * With -v, the exact number of branch counter is displayed. + */ + if (verbose) { + evlist__for_each_entry_from(evsel->evlist, pos) { + if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) = && + (pos->br_cntr_idx =3D=3D i)) + break; + } + if (strbuf_addstr(&sb, pos->abbr_name)) + goto err; + + if (!br_cntr[i]) { + if (strbuf_addstr(&sb, "=3D-")) + goto err; + } else { + if (strbuf_addf(&sb, "=3D%d", avg)) + goto err; + } + if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG) { + if (strbuf_addch(&sb, '+')) + goto err; + } else { + if (strbuf_addch(&sb, ' ')) + goto err; + } + + if ((i < br_cntr_nr - 1) && strbuf_addch(&sb, ',')) + goto err; + continue; + } + + if (strbuf_addch(&sb, '|')) + goto err; + + if (!br_cntr[i]) { + if (strbuf_addch(&sb, '-')) + goto err; + used++; + } else { + evlist__for_each_entry_from(evsel->evlist, pos) { + if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) = && + (pos->br_cntr_idx =3D=3D i)) + break; + } + if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG) + saturated =3D true; + + for (j =3D 0; j < avg; j++, used++) { + /* Print + if the number of logged events > 3 */ + if (j >=3D ANNOTATION_BR_CNTR_SATURATION) { + saturated =3D true; + break; + } + if (strbuf_addstr(&sb, pos->abbr_name)) + goto err; + } + + if (saturated) { + if (strbuf_addch(&sb, '+')) + goto err; + used++; + } + pos =3D list_next_entry(pos, core.node); + } + + for (j =3D used; j < ANNOTATION_BR_CNTR_SATURATION + 1; j++) { + if (strbuf_addch(&sb, ' ')) + goto err; + } + } + + if (!verbose && strbuf_addch(&sb, br_cntr_nr ? '|' : ' ')) + goto err; + + *str =3D strbuf_detach(&sb, NULL); + + return 0; +err: + strbuf_release(&sb); + return -ENOMEM; +} + static void __annotation_line__write(struct annotation_line *al, struct an= notation *notes, bool first_line, bool current_entry, bool change_color, int width, void *obj, unsigned int percent_type, diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 6b3023f3b18f..4fdaa3d5e8d2 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -553,4 +553,7 @@ int annotate_get_basic_blocks(struct symbol *sym, s64 s= rc, s64 dst, =20 void debuginfo_cache__delete(void); =20 +int annotation_br_cntr_entry(char **str, int br_cntr_nr, u64 *br_cntr, + int num_aggr, struct evsel *evsel); +int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool hea= der); #endif /* __PERF_ANNOTATE_H */ diff --git a/tools/perf/util/block-info.c b/tools/perf/util/block-info.c index 04068d48683f..649392bee7ed 100644 --- a/tools/perf/util/block-info.c +++ b/tools/perf/util/block-info.c @@ -40,16 +40,32 @@ static struct block_header_column { [PERF_HPP_REPORT__BLOCK_DSO] =3D { .name =3D "Shared Object", .width =3D 20, + }, + [PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER] =3D { + .name =3D "Branch Counter", + .width =3D 30, } }; =20 -struct block_info *block_info__new(void) +static struct block_info *block_info__new(unsigned int br_cntr_nr) { - return zalloc(sizeof(struct block_info)); + struct block_info *bi =3D zalloc(sizeof(struct block_info)); + + if (bi && br_cntr_nr) { + bi->br_cntr =3D calloc(br_cntr_nr, sizeof(u64)); + if (!bi->br_cntr) { + free(bi); + return NULL; + } + } + + return bi; } =20 void block_info__delete(struct block_info *bi) { + if (bi) + free(bi->br_cntr); free(bi); } =20 @@ -86,7 +102,8 @@ int64_t block_info__cmp(struct perf_hpp_fmt *fmt __maybe= _unused, =20 static void init_block_info(struct block_info *bi, struct symbol *sym, struct cyc_hist *ch, int offset, - u64 total_cycles) + u64 total_cycles, unsigned int br_cntr_nr, + u64 *br_cntr, struct evsel *evsel) { bi->sym =3D sym; bi->start =3D ch->start; @@ -99,10 +116,18 @@ static void init_block_info(struct block_info *bi, str= uct symbol *sym, =20 memcpy(bi->cycles_spark, ch->cycles_spark, NUM_SPARKS * sizeof(u64)); + + if (br_cntr && br_cntr_nr) { + bi->br_cntr_nr =3D br_cntr_nr; + memcpy(bi->br_cntr, &br_cntr[offset * br_cntr_nr], + br_cntr_nr * sizeof(u64)); + } + bi->evsel =3D evsel; } =20 int block_info__process_sym(struct hist_entry *he, struct block_hist *bh, - u64 *block_cycles_aggr, u64 total_cycles) + u64 *block_cycles_aggr, u64 total_cycles, + unsigned int br_cntr_nr) { struct annotation *notes; struct cyc_hist *ch; @@ -125,12 +150,14 @@ int block_info__process_sym(struct hist_entry *he, st= ruct block_hist *bh, struct block_info *bi; struct hist_entry *he_block; =20 - bi =3D block_info__new(); + bi =3D block_info__new(br_cntr_nr); if (!bi) return -1; =20 init_block_info(bi, he->ms.sym, &ch[i], i, - total_cycles); + total_cycles, br_cntr_nr, + notes->branch->br_cntr, + hists_to_evsel(he->hists)); cycles +=3D bi->cycles_aggr / bi->num_aggr; =20 he_block =3D hists__add_entry_block(&bh->block_hists, @@ -327,6 +354,24 @@ static void init_block_header(struct block_fmt *block_= fmt) fmt->width =3D block_column_width; } =20 +static int block_branch_counter_entry(struct perf_hpp_fmt *fmt, + struct perf_hpp *hpp, + struct hist_entry *he) +{ + struct block_fmt *block_fmt =3D container_of(fmt, struct block_fmt, fmt); + struct block_info *bi =3D he->block_info; + char *buf; + int ret; + + if (annotation_br_cntr_entry(&buf, bi->br_cntr_nr, bi->br_cntr, + bi->num_aggr, bi->evsel)) + return 0; + + ret =3D scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, buf); + free(buf); + return ret; +} + static void hpp_register(struct block_fmt *block_fmt, int idx, struct perf_hpp_list *hpp_list) { @@ -357,6 +402,9 @@ static void hpp_register(struct block_fmt *block_fmt, i= nt idx, case PERF_HPP_REPORT__BLOCK_DSO: fmt->entry =3D block_dso_entry; break; + case PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER: + fmt->entry =3D block_branch_counter_entry; + break; default: return; } @@ -390,7 +438,7 @@ static void init_block_hist(struct block_hist *bh, stru= ct block_fmt *block_fmts, static int process_block_report(struct hists *hists, struct block_report *block_report, u64 total_cycles, int *block_hpps, - int nr_hpps) + int nr_hpps, unsigned int br_cntr_nr) { struct rb_node *next =3D rb_first_cached(&hists->entries); struct block_hist *bh =3D &block_report->hist; @@ -405,7 +453,7 @@ static int process_block_report(struct hists *hists, while (next) { he =3D rb_entry(next, struct hist_entry, rb_node); block_info__process_sym(he, bh, &block_report->cycles, - total_cycles); + total_cycles, br_cntr_nr); next =3D rb_next(&he->rb_node); } =20 @@ -435,7 +483,7 @@ struct block_report *block_info__create_report(struct e= vlist *evlist, struct hists *hists =3D evsel__hists(pos); =20 process_block_report(hists, &block_reports[i], total_cycles, - block_hpps, nr_hpps); + block_hpps, nr_hpps, evlist->nr_br_cntr); i++; } =20 diff --git a/tools/perf/util/block-info.h b/tools/perf/util/block-info.h index 0b9e1aad4c55..b9329dc3ab59 100644 --- a/tools/perf/util/block-info.h +++ b/tools/perf/util/block-info.h @@ -18,6 +18,9 @@ struct block_info { u64 total_cycles; int num; int num_aggr; + int br_cntr_nr; + u64 *br_cntr; + struct evsel *evsel; }; =20 struct block_fmt { @@ -36,6 +39,7 @@ enum { PERF_HPP_REPORT__BLOCK_AVG_CYCLES, PERF_HPP_REPORT__BLOCK_RANGE, PERF_HPP_REPORT__BLOCK_DSO, + PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER, PERF_HPP_REPORT__BLOCK_MAX_INDEX }; =20 @@ -46,7 +50,6 @@ struct block_report { int nr_fmts; }; =20 -struct block_info *block_info__new(void); void block_info__delete(struct block_info *bi); =20 int64_t __block_info__cmp(struct hist_entry *left, struct hist_entry *righ= t); @@ -55,7 +58,8 @@ int64_t block_info__cmp(struct perf_hpp_fmt *fmt __maybe_= unused, struct hist_entry *left, struct hist_entry *right); =20 int block_info__process_sym(struct hist_entry *he, struct block_hist *bh, - u64 *block_cycles_aggr, u64 total_cycles); + u64 *block_cycles_aggr, u64 total_cycles, + unsigned int br_cntr_nr); =20 struct block_report *block_info__create_report(struct evlist *evlist, u64 total_cycles, --=20 2.38.1 From nobody Sat Feb 7 17:56:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 96C891A2C10; Tue, 13 Aug 2024 16:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564904; cv=none; b=qVoj02yYCEMe4PhI+/nPTShCS976aEjOtR+wI+iiYnIqjGwiKnRt5ezLyFKdKsPN/TyRls0G3OSWW1I7f4XC0IrMRgALx2CHl7bIOhbdrWHrUgzCKU+7lQgfsk91PAKaktkf2nbJCXDbQsPT/nPyjd8MLysjXiMriIUq+rxENH0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564904; c=relaxed/simple; bh=TyKtHmmCdz/4DUzVCTAlXYoZjzK1XVvU5QFAXNpcfeQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=VfkubVBzSd6B/1h6vmapepJBGinikjjyFRhX8V+0PiFQ9OlOMHMxEIVoDBIwRlqYH2QDIlFC6B/8AczKY4w/WLHu1TpWBVfptFbspRY0aaT8LwqBgR/by3YgBPPYV+ekiK5Hs8bez5WfL7Sy9+8/Frbqz+wc63SssVXUxjn5n6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=fikfgq5I; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="fikfgq5I" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564903; x=1755100903; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TyKtHmmCdz/4DUzVCTAlXYoZjzK1XVvU5QFAXNpcfeQ=; b=fikfgq5ImrZw8vQP7Q+vE9lpcgfhysQ8iWDlr9ACuhea4xvgEYS5k5Aj zPE7f5ds9lNuUR1Rzq/G8dntN8VZlLms1wFn7k5Wz2EPpARkvCO7abe3A jobuQZbPjN22Gz/4g5ifOb8KoO3jF/Qrh10Ao22YiKzXUfYOcRV86Fz4R hh0x8MhqAFRbK/aVi4pHqyOGvyK430I2/Bvdp6prdvoMIDS4lcBxlPFgG mCWL3BnhaAkaJQBHD4J/dMHNfIKFGv7XTU3Ys66RmKb31mT72zDZU08AJ qcNUji1JCuow/x1jjWhyzmawLMTs8h4yGQ9R/W6y6QThzRYf3Yg9ceTtk g==; X-CSE-ConnectionGUID: p55ynFgHRWuZ+HNEnOsnJQ== X-CSE-MsgGUID: cQ/iDAIbSUmYN4OLTry2pg== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383221" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383221" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:37 -0700 X-CSE-ConnectionGUID: GrZgQ8BDRkim3BxoKW0h0w== X-CSE-MsgGUID: A5z//xiJSDCJoJ9sB2rd3Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479756" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:37 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang , Tinghao Zhang Subject: [PATCH V3 7/9] perf annotate: Display the branch counter histogram Date: Tue, 13 Aug 2024 09:02:06 -0700 Message-Id: <20240813160208.2493643-8-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Kan Liang Display the branch counter histogram in the annotation view. Press 'B' to display the branch counter's abbreviation list as well. Samples: 1M of events 'anon group { branch-instructions:ppp, branch-misses = }', 4000 Hz, Event count (approx.): f3 /home/sdp/test/tchain_edit [Percent: local period] Percent =E2=94=82 IPC Cycle Branch Counter (Average IPC: 1.39, = IPC Coverage: 29.4%) =E2=94=82 000000000040175= 5 : 0.00 0.00 =E2=94=82 endbr64 =E2=94=82 push %rbp =E2=94=82 mov %rsp,= %rbp =E2=94=82 movl $0x0,= -0x4(%rbp) 0.00 0.00 =E2=94=821.33 3 |A |- | =E2=86=93 jmp = 25 11.03 11.03 =E2=94=82 11: mov -0x4(= %rbp),%eax =E2=94=82 and $0x1,= %eax =E2=94=82 test %eax,= %eax 17.13 17.13 =E2=94=822.41 1 |A |- | =E2=86=93 je = 21 =E2=94=82 addl $0x1,= -0x4(%rbp) 21.84 21.84 =E2=94=822.22 2 |AA |- | =E2=86=93 jmp = 25 17.13 17.13 =E2=94=82 21: addl $0x1,= -0x4(%rbp) 21.84 21.84 =E2=94=82 25: cmpl $0x27= 0f,-0x4(%rbp) 11.03 11.03 =E2=94=820.61 3 |A |- | =E2=86=91 jle = 11 =E2=94=82 nop =E2=94=82 pop %rbp 0.00 0.00 =E2=94=820.24 20 |AA |B | =E2=86=90 ret Originally-by: Tinghao Zhang Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/builtin-annotate.c | 10 +++++--- tools/perf/ui/browsers/annotate.c | 18 ++++++++++++-- tools/perf/ui/browsers/hists.c | 3 ++- tools/perf/util/annotate.c | 40 ++++++++++++++++++++++++++++--- tools/perf/util/annotate.h | 11 +++++++++ tools/perf/util/disasm.c | 1 + 6 files changed, 74 insertions(+), 9 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 9b4a8a379b5b..3dc6197ef3fa 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -927,11 +927,15 @@ int cmd_annotate(int argc, const char **argv) sort_order =3D "dso,symbol"; =20 /* - * Set SORT_MODE__BRANCH so that annotate display IPC/Cycle - * if branch info is in perf data in TUI mode. + * Set SORT_MODE__BRANCH so that annotate displays IPC/Cycle and + * branch counters, if the corresponding branch info is available + * in the perf data in the TUI mode. */ - if ((use_browser =3D=3D 1 || annotate.use_stdio2) && annotate.has_br_stac= k) + if ((use_browser =3D=3D 1 || annotate.use_stdio2) && annotate.has_br_stac= k) { sort__mode =3D SORT_MODE__BRANCH; + if (annotate.session->evlist->nr_br_cntr > 0) + annotate_opts.show_br_cntr =3D true; + } =20 if (setup_sorting(NULL) < 0) usage_with_options(annotate_usage, options); diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index fe991a81256b..d7e727345dab 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -156,6 +156,7 @@ static void annotate_browser__draw_current_jump(struct = ui_browser *browser) struct symbol *sym =3D ms->sym; struct annotation *notes =3D symbol__annotation(sym); u8 pcnt_width =3D annotation__pcnt_width(notes); + u8 cntr_width =3D annotation__br_cntr_width(); int width; int diff =3D 0; =20 @@ -205,13 +206,13 @@ static void annotate_browser__draw_current_jump(struc= t ui_browser *browser) =20 ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); __ui_browser__line_arrow(browser, - pcnt_width + 2 + notes->src->widths.addr + width, + pcnt_width + 2 + notes->src->widths.addr + width + cntr_width, from, to); =20 diff =3D is_fused(ab, cursor); if (diff > 0) { ui_browser__mark_fused(browser, - pcnt_width + 3 + notes->src->widths.addr + width, + pcnt_width + 3 + notes->src->widths.addr + width + cntr_width, from - diff, diff, to > from); } } @@ -714,6 +715,7 @@ static int annotate_browser__run(struct annotate_browse= r *browser, struct annotation *notes =3D symbol__annotation(ms->sym); const char *help =3D "Press 'h' for help on key bindings"; int delay_secs =3D hbt ? hbt->refresh : 0; + char *br_cntr_text =3D NULL; char title[256]; int key; =20 @@ -730,6 +732,8 @@ static int annotate_browser__run(struct annotate_browse= r *browser, =20 nd =3D browser->curr_hot; =20 + annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false); + while (1) { key =3D ui_browser__run(&browser->b, delay_secs); =20 @@ -796,6 +800,7 @@ static int annotate_browser__run(struct annotate_browse= r *browser, "r Run available scripts\n" "p Toggle percent type [local/global]\n" "b Toggle percent base [period/hits]\n" + "B Branch counter abbr list (Optional)\n" "? Search string backwards\n" "f Toggle showing offsets to full address\n"); continue; @@ -904,6 +909,14 @@ static int annotate_browser__run(struct annotate_brows= er *browser, hists__scnprintf_title(hists, title, sizeof(title)); annotate_browser__show(&browser->b, title, help); continue; + case 'B': + if (br_cntr_text) + ui_browser__help_window(&browser->b, br_cntr_text); + else { + ui_browser__help_window(&browser->b, + "\n The branch counter is not available.\n"); + } + continue; case 'f': annotation__toggle_full_addr(notes, ms); continue; @@ -923,6 +936,7 @@ static int annotate_browser__run(struct annotate_browse= r *browser, } out: ui_browser__hide(&browser->b); + free(br_cntr_text); return key; } =20 diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 970f7f349298..49ba82bf3391 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3705,7 +3705,8 @@ int block_hists_tui_browse(struct block_hist *bh, str= uct evsel *evsel, =20 memset(&action, 0, sizeof(action)); =20 - annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false); + if (!annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false)) + annotate_opts.show_br_cntr =3D true; =20 while (1) { key =3D hist_browser__run(browser, "? - help", true, 0); diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 5200cafe20e7..4990c70b1794 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -501,8 +501,10 @@ static void annotation__count_and_fill(struct annotati= on *notes, u64 start, u64 } } =20 -static int annotation__compute_ipc(struct annotation *notes, size_t size) +static int annotation__compute_ipc(struct annotation *notes, size_t size, + struct evsel *evsel) { + unsigned int br_cntr_nr =3D evsel->evlist->nr_br_cntr; int err =3D 0; s64 offset; =20 @@ -537,6 +539,20 @@ static int annotation__compute_ipc(struct annotation *= notes, size_t size) al->cycles->max =3D ch->cycles_max; al->cycles->min =3D ch->cycles_min; } + if (al && notes->branch->br_cntr) { + if (!al->br_cntr) { + al->br_cntr =3D calloc(br_cntr_nr, sizeof(u64)); + if (!al->br_cntr) { + err =3D ENOMEM; + break; + } + } + al->num_aggr =3D ch->num_aggr; + al->br_cntr_nr =3D br_cntr_nr; + al->evsel =3D evsel; + memcpy(al->br_cntr, ¬es->branch->br_cntr[offset * br_cntr_nr], + br_cntr_nr * sizeof(u64)); + } } } =20 @@ -548,8 +564,10 @@ static int annotation__compute_ipc(struct annotation *= notes, size_t size) struct annotation_line *al; =20 al =3D annotated_source__get_line(notes->src, offset); - if (al) + if (al) { zfree(&al->cycles); + zfree(&al->br_cntr); + } } } } @@ -1960,6 +1978,22 @@ static void __annotation_line__write(struct annotati= on_line *al, struct annotati "Cycle(min/max)"); } =20 + if (annotate_opts.show_br_cntr) { + if (show_title) { + obj__printf(obj, "%*s ", + ANNOTATION__BR_CNTR_WIDTH, + "Branch Counter"); + } else { + char *buf; + + if (!annotation_br_cntr_entry(&buf, al->br_cntr_nr, al->br_cntr, + al->num_aggr, al->evsel)) { + obj__printf(obj, "%*s ", ANNOTATION__BR_CNTR_WIDTH, buf); + free(buf); + } + } + } + if (show_title && !*al->line) { ipc_coverage_string(bf, sizeof(bf), notes); obj__printf(obj, "%*s", ANNOTATION__AVG_IPC_WIDTH, bf); @@ -2056,7 +2090,7 @@ int symbol__annotate2(struct map_symbol *ms, struct e= vsel *evsel, annotation__set_index(notes); annotation__mark_jump_targets(notes, sym); =20 - err =3D annotation__compute_ipc(notes, size); + err =3D annotation__compute_ipc(notes, size, evsel); if (err) return err; =20 diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 4fdaa3d5e8d2..8b9e05a1932f 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -31,6 +31,7 @@ struct annotated_data_type; #define ANNOTATION__CYCLES_WIDTH 6 #define ANNOTATION__MINMAX_CYCLES_WIDTH 19 #define ANNOTATION__AVG_IPC_WIDTH 36 +#define ANNOTATION__BR_CNTR_WIDTH 30 #define ANNOTATION_DUMMY_LEN 256 =20 struct annotation_options { @@ -44,6 +45,7 @@ struct annotation_options { show_nr_jumps, show_minmax_cycle, show_asm_raw, + show_br_cntr, annotate_src, full_addr; u8 offset_level; @@ -104,6 +106,10 @@ struct annotation_line { char *fileloc; char *path; struct cycles_info *cycles; + int num_aggr; + int br_cntr_nr; + u64 *br_cntr; + struct evsel *evsel; int jump_sources; u32 idx; int idx_asm; @@ -353,6 +359,11 @@ static inline bool annotation_line__filter(struct anno= tation_line *al) return annotate_opts.hide_src_code && al->offset =3D=3D -1; } =20 +static inline u8 annotation__br_cntr_width(void) +{ + return annotate_opts.show_br_cntr ? ANNOTATION__BR_CNTR_WIDTH : 0; +} + void annotation__update_column_widths(struct annotation *notes); void annotation__toggle_full_addr(struct annotation *notes, struct map_sym= bol *ms); =20 diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 22289003e16d..68aae87101bd 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -1014,6 +1014,7 @@ static void annotation_line__exit(struct annotation_l= ine *al) zfree_srcline(&al->path); zfree(&al->line); zfree(&al->cycles); + zfree(&al->br_cntr); } =20 static size_t disasm_line_size(int nr) --=20 2.38.1 From nobody Sat Feb 7 17:56:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04C2E1A2C21; Tue, 13 Aug 2024 16:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564905; cv=none; b=TKAy2vSKmhU+tAnlseOi+fQOnwryxl2YlXe5H6xk+cYNx3yg4FvWvQ74GexwiFvsdtT+yaVdsXyXcy4SnOhddgxJFN3E5MU8/5UkgM/kNeorYXCOZPjAwRvL7fVzfWRd4S3bVROHxfdKzG1a+b7WWBsjqtPc5Xk1xQOJCvVDSrk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564905; c=relaxed/simple; bh=u1pTqMjYDZsfAePqwZ018IaSJayVWkUkjKUsn88vuXM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UuCYjE0twYfMyx7NxiWPqK/5ignCOhkm2NbcvtLR0f1/fOuTImmaHZ3F2HWH2+6OMBJdrxCGqKbxuiXlJBE8P07fb665HnbitH7h6txKm4blcmjiwVAe5oCJeS3wNyx26VW4h7AszShEw238suz3W3+k9tlbVpsMvehcrkJV+PU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=EGQmA57m; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="EGQmA57m" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564903; x=1755100903; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=u1pTqMjYDZsfAePqwZ018IaSJayVWkUkjKUsn88vuXM=; b=EGQmA57m+8azj8Ldujttu2Y5wLZ4J/Cs6G5rtJRk78Oz8yy489b0GAqv rzew+exsRg6q2pCS2wsk9if+kICVuXW6DsEp/7gVz9KsyksPYRfyscasc cC3PepIHpCQp5yGU58v4zCVqCNzf3zDqcdjzReqLyobmXz+Hk7o/RMNEr 6ttSAaJradCjJhAEnRs2ObO2vOlFoACPXv7uSZLrgq6SG3RBITtvy5U2i 4nZ9WHJavpSSZP8w03rrjHWId0U61xVicOalB8bSHtcVVgXMSiSq+o7Xt +mhz4rzBHZJf+A6yZMR9jlRhJBbxpVTKIhTxW1+aqpItFQaUO2/pjGORw g==; X-CSE-ConnectionGUID: 2ooB/QomTdur9oRpGMLOcQ== X-CSE-MsgGUID: RxgNjpkjQgG/+oZpq7PK4Q== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383225" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383225" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:37 -0700 X-CSE-ConnectionGUID: fEq8fnvdTL+38A2PRuMVqg== X-CSE-MsgGUID: yj1wM1+4QmqfwrS/P2wYtA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479759" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:37 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang , Tinghao Zhang Subject: [PATCH V3 8/9] perf script: Add branch counters Date: Tue, 13 Aug 2024 09:02:07 -0700 Message-Id: <20240813160208.2493643-9-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang It's useful to print the branch counter information for each jump in the brstackinsn when it's available. Add a new field brcntr to display the branch counter information. By default, the abbreviation will be used to indicate the branch counter. In the verbose mode, the real event name is shown. $perf script -F +brstackinsn,+brcntr # Branch counter abbr list: # branch-instructions:ppp =3D A # branch-misses =3D B # '-' No event occurs # '+' Event occurrences may be lost due to branch counter saturated tchain_edit 332203 3366329.405674: 53030 branch-instructions:ppp= : 401781 f3+0x2c (home/sdp/test/tchain_edit) f3+31: 0000000000401774 insn: eb 04 br_cntr: AA= # PRED 5 cycles [5] 000000000040177a insn: 81 7d fc 0f 27 00 00 0000000000401781 insn: 7e e3 br_cntr: A = # PRED 1 cycles [6] 2.00 IPC 0000000000401766 insn: 8b 45 fc 0000000000401769 insn: 83 e0 01 000000000040176c insn: 85 c0 000000000040176e insn: 74 06 br_cntr: A = # PRED 1 cycles [7] 4.00 IPC 0000000000401776 insn: 83 45 fc 01 000000000040177a insn: 81 7d fc 0f 27 00 00 0000000000401781 insn: 7e e3 br_cntr: A = # PRED 7 cycles [14] 0.43 IPC $perf script -F +brstackinsn,+brcntr -v tchain_edit 332203 3366329.405674: 53030 branch-instructions:ppp= : 401781 f3+0x2c (/home/sdp/os.linux.perf.test-suite/kernels/lbr= _kernel/tchain_edit) f3+31: 0000000000401774 insn: eb 04 br_cntr: br= anch-instructions:ppp 2 branch-misses 0 # PRED 5 cycles [5] 000000000040177a insn: 81 7d fc 0f 27 00 00 0000000000401781 insn: 7e e3 br_cntr: br= anch-instructions:ppp 1 branch-misses 0 # PRED 1 cycles [6] 2.00 IPC 0000000000401766 insn: 8b 45 fc 0000000000401769 insn: 83 e0 01 000000000040176c insn: 85 c0 000000000040176e insn: 74 06 br_cntr: br= anch-instructions:ppp 1 branch-misses 0 # PRED 1 cycles [7] 4.00 IPC 0000000000401776 insn: 83 45 fc 01 000000000040177a insn: 81 7d fc 0f 27 00 00 0000000000401781 insn: 7e e3 br_cntr: br= anch-instructions:ppp 1 branch-misses 0 # PRED 7 cycles [14] 0.43 IPC Originally-by: Tinghao Zhang Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-script.c | 69 +++++++++++++++++++++--- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Document= ation/perf-script.txt index 5abb960c4960..b72866ef270b 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -134,7 +134,7 @@ OPTIONS srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-out= put, brstackinsn, brstackinsnlen, brstackdisasm, brstackoff, callindent= , insn, disasm, insnlen, synth, phys_addr, metric, misc, srccode, ipc, data_page_s= ize, - code_page_size, ins_lat, machine_pid, vcpu, cgroup, retire_lat, + code_page_size, ins_lat, machine_pid, vcpu, cgroup, retire_lat, br= cntr, =20 Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 54598d1e815a..206b08426555 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -62,6 +62,7 @@ #include "util/record.h" #include "util/util.h" #include "util/cgroup.h" +#include "util/annotate.h" #include "perf.h" =20 #include @@ -138,6 +139,7 @@ enum perf_output_field { PERF_OUTPUT_DSOFF =3D 1ULL << 41, PERF_OUTPUT_DISASM =3D 1ULL << 42, PERF_OUTPUT_BRSTACKDISASM =3D 1ULL << 43, + PERF_OUTPUT_BRCNTR =3D 1ULL << 44, }; =20 struct perf_script { @@ -213,6 +215,7 @@ struct output_option { {.str =3D "cgroup", .field =3D PERF_OUTPUT_CGROUP}, {.str =3D "retire_lat", .field =3D PERF_OUTPUT_RETIRE_LAT}, {.str =3D "brstackdisasm", .field =3D PERF_OUTPUT_BRSTACKDISASM}, + {.str =3D "brcntr", .field =3D PERF_OUTPUT_BRCNTR}, }; =20 enum { @@ -520,6 +523,12 @@ static int evsel__check_attr(struct evsel *evsel, stru= ct perf_session *session) "Hint: run 'perf record -b ...'\n"); return -EINVAL; } + if (PRINT_FIELD(BRCNTR) && + !(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_= COUNTERS)) { + pr_err("Display of branch counter requested but it's not enabled\n" + "Hint: run 'perf record -j any,counter ...'\n"); + return -EINVAL; + } if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PER= F_OUTPUT_PID)) return -EINVAL; @@ -789,6 +798,19 @@ static int perf_sample__fprintf_start(struct perf_scri= pt *script, int printed =3D 0; char tstr[128]; =20 + /* + * Print the branch counter's abbreviation list, + * if the branch counter is available. + */ + if (PRINT_FIELD(BRCNTR) && !verbose) { + char *buf; + + if (!annotation_br_cntr_abbr_list(&buf, evsel, true)) { + printed +=3D fprintf(stdout, "%s", buf); + free(buf); + } + } + if (PRINT_FIELD(MACHINE_PID) && sample->machine_pid) printed +=3D fprintf(fp, "VM:%5d ", sample->machine_pid); =20 @@ -1195,7 +1217,9 @@ static int ip__fprintf_jump(uint64_t ip, struct branc= h_entry *en, struct perf_insn *x, u8 *inbuf, int len, int insn, FILE *fp, int *total_cycles, struct perf_event_attr *attr, - struct thread *thread) + struct thread *thread, + struct evsel *evsel, + u64 br_cntr) { int ilen =3D 0; int printed =3D fprintf(fp, "\t%016" PRIx64 "\t", ip); @@ -1216,6 +1240,28 @@ static int ip__fprintf_jump(uint64_t ip, struct bran= ch_entry *en, addr_location__exit(&al); } =20 + if (PRINT_FIELD(BRCNTR)) { + unsigned int width =3D evsel__env(evsel)->br_cntr_width; + unsigned int i =3D 0, j, num, mask =3D (1L << width) - 1; + struct evsel *pos =3D evsel__leader(evsel); + + printed +=3D fprintf(fp, "br_cntr: "); + evlist__for_each_entry_from(evsel->evlist, pos) { + if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) + continue; + if (evsel__leader(pos) !=3D evsel__leader(evsel)) + break; + + num =3D (br_cntr >> (i++ * width)) & mask; + if (!verbose) { + for (j =3D 0; j < num; j++) + printed +=3D fprintf(fp, "%s", pos->abbr_name); + } else + printed +=3D fprintf(fp, "%s %d ", pos->name, num); + } + printed +=3D fprintf(fp, "\t"); + } + printed +=3D fprintf(fp, "#%s%s%s%s", en->flags.predicted ? " PRED" : "", en->flags.mispred ? " MISPRED" : "", @@ -1272,6 +1318,7 @@ static int ip__fprintf_sym(uint64_t addr, struct thre= ad *thread, } =20 static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, + struct evsel *evsel, struct thread *thread, struct perf_event_attr *attr, struct machine *machine, FILE *fp) @@ -1285,6 +1332,7 @@ static int perf_sample__fprintf_brstackinsn(struct pe= rf_sample *sample, unsigned off; struct symbol *lastsym =3D NULL; int total_cycles =3D 0; + u64 br_cntr =3D 0; =20 if (!(br && br->nr)) return 0; @@ -1296,6 +1344,9 @@ static int perf_sample__fprintf_brstackinsn(struct pe= rf_sample *sample, x.machine =3D machine; x.cpu =3D sample->cpu; =20 + if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr) + br_cntr =3D sample->branch_stack_cntr[nr - 1]; + printed +=3D fprintf(fp, "%c", '\n'); =20 /* Handle first from jump, of which we don't know the entry. */ @@ -1307,7 +1358,7 @@ static int perf_sample__fprintf_brstackinsn(struct pe= rf_sample *sample, x.cpumode, x.cpu, &lastsym, attr, fp); printed +=3D ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1], &x, buffer, len, 0, fp, &total_cycles, - attr, thread); + attr, thread, evsel, br_cntr); if (PRINT_FIELD(SRCCODE)) printed +=3D print_srccode(thread, x.cpumode, entries[nr - 1].from); } @@ -1337,8 +1388,10 @@ static int perf_sample__fprintf_brstackinsn(struct p= erf_sample *sample, =20 printed +=3D ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, at= tr, fp); if (ip =3D=3D end) { + if (PRINT_FIELD(BRCNTR) && sample->branch_stack_cntr) + br_cntr =3D sample->branch_stack_cntr[i]; printed +=3D ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len -= off, ++insn, fp, - &total_cycles, attr, thread); + &total_cycles, attr, thread, evsel, br_cntr); if (PRINT_FIELD(SRCCODE)) printed +=3D print_srccode(thread, x.cpumode, ip); break; @@ -1547,6 +1600,7 @@ void script_fetch_insn(struct perf_sample *sample, st= ruct thread *thread, } =20 static int perf_sample__fprintf_insn(struct perf_sample *sample, + struct evsel *evsel, struct perf_event_attr *attr, struct thread *thread, struct machine *machine, FILE *fp, @@ -1567,7 +1621,7 @@ static int perf_sample__fprintf_insn(struct perf_samp= le *sample, printed +=3D sample__fprintf_insn_asm(sample, thread, machine, fp, al); } if (PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN) || PRINT_FIEL= D(BRSTACKDISASM)) - printed +=3D perf_sample__fprintf_brstackinsn(sample, thread, attr, mach= ine, fp); + printed +=3D perf_sample__fprintf_brstackinsn(sample, evsel, thread, att= r, machine, fp); =20 return printed; } @@ -1639,7 +1693,7 @@ static int perf_sample__fprintf_bts(struct perf_sampl= e *sample, if (print_srcline_last) printed +=3D map__fprintf_srcline(al->map, al->addr, "\n ", fp); =20 - printed +=3D perf_sample__fprintf_insn(sample, attr, thread, machine, fp,= al); + printed +=3D perf_sample__fprintf_insn(sample, evsel, attr, thread, machi= ne, fp, al); printed +=3D fprintf(fp, "\n"); if (PRINT_FIELD(SRCCODE)) { int ret =3D map__fprintf_srccode(al->map, al->addr, stdout, @@ -2297,7 +2351,7 @@ static void process_event(struct perf_script *script, =20 if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) perf_sample__fprintf_bpf_output(sample, fp); - perf_sample__fprintf_insn(sample, attr, thread, machine, fp, al); + perf_sample__fprintf_insn(sample, evsel, attr, thread, machine, fp, al); =20 if (PRINT_FIELD(PHYS_ADDR)) fprintf(fp, "%16" PRIx64, sample->phys_addr); @@ -3947,7 +4001,8 @@ int cmd_script(int argc, const char **argv) "brstacksym,flags,data_src,weight,bpf-output,brstackinsn," "brstackinsnlen,brstackdisasm,brstackoff,callindent,insn,disasm,ins= nlen,synth," "phys_addr,metric,misc,srccode,ipc,tod,data_page_size," - "code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat", + "code_page_size,ins_lat,machine_pid,vcpu,cgroup,retire_lat," + "brcntr", parse_output_fields), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), --=20 2.38.1 From nobody Sat Feb 7 17:56:02 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D18831A38C8; Tue, 13 Aug 2024 16:01:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564905; cv=none; b=BlI5d60nLwlXdu1zSXWU9xXRmvjssvHPCovJGslrriZomkN8twVGHBKdagyNGhnCmAtFTYhV1rgZb/m0NJ2WxLcrkrgElLRGhhZc7Gija3kqt/xIgcwuVh8QX6W3xAew4DEIqJXoqq0qIyrhQIcw8v3byAtWBM0x9zLUiXLbNiw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723564905; c=relaxed/simple; bh=iDcHhBjklszsHCFlB1I+Epu/zTkyEf/8+o8VvG5QsHY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=V5CXfET0wWDKWDXZctyut/kA7x1PwN/5aYpNja0E9g9kMLO9Cmu89hHlEodNSYEPrTq/rG4mhGPBF4Wco9zfDgRaUIw3sC2NQXWMUAJtDsv9O07yYE0RhBsAiiQag8DxirJr/zRzhChjJe2yWUWJdFactu4U7jEMjRKcGxQZqYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=UUqKfY8f; arc=none smtp.client-ip=192.198.163.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="UUqKfY8f" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723564904; x=1755100904; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iDcHhBjklszsHCFlB1I+Epu/zTkyEf/8+o8VvG5QsHY=; b=UUqKfY8fUgjL5dinrRnCk/R5rz4JpTekt6zdbiJy3OUPNeYXb3TpEAVF nSEvOGJXvxvVQd2ScyVUqe2N2bEjEvIp46BB1g637AuflcnO/goThuv7c BbLMdBJ10PFhKFFpiDZWRjuYbMY0q/Bqytpynd8+cfkE3z+jDGTYeP+bm pffh27M09qDQV9YuuHXL910Znl0FBldrqFlMJtSvUshebQ7eH858Sd3gg rGjjGkRw7cAnvPXjmiD+s+2Tg0e24GGqUtzb8l5EEKOuIhnwSmvOyZUOw evkD7VZyF3ppdeBmVqjdUjS/KNofFPk9YuXWqHHY8HnO7YVSPiPsuD6HX g==; X-CSE-ConnectionGUID: rUDSSvcGTImf6py9rMIU5A== X-CSE-MsgGUID: vHr4eDkyTK6C678xjTU3SA== X-IronPort-AV: E=McAfee;i="6700,10204,11163"; a="21383230" X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="21383230" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Aug 2024 09:01:37 -0700 X-CSE-ConnectionGUID: lTzbP6CeSUCGpyZWHRARFg== X-CSE-MsgGUID: 5V37HyPHQcO0+keY8/NkFg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,286,1716274800"; d="scan'208";a="59479762" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by orviesa008.jf.intel.com with ESMTP; 13 Aug 2024 09:01:37 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V3 9/9] perf test: Add new test cases for the branch counter feature Date: Tue, 13 Aug 2024 09:02:08 -0700 Message-Id: <20240813160208.2493643-10-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240813160208.2493643-1-kan.liang@linux.intel.com> References: <20240813160208.2493643-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang Enhance the test case for the branch counter feature. Now, the test verifies - The new filter can be successfully applied on the supported platforms. - The counter value can be outputted via the perf report -D - The counter value and the abbr name can be outputted via the perf script (New) Acked-by: Namhyung Kim Reviewed-by: Andi Kleen Signed-off-by: Kan Liang --- tools/perf/tests/shell/record.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/reco= rd.sh index 3d1a7759a7b2..7964ebd9007d 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -21,6 +21,7 @@ testprog=3D"perf test -w thloop" cpu_pmu_dir=3D"/sys/bus/event_source/devices/cpu*" br_cntr_file=3D"/caps/branch_counter_nr" br_cntr_output=3D"branch stack counters" +br_cntr_script_output=3D"br_cntr: A" =20 cleanup() { rm -rf "${perfdata}" @@ -165,7 +166,7 @@ test_workload() { } =20 test_branch_counter() { - echo "Basic branch counter test" + echo "Branch counter test" # Check if the branch counter feature is supported for dir in $cpu_pmu_dir do @@ -175,19 +176,25 @@ test_branch_counter() { return fi done - if ! perf record -o "${perfdata}" -j any,counter ${testprog} 2> /dev/null + if ! perf record -o "${perfdata}" -e "{branches:p,instructions}" -j any,= counter ${testprog} 2> /dev/null then - echo "Basic branch counter test [Failed record]" + echo "Branch counter record test [Failed record]" err=3D1 return fi if ! perf report -i "${perfdata}" -D -q | grep -q "$br_cntr_output" then - echo "Basic branch record test [Failed missing output]" + echo "Branch counter report test [Failed missing output]" err=3D1 return fi - echo "Basic branch counter test [Success]" + if ! perf script -i "${perfdata}" -F +brstackinsn,+brcntr | grep -q "$br= _cntr_script_output" + then + echo " Branch counter script test [Failed missing output]" + err=3D1 + return + fi + echo "Branch counter test [Success]" } =20 test_per_thread --=20 2.38.1