From nobody Sat Feb 7 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 CFC7B567D for ; Wed, 3 Jul 2024 20:03:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037006; cv=none; b=p63QDBpvCsQf00VnD213TYYQq+n45KgfCp+QrrWFEpsEr4ubiiRk3NXDkyQUOab1anpFKcTefi7cL9jR1sQnY6L7BWBTsOBpWkvg5l5XqQksm+SOCAnOO2dzdvzc4dF7hq512/L/Vp4IbvRxoQN6GEyesYpTtxfsUR+GdlUH3DU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037006; c=relaxed/simple; bh=1lnmijjEyM+iKRxKs5E+zqzgewb6VXfpWqoba3U+K2Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eWeFkjemHuAXCgQNd7LFlhiXmoMQVNFd9H8qTbO6JJtIP68scz58VRdCCWgiImngIN+qZTKNt53HRT2m3IMvjpoJS7F4h1kN3+vBaQ2BHVNgVbpWRR0Z/NbXwcHQ2vmM7yeZSuJ5LiwVkrABblCzGgZ0SRoo6kvubXjcpW5BcJQ= 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=TK3OCq0c; arc=none smtp.client-ip=198.175.65.9 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="TK3OCq0c" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037005; x=1751573005; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1lnmijjEyM+iKRxKs5E+zqzgewb6VXfpWqoba3U+K2Q=; b=TK3OCq0cd2SVP6s8cLGqs9WrnMj4WXKTRbxizot3luuJLEOM4fGwL/Le cBAzt6oliT2XNK17aKmkBS4pyjIuyV8ilPYYnSaI9s3kuhdoE9v2aALr2 2D29rzFNh2Rdk71LUaLxoXacuX80UJ2JzYvmTGU5ClGtrpeycL8wCVBZr ag72cmvvXcOi/eJ67jRIr5c1Rh5z7uDfKBA82tJlx4Zvb0I+UXFT1sVl6 NrHIsyTB9aqlunscgxoNmDTFPMr/X4LFEHXPFgu6PVEBI4cN4V813ktpI 6/Cu22vEHC5Xznu9xLuGKoCgIlOgsU/4gnP02SBd7nsQVrW6F80HQHEUW g==; X-CSE-ConnectionGUID: jOYy8V41TEaIM+ltSfKLKA== X-CSE-MsgGUID: XS1wBnRLQPC9YkQmpfGrCA== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807563" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807563" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:24 -0700 X-CSE-ConnectionGUID: Y5WAf1T+SeS/YCSKEmZ/rg== X-CSE-MsgGUID: sxmAv0xBR3etZDlum39Epw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442543" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:23 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH 1/9] perf report: Fix --total-cycles --stdio output error Date: Wed, 3 Jul 2024 13:03:48 -0700 Message-Id: <20240703200356.852727-2-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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") Signed-off-by: Kan Liang Acked-by: Namhyung Kim --- 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 9718770facb5..b9f22c5321da 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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 97CD8138495 for ; Wed, 3 Jul 2024 20:03:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037007; cv=none; b=n2EilQhHJhbZ3nBgx0adKXUnYHvfNIfgSZ/dBDK/4svQDSw3eZid1VZuFdEn9iQmk+b2pFBnnzXmpcpTJIsHoJX/Il/uE8x+7C377nDFonLmNgUn0uf1V6uTOn7SUqFkKgrp49qs8BuM1WjQWADe7BfmAqyhC22ZARbVBZQMwvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037007; c=relaxed/simple; bh=Vaax5cGGtoogj26pRgneNRu+6h5uUKF5KLvkOclKNA0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OGNZ6YsNuGb6REons9SqaZKiZ/UI0ilxRjVFcc+Zrg8zWo4JtyNKv8Q9342gNOGHanGIr2KAWZc+UL3q151oTGyAWOb30OhW1A2d8R/JiatAbV4MJEZ4cm6rJJimiIux4nBvBLPQyaf1OgDgzRflk9S+oYy9IX+6j+PMxKAXEJs= 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=h1LyIaPS; arc=none smtp.client-ip=198.175.65.9 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="h1LyIaPS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037006; x=1751573006; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Vaax5cGGtoogj26pRgneNRu+6h5uUKF5KLvkOclKNA0=; b=h1LyIaPS7y/5bikmW5GxMKAVNTmTrhw2P0NOyXE6Xz/ahIICagpMPs/K 1eHYezNB5whBOQW58vVoZKtNGeqvPIxdcinwYVrocrRNKv0GiUgqCa7Xh XubdxfdwEOyg4O9cITOCa8q8XhO+B0J2MQDCl1o8VqDD2b2PH8q+YloH4 M/ivg2s6+T7PrcXGTJvMk3Ngf/2aNkOEDMFrCWTFLhr5uwb66i6oPJ7d0 2y8EMeL6rTtNF6a8L0+r32PBznhHE/17TIMkbg1DNrJicmxrBLduPOagL GrindiUU7bgpGkA2j3NLYi2dR+p3bjw49PQ8p38M9vRmAIChAJNTMZ/QC g==; X-CSE-ConnectionGUID: /61+Nte2T/qzs7NtYhmBog== X-CSE-MsgGUID: MdTPXA8wQqquiYtGCHQBGQ== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807567" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807567" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:24 -0700 X-CSE-ConnectionGUID: eMHOJnlmR3qSo51fIsEGtg== X-CSE-MsgGUID: F+mjZy/aTHGCt4BZhZ2uzg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442554" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:23 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH 2/9] perf report: Remove the first overflow check for branch counters Date: Wed, 3 Jul 2024 13:03:49 -0700 Message-Id: <20240703200356.852727-3-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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") Signed-off-by: Kan Liang Acked-by: Namhyung Kim --- 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 bc603193c477..a5dd031c9080 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2810,8 +2810,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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 37BED1849EB for ; Wed, 3 Jul 2024 20:03:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037007; cv=none; b=fTg9w3bHRhDSdJBs+qZHC5qgYZK4Jj0LVMgYj0WS53Gn8kkgIHop431HqK8YpRPQQ4eBYXFy4T9d9UDbfEWZoGt9AGzQEAMZDuAwzysukOchpuHZe+/iLTwvJQpP5m7aLlFrCU8nakcslETBRloPKx2rI9//f2NvQTs709oOL3A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037007; c=relaxed/simple; bh=PnDdlfcERxVSvWUX3ql7Jr5lCD7PahiVaogQ8rp5bfU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HgUOIUtJVFxAtnJJ5ahOB2ppexzFM2Rha5hV8QVFYoWrY9W7QDpyGAiMPtbIZognkqj5gxTdjuEkP/+Tp0B9TQXGipN7zGiVN5xiozKHwYcjz+rScRnYtVzKx44CQPVDZUyE2t6CcXr8dCCxI7TI/4xoed4SW0a1gpZo1gTMXgE= 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=nUynTbGr; arc=none smtp.client-ip=198.175.65.9 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="nUynTbGr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037006; x=1751573006; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PnDdlfcERxVSvWUX3ql7Jr5lCD7PahiVaogQ8rp5bfU=; b=nUynTbGrmRF4sX/K10d1cySejLVB3CFi9uk/WZbc046/ws+XCljPlt+C bbHLDneOyw/+mPbwTTomRXym5rxaXsaaGAgB5T+g/i/Yq0RhXR2bLwdsQ 7mcaz+YmzarFiGJgzUqQBfeJO2CWS0QtiZo1X+1GIEI5b7NeFQUS7mhWP Ge5XjCW/WDhrsp0agfGu3lDF1p2aPe89OARUJPJUaF/D1EGcQLdgkdEIo HBqDhOfRXsH2C86u8SkDRQZP6pWnTrh/io9QGSB8XLXjn9wyT2IaMuR7J TiYrewsdRwbl4uGXU3vfJqTH9zzT/wgHiqCMCNq07Kc7wkLAaM/oUfd/G A==; X-CSE-ConnectionGUID: zmqscmi2To2kdXCutvmZsw== X-CSE-MsgGUID: 7RWldaUWTQedE9puPRHF7A== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807576" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807576" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:25 -0700 X-CSE-ConnectionGUID: Iq3UV6fWQQmLF1DfDZ1oIw== X-CSE-MsgGUID: 1scwYKs/S0+K7HkEZGYl+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442561" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:24 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH 3/9] perf evlist: Save branch counters information Date: Wed, 3 Jul 2024 13:03:50 -0700 Message-Id: <20240703200356.852727-4-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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. 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 3a719edafc7a..6f5311d01a14 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -78,6 +78,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) @@ -1261,6 +1262,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 cb91dc9117a2..88206dd554c7 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -56,6 +56,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 { @@ -217,6 +218,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 a5dd031c9080..89c3baae926e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2562,17 +2562,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 80b5f6dd868e..a733d3407b35 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -147,6 +147,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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 95F1E18C33E for ; Wed, 3 Jul 2024 20:03:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037008; cv=none; b=GNgYGtIqivsv75IMGHVIpbBiZ4c/77F6CzBZx8AIbk8njr5fNYIFO7g8rA4iDnZZ/3tMWCzGbN69FjNgVs7WJHdXxs3jPlS+lbmY69ZvEjwFi2zu9Mg1mmM3vs81GPueKsHTulOm+JrDLAC4BOAJ8s5ucOwYwqdwr7IG1wnjFJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037008; c=relaxed/simple; bh=CX5wlUOzAgLyFjF9LKsD0KamFVv776tq9vtJojAPpks=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PGD+jwZ+ZeaC4kg/05am111D8qBbuixfbGtOw8X79vn4XwCehdRIonve0zyxqkrAcStRJsdYyVx5kFcmOmMUKUIe7iV8OaPXC7B8Rj6cfNnL/DUscbKw4bknfm+FWYqZ+pOavSejDD2AfhCS0XXzLQ1tlWrs8tJUT0wNekVCY2E= 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=cO/vEsO3; arc=none smtp.client-ip=198.175.65.9 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="cO/vEsO3" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037007; x=1751573007; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CX5wlUOzAgLyFjF9LKsD0KamFVv776tq9vtJojAPpks=; b=cO/vEsO38v/At6raHLbutMOAuFxgEtJ/bJrd6KuMWWOICztn+cgG3cmf UIhdTGqUcFCPdbTbWqEvQHfOZtwSN1Dph+rjJjLgI+/ApH+biZ05O7p9D cr/xl1qOB3wPm2Zu5qg7/pnlKjsxvohYNUm2xwW//BIsSxLatk/0urCfh pDs/bUzEtWVCPKtcEcJTJAkZKmRkllzBsdX+vIfJSU/u8ApoI2ko56Z8D VI6pYK88MO70g0TCbU8BOMifPinPHj/o+fOyLogNapn3K5gG/RvtbP89h rS9f1Tg9iVo5UlpbknxDwSixIMWT33H4fceSGNWH9fvmT735S/PoBkzEa A==; X-CSE-ConnectionGUID: mRlESHmnR1yWjUk+X44Fcg== X-CSE-MsgGUID: 2IFhAwSOTvG1TaBM7mhGvg== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807586" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807586" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:26 -0700 X-CSE-ConnectionGUID: XJdZqdf0SN2gppKDXzrs8A== X-CSE-MsgGUID: yQeG51FiScitX2kJFw673Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442570" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:24 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH 4/9] perf annotate: Save branch counters for each block Date: Wed, 3 Jul 2024 13:03:51 -0700 Message-Id: <20240703200356.852727-5-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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. 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 b10b7f005658..0aa40588425c 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 57d300d8e570..2d9226b1de52 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -431,8 +431,8 @@ static int diff__process_sample_event(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 b9f22c5321da..da8d13bbb500 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -328,7 +328,7 @@ static int process_sample_event(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 e8cbbf10d361..040190a64fff 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 1451caf25e77..6baa0671598e 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -265,22 +265,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) @@ -315,16 +323,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; @@ -336,15 +372,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; @@ -370,7 +413,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; @@ -411,6 +454,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 d5c821c22f79..f39dd5d7b05e 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; @@ -285,6 +286,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. * @@ -294,6 +298,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 @@ -310,6 +315,7 @@ struct annotated_branch { unsigned int cover_insn; struct cyc_hist *cycles_hist; u64 max_coverage; + u64 *br_cntr; }; =20 struct LOCKABLE annotation { @@ -380,7 +386,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 f028f113c4fd..c405c7773e15 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2667,7 +2667,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); @@ -2691,7 +2691,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 8477edefc299..19fc7979c66b 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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 29E5218FC7F for ; Wed, 3 Jul 2024 20:03:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037008; cv=none; b=WAVH+BLL163tZwZwR4vm2JeMdzRPEcRSRJ16A/aNsXlzCS49M+9ii+HSzchxkRfOnMzgM5ElhyK9mgEhcb1aZRvQ6GhPB//+avkmP573wSCv4XYL1KUNc9PlS2GwrWeiNMPNAOsBW8YIVqVcMFYtovqy31JDq2bNsWazCoaHMLM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037008; c=relaxed/simple; bh=1GaNK1PymifhZFxq0NBZ6fvfnfWs7uS6/JsGWQPLcdM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DXKaWMIFS3twDw20Gzf2ZtkT1JE6Hh7psUj4IoI3ipy9+VmXlHOz0vyFiQYNSrgyQaqEqPjqa/ipI9bF/P16Qj+v1otogv11pTzDGTMRiwg13CWDxX5mbf7QHQpeApFbejNSAXFK6yi7bp4biNqRWzo/T17ehjuw5GbYf9ZQhhQ= 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=Xc7DtAZF; arc=none smtp.client-ip=198.175.65.9 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="Xc7DtAZF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037007; x=1751573007; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1GaNK1PymifhZFxq0NBZ6fvfnfWs7uS6/JsGWQPLcdM=; b=Xc7DtAZFHhnR58vzL2XfznSMYYQPA+Izw10r4tMVs9v/wP/GI2/IXuq9 5j4JqOr9hAowWMeGBWLgsJMFW7FiRgspalOUtaf5he+zE9uSJFxw3GJk2 x5l5bD4ztnrV0uHMFIr6xD3dnz5l5WyuqiVb/X3mqAWDsdVQ+xX0YK44m Jf6htWVIBunTzbPCB20JRFtKK/ISwlpds5ICAWd4VqnspVtkehUzbBUVf DroDq5TS7pJkNYeCXL+P17kp0kc+2T6NadydTYfXeyc9lU5tVbJ8hkk6Q Z4ONfw1u5H83MFlmU2XaVIG5nOsxXUWdLqq8ALrYzyBPvAh+K8BRK0F5M A==; X-CSE-ConnectionGUID: 2li2xUGOR2G51zZtQypj5g== X-CSE-MsgGUID: BZC5kg9HTNuKy0OcCqsegg== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807595" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807595" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:26 -0700 X-CSE-ConnectionGUID: W4B8xxzOSku+WmCq2xwBQA== X-CSE-MsgGUID: /1AW7v56Q2aaSvYVN10Y/w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442580" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:25 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH 5/9] perf evsel: Assign abbr name for the branch counter events Date: Wed, 3 Jul 2024 13:03:52 -0700 Message-Id: <20240703200356.852727-6-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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. Signed-off-by: Kan Liang --- tools/perf/util/evlist.c | 53 +++++++++++++++++++++++++++++++++++++++- tools/perf/util/evsel.h | 4 +++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 6f5311d01a14..028169dcb53d 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 #include #include @@ -1262,15 +1263,65 @@ 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 char *evlist__new_abbr_name(void) +{ + static int idx; + char str[3]; + int i =3D idx / 26; + + if (idx >=3D MAX_NR_ABBR_NAME) + return strdup("NA"); + + str[0] =3D 'A' + (idx % 26); + + if (!i) + str[1] =3D '\0'; + else { + str[1] =3D '0' + i - 1; + str[2] =3D '\0'; + } + + idx++; + return strdup(str); +} + 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) + evsel->abbr_name =3D strdup(dup->abbr_name); + else + evsel->abbr_name =3D evlist__new_abbr_name(); } } evlist->nr_br_cntr =3D i; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a733d3407b35..bf37442002aa 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -152,9 +152,13 @@ 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. */ int br_cntr_idx; int br_cntr_nr; + char *abbr_name; + /* * 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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 D9D88190056 for ; Wed, 3 Jul 2024 20:03:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037009; cv=none; b=iDduSsQJ+emTVJFFsKhl3KJzBjvbhgvEplnrBMYqzIgNcpWtCmVyQY7uleBWEo9da7PMQrXihD74a6ho84vEU18ZdBUv4rXWRtbWql/sMT3H7erf7n3eB/ZRMiGvmQTp6r91mkLiqmvyn547cwLBoRw472a22UeyMqDos+KFs0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037009; c=relaxed/simple; bh=u4wEPK5MG4CDgThx5PvOXlfcoarqmDMSbr8FVps8Jx8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PeRjIRXXc4MScK0M6xv7p3TbngZA4LoWRyj1TlDs3/tJbCSYwQTKwyLMr0cCmoZDHA6LBK+txTWdNkrurO8pGCcbleVSCSCUqVBmQfbY0yMFaRUXhSMFf6Gy5nDKXNWnhsCVdgOfl7x1w82C0J5TSBP51NH+f61pmPbRSceTpvs= 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=NtHVoJRD; arc=none smtp.client-ip=198.175.65.9 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="NtHVoJRD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037008; x=1751573008; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=u4wEPK5MG4CDgThx5PvOXlfcoarqmDMSbr8FVps8Jx8=; b=NtHVoJRDa/pTSZciqCkb+xnTAgA9C+cWS+6fIo3NT7y0/UqI0UfDEzWo h9SkmQmg9l+HNm16sSkX46fcSfJqx85hJJJ7ntHEgP9FeaoSBeXZ/B9l3 a/ZftugiobHpmU7drUXNFABQfisHfrrhDcOSBl4fmop4FRnF6HtCClgro W9Qo33HxGXclRA6R+ZKHaAskLoyMeG4ORwZQ/bnaPvDdmFLu+V/NAzwV0 OX1gCWSYotxvRKCS2pVMzagqRw3oxG0JPJJO/NIBakRNP1Y4FkTYN6D+b 1g69j+Wx82U8Rqq9WuO0SJtCNd8N77iWPecWOwn37sIQOfaEGGz7eOZ7I w==; X-CSE-ConnectionGUID: yOM0rOyFTSWTZP8VOXm86Q== X-CSE-MsgGUID: n/vh2TEAQXaaIIl1tHUQIA== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807602" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807602" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:27 -0700 X-CSE-ConnectionGUID: RMw/D04CRSC0jlAdcRMNzQ== X-CSE-MsgGUID: 0N6EAhcZSnuaO9wc21v97A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442593" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:26 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH 6/9] perf report: Display the branch counter histogram Date: Wed, 3 Jul 2024 13:03:53 -0700 Message-Id: <20240703200356.852727-7-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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. 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 | ... 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 | 101 +++++++++++++++++++++++ tools/perf/util/annotate.h | 3 + tools/perf/util/block-info.c | 66 +++++++++++++-- tools/perf/util/block-info.h | 8 +- 8 files changed, 202 insertions(+), 18 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Document= ation/perf-report.txt index d2b1593ef700..f35189d5ff1e 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 =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 2d9226b1de52..de24892dc7b8 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -705,7 +705,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) { @@ -728,7 +728,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 da8d13bbb500..a0f864f2e996 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; @@ -1121,18 +1128,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..73d766eac75b 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 6baa0671598e..f20f9e40ef0d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -40,6 +40,7 @@ #include "namespaces.h" #include "thread.h" #include "hashmap.h" +#include "strbuf.h" #include #include #include @@ -47,6 +48,7 @@ #include #include #include +#include =20 /* FIXME: For the HE_COLORSET */ #include "ui/browser.h" @@ -1706,6 +1708,105 @@ 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; +} + +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; + 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); + + 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; + } + for (j =3D 0; j < avg; j++, used++) { + if (strbuf_addstr(&sb, pos->abbr_name)) + goto err; + } + + if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG) { + if (strbuf_addch(&sb, '+')) + goto err; + used++; + } + pos =3D list_next_entry(pos, core.node); + } + + /* Assume the branch counter saturated at 3 */ + for (j =3D used; j < 4; j++) { + if (strbuf_addch(&sb, ' ')) + goto err; + } + } + + if (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 f39dd5d7b05e..2ff79a389dc0 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -548,4 +548,7 @@ struct annotated_basic_block { int annotate_get_basic_blocks(struct symbol *sym, s64 src, s64 dst, struct list_head *head); =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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 A1B7C191F69 for ; Wed, 3 Jul 2024 20:03:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037010; cv=none; b=HFTVHKpVFXNh0I2mE+hlCJpLMYPEZvLudI5G6H18EvYfjnd3W5bnyx4EyxkWAtObOQCSlIKInQNb6JtkHDzCxTcTymVjqWDOtoAAEFVA+qCZUMNn7jkXZ8VKgjRGpHEXtkPcEa4snwcj5ge7HLAQitNrY5N5/3Li2bQXgjfU21U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037010; c=relaxed/simple; bh=35d0AnDBxA+mMCwEFzE0w/OcjIGDMUFiqT3maRRcqZk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=WwgigPEKyUo4j+3m+LoqLSM4KJH42LNjGAAu/3NX1R/sKGKkMsolJxpdZymkCSFlfJL2zUtciGTneHZgC3aZuhbTyw4M8EVsFBeA6Z2qBoOhjIXnNcV9hD6fBeDiyC9P+mOtIvRkV88tKrJyr3eb0ltLApFjj53R1+wfQnp7dWw= 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=bvM0IV9C; arc=none smtp.client-ip=198.175.65.9 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="bvM0IV9C" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037009; x=1751573009; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=35d0AnDBxA+mMCwEFzE0w/OcjIGDMUFiqT3maRRcqZk=; b=bvM0IV9Co1/aMPd+SFFdAA9aTE2+N1Zm6q3SqsOM2ive1fT8bB5q4Lr4 bU78C55LOYvqfW9GoIzZLIbrVouDulRh78EbKtZc3Q0Bcj094yjBSEp3L 0m/5ve4n5MFjBRJ0hHi7yEAKHNjpazPIc8qT/3nncDMat0IOBo+Q5T0Mt VJMN1GD09tB4upLybQaZ/ehjh95goUTiMTZCcXHEEGZZ9JU62oLqkrJdx yMjKQPSwC36a9NGYrf2Ke1UC+RQNZdQnCGyDKx4Tv23iOqDNheI4QJMTQ qXU1geYRaotXyKKarV1BR8rWreXF+U/QoppNBvYWEolgDE4eYRv232m1X w==; X-CSE-ConnectionGUID: Id8Ng3+kSciawtIMyH3HlA== X-CSE-MsgGUID: yoPeuB5ISYKdgGsco+FlKA== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807610" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807610" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:28 -0700 X-CSE-ConnectionGUID: 9emNEXXqQs+dnzCNvUwvdQ== X-CSE-MsgGUID: 37i5iBW5TluqjnQX7/1vpw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442599" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:26 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang , Tinghao Zhang Subject: [PATCH 7/9] perf annotate: Display the branch counter histogram Date: Wed, 3 Jul 2024 13:03:54 -0700 Message-Id: <20240703200356.852727-8-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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 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 0aa40588425c..57c9c863dce9 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -917,11 +917,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 ea986430241e..868ea84d766b 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 73d766eac75b..6dc765e37788 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 f20f9e40ef0d..8a7024534469 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -500,8 +500,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 @@ -536,6 +538,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 @@ -547,8 +563,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); + } } } } @@ -1903,6 +1921,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); @@ -2002,7 +2036,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 2ff79a389dc0..5cda399ae52e 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; @@ -350,6 +356,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 72aec8f61b94..3663938ca234 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -857,6 +857,7 @@ static void annotation_line__exit(struct annotation_lin= e *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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 C8F6E191F70 for ; Wed, 3 Jul 2024 20:03:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037010; cv=none; b=JrDc2eipbvh/zHIwZbisajKfcvfQHesRlETdUPrfbuC9UDgrCBuvAgSUagc9Ir16PVSy2qa2Wu7h/x9SmSg/YIGYpceFLOKn4ihcTYD3eGAxd8yWyGfreiu+OPgZuU+Q6v2afaD7wfEJSPJLWTjS/rcex+E4xKy/UtP9tLLNyv0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037010; c=relaxed/simple; bh=nGX4/1SsuB3debswjhQV3ylWUPdQhVBu9G3/DW/tklQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Tqtzh7xLfFGCA3tHY5XG+YH//AgJEwDvocUHBZ1XU5BAredNvelMnJ+KbX65eMW/cC/N44u8f/5hoKv+YkL2EEgB8zS/NH6hm5ExP8Qs74Knx636capYUkwje7Qg3giznq9g6fKPPX54lCVcLwUL4Z2Qsgz/J2n5lLWPA+pMzGI= 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=Q90SYXv2; arc=none smtp.client-ip=198.175.65.9 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="Q90SYXv2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037009; x=1751573009; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nGX4/1SsuB3debswjhQV3ylWUPdQhVBu9G3/DW/tklQ=; b=Q90SYXv2L4q+kRN/OsPXhUfVOGmpCNalOkJl7a1jXzZOjhwwFshjNmI3 YuyQ21zJNbC6D3A9RzXC7z8+JHr6soZPL4YUdpWy1USoH4x5q022J/V4X tt6rA2CMMTDggYawEsdKngYIOb/HwwVnFT/llTjvwIyqBYZC5UneAT8Ch TRHidT3WLQZQMEpcbBdAl4GNq2w9FvIg1x1sr3Zw3yH5Fky+2qleWak97 acMCsv4/K9s23jPd67R46ZEQ9W17gZhm7eBgl8z4WS1TLkV9OB09PElCZ 1RbWTNbF3Aaabm35Fqb2HKOh7+T7LaH+3s2qqC21SbjBsiVcgN6WVCNgH A==; X-CSE-ConnectionGUID: PBRFSYOVRgazbjitMsma+A== X-CSE-MsgGUID: EPZRdJRNQ6W80qHt3IUs8Q== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807619" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807619" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:28 -0700 X-CSE-ConnectionGUID: +MLEejHQQsC5mCGlV87+BQ== X-CSE-MsgGUID: q5dyxyP0QuyopAhegorumg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442611" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:27 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang , Tinghao Zhang Subject: [PATCH 8/9] perf script: Add branch counters Date: Wed, 3 Jul 2024 13:03:55 -0700 Message-Id: <20240703200356.852727-9-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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 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 ff086ef05a0c..be483c904d8d 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 c16224b1fef3..4d71847196bc 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); @@ -3979,7 +4033,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 23:23:21 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.9]) (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 0E0C019412A for ; Wed, 3 Jul 2024 20:03:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037011; cv=none; b=R/JYzwD3SxUwabaDtBrMVs2zt/D7VQ/ftc+aG+6HkeyK4zdnmfBAy+JVlXBz4ATFSLdu3fCsmofzfth/AUSCViscTfId6XalGWG0zWmlJM9tR7N1Q1LvBDlIZXORbqpVcO3r8z4Auq/rPZ/nwscx0XM7HTDKctFfCCCTEQvWQsg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720037011; c=relaxed/simple; bh=eRSy0qosXqU6Hszy6JkiW6BncOZYM9c0YyE7hCnYkgM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=s7Cu6Gb6S5no6sEd7uBd3vraGuK56dsf2gx1JthGCwsjlvshxwA4BQq7lhq3Nf/eMGtixR/VLGakd/vcvhc7Wi7Av/1PAkbS5bnNBUg0HRn2NFwSlQEz68Dz/hAEYhB/EECfxPdpzspv+k7kisJfFrkxN0mjOhkggRaj7+NCqwU= 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=IlkwOoVo; arc=none smtp.client-ip=198.175.65.9 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="IlkwOoVo" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720037010; x=1751573010; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eRSy0qosXqU6Hszy6JkiW6BncOZYM9c0YyE7hCnYkgM=; b=IlkwOoVowcbw7vH5Sr9KncvpQF/AG50DkNmgdawzf4bHh9REVlAfwRYV uHej9ijd+/Y56ZM/h1mhqQBMVfbm65xaFl+q8ywuNtWPExJ+Ei5neA6pe f1KYk0RhTApEDeG5AZKTnEJNXazO8Svg9RuVsKJ4UwxNN5gw+RcZA5dGP zFqVJ9tqYAeZjS/UiFTtb5KZD0vu90BdNbb3RSw+xJfL0P8s02Jhl4V/Y QacoAzeYvJrgdpJe3r0NSCjK0++eyraZGEcoWJky4ojazPst3cfMOq9Zr DiWQ5n6DbKCLj0f23Z5wGUJaQ8sW1GqSU6NW62ea8VygCJHaeZWRR0dwo Q==; X-CSE-ConnectionGUID: im7fI0/nTvmqNS7Dx7cWow== X-CSE-MsgGUID: SLv3lBlRQtOy75ez/jU4uA== X-IronPort-AV: E=McAfee;i="6700,10204,11122"; a="39807626" X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="39807626" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jul 2024 13:03:29 -0700 X-CSE-ConnectionGUID: SN1ao3b9Sp+D4mhQnnaw3Q== X-CSE-MsgGUID: fm4DWIJJTG+of/o+lV4OAw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,182,1716274800"; d="scan'208";a="46442622" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 03 Jul 2024 13:03:28 -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 Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH 9/9] perf test: Add new test cases for the branch counter feature Date: Wed, 3 Jul 2024 13:03:56 -0700 Message-Id: <20240703200356.852727-10-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240703200356.852727-1-kan.liang@linux.intel.com> References: <20240703200356.852727-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) 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