From nobody Sat Feb 7 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 49E28433AD; Thu, 8 Aug 2024 19:32:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145573; cv=none; b=Pw4a7wC9lYbfaRhW5BL+AI79g7oIwnZpyXyWppyRvNn7hTsWJGGezxjAMawIe5UB9X4jCjVwKeS/YAUBpgkNO5zYzUUmTe6oTDIu529UYmDm5YNgJRsUDFsOKXpB1ToJ1BRPhRt/PTpojHyB7o5R8ei2BcLuRZKzdqVIN8vRIXc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145573; c=relaxed/simple; bh=M8Vdlx5v0f5GYQrlo4Op0nn8DVxOwbbRblzNGEktKEI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TyLVhCCgiBawtH6n1jb0Pty+0TSV0XF7NJ/59hU28RK7U5+2bN+OsUDyRljro/KcjyozFW6CbAQ+nZgmgXeIp19q7BEQnXX64bgoZQ1jvUjDNblcW93/lchjeKHw0sUZRCzoaDPsJu4G8pX9MYOVx0yxYkHs3sWA10PWRegTQVw= 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=R6aCJgv1; arc=none smtp.client-ip=198.175.65.14 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="R6aCJgv1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145571; x=1754681571; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=M8Vdlx5v0f5GYQrlo4Op0nn8DVxOwbbRblzNGEktKEI=; b=R6aCJgv1KnPZH5d3X/DZGR2svFqd0ZQdiOuByJAhSt4ORrIef1hHU0sS F/qlZySEEfebR6O5x3SC1iBy733iEsizUfTAbcoh78ByBp9ucSiUxOp8m IeNaX31xKTEGI86wGwiF/o4nnrXKXwaxcYrC7prb6LX1R8aHcoIIFmvfV Q+64vGF2QZ7/ARn+sHl9HnR2kx7mEz1b2RUHaiXcBsZ0YIgo9AdodYHbs mOdoLTehO93VSI64Qgj65qLLwdz04yDHoNLCuHXv6C2Nn3Ir/XKl8W7Lf ZYNYDKW8nErSwcmgecqXB9UEvqd3G0FRnKSJo5JG0RiB22w9retCwjLhW w==; X-CSE-ConnectionGUID: jflJORPWR6urotAVy1hO8g== X-CSE-MsgGUID: KUYr0sgJSeKn4Pmw2whKLA== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091691" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091691" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:51 -0700 X-CSE-ConnectionGUID: C5hUPoGETKeTrk2+DrZrLw== X-CSE-MsgGUID: jjja2Mt/QOqwnkbycOdGzA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402577" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:50 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V2 1/9] perf report: Fix --total-cycles --stdio output error Date: Thu, 8 Aug 2024 12:33:16 -0700 Message-Id: <20240808193324.2027665-2-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang The --total-cycles may output wrong information with the --stdio. For example, perf record -e "{cycles,instructions}",cache-misses -b sleep 1 perf report --total-cycles --stdio The total cycles output of {cycles,instructions} and cache-misses are almost the same. # Samples: 938 of events 'anon group { cycles, instructions }' # Event count (approx.): 938 # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles # ............... .............. ........... .......... ..................................................> # 11.19% 2.6K 0.10% 21 [perf_iterate_ctx+48 -> > 5.79% 1.4K 0.45% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_> 5.11% 1.2K 0.33% 71 [native_write_msr+0 ->> # Samples: 293 of event 'cache-misses' # Event count (approx.): 293 # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles [> # ............... .............. ........... .......... ..................................................> # 11.19% 2.6K 0.13% 21 [perf_iterate_ctx+48 -> > 5.79% 1.4K 0.59% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_> 5.11% 1.2K 0.43% 71 [native_write_msr+0 ->> With the symbol_conf.event_group, the perf report should only report the block information of the leader event in a group. However, the current implementation retrieves the next event's block information, rather than the next group leader's block information. Make sure the index is updated even if the event is skipped. With the patch, # Samples: 293 of event 'cache-misses' # Event count (approx.): 293 # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles [> # ............... .............. ........... .......... ..................................................> # 37.98% 9.0K 4.05% 299 [perf_event_addr_filters_exec+0 -> perf_event_a> 11.19% 2.6K 0.28% 21 [perf_iterate_ctx+48 -> > 5.79% 1.4K 1.32% 97 [__intel_pmu_enable_all.constprop.0+80 -> __intel_> Fixes: 6f7164fa231a ("perf report: Sort by sampled cycles percent per block= for stdio") Acked-by: Namhyung Kim Signed-off-by: Kan Liang Reviewed-by: Andi Kleen --- 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 930052961c1a..312396b52468 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 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 6886F13E032; Thu, 8 Aug 2024 19:32:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145574; cv=none; b=Oo2q6DSEbwR9PZ1AxevpTsHUkHq7YfP4jW0ThScpIujvsBxBj1/fHH+seSyOFB0EXgC8WJZ4zCB5E4Kh1wOSzOBlqE5pfGmXE5XwN78fr9VUnb3mCyOnGAxAKjIlKb6Pv+zGFJFljTnnqEAHWkEdhVUhhIxGnQYhKA7dQm98hYI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145574; c=relaxed/simple; bh=7pLKnvHMK8oM3IFZf3l13sipR+dirpfsjlql8/Wn4yY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WO12u6abuBHRwEoyIcKVf8juihKI1/Pse3lj/kbNY9AS4s+79IXQWn4eA9R//VJ3CxG42joQ5pM8RHU9845Zdnm9Bo14FaoRk452Ppyj8aZtDK/tTAPzJ5YZXZTZKjMZnGlD/ffBslpekXXHTZoY3u916a8jp+wjFF4r+RkcS6k= 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=mTGfAEkK; arc=none smtp.client-ip=198.175.65.14 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="mTGfAEkK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145574; x=1754681574; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7pLKnvHMK8oM3IFZf3l13sipR+dirpfsjlql8/Wn4yY=; b=mTGfAEkKfLvfN5O+39Vu2iRXqFaw6s7bXwQOSfMobzN278vOZId+bRfJ eRLTYVMeOAkzKXYu64H7HKYIyzerqrs/aJpELWFYxvaNZekzYMAk39tZa uLS+xOpWWe6qlkhdpxdN0yPp8FZSoPFsN54s0eAv779n67ssL9rE6Ffj/ WkyBHea6gJjH2QglREq34xkO+6MJrimSqvzCzAqLriwQW8R+UDs1Lhf5/ vnlFpvRnSb4qzmPlk+W9WSoRrpq2Gyn2hqUoR3l7kpLWXtuGiuVim/AgR 6h95azCa9UD3HKrXBBf2o75WIhqmfcnkHXYWn8WG5nSTwkgcp+6zPDljT Q==; X-CSE-ConnectionGUID: 2AVDn2nCR8m0d1zRkqd9uA== X-CSE-MsgGUID: MQwiHj5NQgarAptoiWNdSA== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091695" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091695" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:51 -0700 X-CSE-ConnectionGUID: 0P5NfmMhQOy42S/V4Ee93w== X-CSE-MsgGUID: 92jxCo34S6e1OcKVzLO5NQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402581" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:51 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V2 2/9] perf report: Remove the first overflow check for branch counters Date: Thu, 8 Aug 2024 12:33:17 -0700 Message-Id: <20240808193324.2027665-3-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang A false overflow warning is triggered if a sample doesn't have any LBRs recorded and the branch counters feature is enabled. The current code does OVERFLOW_CHECK_u64() at the very beginning when reading the information of branch counters. It assumes that there is at least one LBR in the PEBS record. But it is a valid case that 0 LBR is recorded especially in a high context switch. Remove the OVERFLOW_CHECK_u64(). The later OVERFLOW_CHECK() should be good enough to check the overflow when reading the information of the branch counters. Fixes: 9fbb4b02302b ("perf tools: Add branch counter knob") Acked-by: Namhyung Kim Signed-off-by: Kan Liang Reviewed-by: Andi Kleen --- tools/perf/util/evsel.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d607056b73c9..f22f402d54cc 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2884,8 +2884,6 @@ int evsel__parse_sample(struct evsel *evsel, union pe= rf_event *event, array =3D (void *)array + sz; =20 if (evsel__has_branch_counters(evsel)) { - OVERFLOW_CHECK_u64(array); - data->branch_stack_cntr =3D (u64 *)array; sz =3D data->branch_stack->nr * sizeof(u64); =20 --=20 2.38.1 From nobody Sat Feb 7 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 7473C147C86; Thu, 8 Aug 2024 19:32:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145576; cv=none; b=tWN4tv9nfon6uuxhbBE38yaM/sAzqDHTmOho13LezXTFywhCgRx9W3Rc8x41jt8pIwbvwGdIcgs9MmsLuY1OQ0WcCkGznHSPu2wVsLptdeRUClhwEklbL+JenmFp14JjXa+xA3xWumhtPhEfLPVeBKxfeLabLZ4NHVcTBeiR3g4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145576; c=relaxed/simple; bh=PUCAnV1am/H9H6knp3RxChEqhaqrs51NcPpmZipRtQM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=f/dZx1hMkMt93CPG7D3oA+6P6Y4YX9fcwJZtc3nuSRGwUdiC20I+4t2yJhKrZzAo7Xs0vewtL/bbWrtVqTS9XyHeylyRIc7ZUVNETwsZATZlYIQcvHKtv9xAY0LGg3Sr+SM/ZFPoJJNG4Q9El6cRlyxiGkt8ToAlPyLHJ9KbQr4= 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=QznDpzHL; arc=none smtp.client-ip=198.175.65.14 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="QznDpzHL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145574; x=1754681574; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PUCAnV1am/H9H6knp3RxChEqhaqrs51NcPpmZipRtQM=; b=QznDpzHLOLNwKaNPZjtI9ZncwBs46JnRDRG68bu7W6xlin2QktPa6dRe q4yoFF7rGKKxJ1BZYdmUJTy+oJZsMlcxYLlAavoMt66U9uFpVZE/JCgAa 7903/m/49FcBpGbONF++I5fE6NJO6KdHy1b7fYd+PILUPvQxH4xzdyZhc H82s/wQKMPQyco5X8yhG2V4i0kwYCwRGVp5R5Vg1L0XkRi8vf2swdz4H3 M/aOgqM3fHg25d2nMCzh1IrBkhnGDX1uWOBeTdxy7gRFaJjRM705u1geY /QMUS8qR6gE1MfBhCwD3cV6bLxxpkvksVjEdeXmFlAFfp96HUEQo66B3C w==; X-CSE-ConnectionGUID: hi8+2ghcRw6PiSAfYNvclA== X-CSE-MsgGUID: Lbg83UGnRdmrMNBMaikVGg== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091700" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091700" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:51 -0700 X-CSE-ConnectionGUID: UH/jKZwRT0CMbNcDrV2whg== X-CSE-MsgGUID: bkGNTlvTQwi3PBcgvBpJKg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402584" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:51 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V2 3/9] perf evlist: Save branch counters information Date: Thu, 8 Aug 2024 12:33:18 -0700 Message-Id: <20240808193324.2027665-4-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-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 Acked-by: Namhyung Kim Reviewed-by: Andi Kleen --- tools/perf/util/evlist.c | 15 +++++++++++++++ tools/perf/util/evlist.h | 2 ++ tools/perf/util/evsel.c | 13 +++++++------ tools/perf/util/evsel.h | 8 ++++++++ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4b2538e4f679..68bbd3ea771b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -79,6 +79,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_= map *cpus, evlist->ctl_fd.fd =3D -1; evlist->ctl_fd.ack =3D -1; evlist->ctl_fd.pos =3D -1; + evlist->nr_br_cntr =3D -1; } =20 struct evlist *evlist__new(void) @@ -1264,6 +1265,20 @@ u64 evlist__combined_branch_type(struct evlist *evli= st) return branch_type; } =20 +void evlist__update_br_cntr(struct evlist *evlist) +{ + struct evsel *evsel; + int i =3D 0; + + evlist__for_each_entry(evlist, evsel) { + if (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) { + evsel->br_cntr_idx =3D i++; + evsel__leader(evsel)->br_cntr_nr++; + } + } + evlist->nr_br_cntr =3D i; +} + bool evlist__valid_read_format(struct evlist *evlist) { struct evsel *first =3D evlist__first(evlist), *pos =3D first; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index cccc34da5a02..b46f1a320783 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -57,6 +57,7 @@ struct evlist { bool enabled; int id_pos; int is_pos; + int nr_br_cntr; u64 combined_sample_type; enum bkw_mmap_state bkw_mmap_state; struct { @@ -219,6 +220,7 @@ int evlist__apply_filters(struct evlist *evlist, struct= evsel **err_evsel, u64 __evlist__combined_sample_type(struct evlist *evlist); u64 evlist__combined_sample_type(struct evlist *evlist); u64 evlist__combined_branch_type(struct evlist *evlist); +void evlist__update_br_cntr(struct evlist *evlist); bool evlist__sample_id_all(struct evlist *evlist); u16 evlist__id_hdr_size(struct evlist *evlist); =20 diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f22f402d54cc..38a74d6dde49 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2636,17 +2636,18 @@ u64 evsel__bitfield_swap_branch_flags(u64 value) =20 static inline bool evsel__has_branch_counters(const struct evsel *evsel) { - struct evsel *cur, *leader =3D evsel__leader(evsel); + struct evsel *leader =3D evsel__leader(evsel); =20 /* The branch counters feature only supports group */ if (!leader || !evsel->evlist) return false; =20 - evlist__for_each_entry(evsel->evlist, cur) { - if ((leader =3D=3D evsel__leader(cur)) && - (cur->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) - return true; - } + if (evsel->evlist->nr_br_cntr < 0) + evlist__update_br_cntr(evsel->evlist); + + if (leader->br_cntr_nr > 0) + return true; + return false; } =20 diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a5da4b03bb1c..a393dae1dc96 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -148,6 +148,14 @@ struct evsel { */ __u64 synth_sample_type; =20 + /* + * Store the branch counter related information. + * br_cntr_idx: The idx of the branch counter event in the evlist + * br_cntr_nr: The number of the branch counter event in the group + * (Only available for the leader event) + */ + int br_cntr_idx; + int br_cntr_nr; /* * bpf_counter_ops serves two use cases: * 1. perf-stat -b counting events used byBPF programs --=20 2.38.1 From nobody Sat Feb 7 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 5EC6E155725; Thu, 8 Aug 2024 19:32:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145576; cv=none; b=jQQqoBkjHMbuD9IYTn3AH0DsZQc6KSBo/hYAb4YHchGu4+Mjtkz9w2sO58hMs+3VldiQIr5V1X+ABC7p6BgStvJQp1SKdW9YpATPlUwmCK9m9CDBIaQIC1zPZu7s1ddviEb4TmiGXEZb3HdwEOo97MT1QhUG+on8ymUssOW1om0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145576; c=relaxed/simple; bh=wFgPVmGBl+D67JH6N4EmnmCKG/Yqj3j8D0luZV4BR20=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tAgcoZ4mXIWn2BZxePbvSFvTrfe3Rd0EHJfp4NFOZo44cgFS7QSSdnF//U3jD5pXeeuUyXqCJR+k17QiMIesni0/peUTMYNLWXauQRsMd97d28VPmJ/j1UP8aEo1OHX9WrATrKQp1CeeR/raWGdk8LDg3DFHreWO510LZKW1d3I= 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=dE7Css87; arc=none smtp.client-ip=198.175.65.14 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="dE7Css87" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145575; x=1754681575; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wFgPVmGBl+D67JH6N4EmnmCKG/Yqj3j8D0luZV4BR20=; b=dE7Css87pqKp/xjUuZ0F1NtH4kWINRjUMbvppLc4KGs14rfhJrSzVHSt NSxGsS4M4v7bgjeB1rv3IYVbihABG6b3h7p9RTtWXaBmIkxKOSOkbT30X 8x8VdTccUJ/nYCVJ7w0a9x3OlH/rh49eJGSaFmsQelXmpCgwa6Y5N7Qdt hX8VBEEOnync8dKC2e5jzWQC7/rNkp3Jr/r1eBUjN0f2lEJ2aSZh7S9ii o3jIzPLhSOWUPl26LRNSsMJrMAUQnD76cHXEUOY2CRrKvoKA6oFXPmR/f gezs4wU8HrahgAX/SOqeIiqmr+NU5J0M7Q387rKTjdfxA7SM4D+49GtZR g==; X-CSE-ConnectionGUID: c54wtKxnS5Ge/tQi4pkiaQ== X-CSE-MsgGUID: qm53MhUQSjaKoYdYhq+Feg== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091705" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091705" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:52 -0700 X-CSE-ConnectionGUID: aod8bZIDTF2KftH+zEyn+A== X-CSE-MsgGUID: lggByeuxTcGu8SUVZPmTlg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402589" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:51 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V2 4/9] perf annotate: Save branch counters for each block Date: Thu, 8 Aug 2024 12:33:19 -0700 Message-Id: <20240808193324.2027665-5-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-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 Acked-by: Namhyung Kim Reviewed-by: Andi Kleen --- 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 efcadb7620b8..dbe94441e4e9 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 312396b52468..13b41c5f99ed 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 d1a06a88d693..76a44321b9cb 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 eafe8d65052e..f3d8e703f81b 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 64e70d716ff1..76ccb0e721c7 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -14,6 +14,7 @@ #include "spark.h" #include "hashmap.h" #include "disasm.h" +#include "branch.h" =20 struct hist_browser_timer; struct hist_entry; @@ -288,6 +289,9 @@ struct annotated_source { struct annotation_line *annotated_source__get_line(struct annotated_source= *src, s64 offset); =20 +/* A branch counter once saturated */ +#define ANNOTATION__BR_CNTR_SATURATED_FLAG (1ULL << 63) + /** * struct annotated_branch - basic block and IPC information for a symbol. * @@ -297,6 +301,7 @@ struct annotation_line *annotated_source__get_line(stru= ct annotated_source *src, * @cover_insn: Number of distinct, actually executed instructions. * @cycles_hist: Array of cyc_hist for each instruction. * @max_coverage: Maximum number of covered basic block (used for block-ra= nge). + * @br_cntr: Array of the occurrences of events (branch counters) during a= block. * * This struct is used by two different codes when the sample has branch s= tack * and cycles information. annotation__compute_ipc() calculates average I= PC @@ -313,6 +318,7 @@ struct annotated_branch { unsigned int cover_insn; struct cyc_hist *cycles_hist; u64 max_coverage; + u64 *br_cntr; }; =20 struct LOCKABLE annotation { @@ -383,7 +389,9 @@ struct annotated_branch *annotation__get_branch(struct = annotation *notes); =20 int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, struct addr_map_symbol *start, - unsigned cycles); + unsigned cycles, + struct evsel *evsel, + u64 br_cntr); =20 int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample= *sample, struct evsel *evsel, u64 addr); diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h index 87704d713ff6..b80c12c74bbb 100644 --- a/tools/perf/util/branch.h +++ b/tools/perf/util/branch.h @@ -34,6 +34,7 @@ struct branch_info { struct addr_map_symbol from; struct addr_map_symbol to; struct branch_flags flags; + u64 branch_stack_cntr; char *srcline_from; char *srcline_to; }; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f8ee1cd6929d..0121ea72a2ba 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 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 0C74E156863; Thu, 8 Aug 2024 19:32:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145576; cv=none; b=BLcZbnA3/bM0NF9Nksb1WKqF6rE9cvm2lSS/dGGcu3aTmvnKCgx7q1c8GjQV2vyCdR7F1UxGJJJ8srStDd+zbsEsD9aWBnn8MInVSfBrkHVIy6ce16XU/VOBtbiYsDVmJakYfYUyYjkkpoJAdtbqedGsg1HwMZt+x8g7DOXixw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145576; c=relaxed/simple; bh=INmGvse47m1TyhqqOxl4EU0UajeILdDJuF9VfmuIi70=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=S+H9q3maTOWTTMr68n89k0aF11uIfFwyREF4jIQY8JhQko2vSCHzepY6OHKMvLkBWza0nDvsMZpNYu1qiNc33Hi9dtrMARJb5LPfCZaD7Fx5VvZOkp/w18KybqS1C4a3xEY19Oks+6AtDOLyy3tk7uIITC8YgiswiSM8xeJh4gk= 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=kFFM0TiN; arc=none smtp.client-ip=198.175.65.14 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="kFFM0TiN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145575; x=1754681575; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=INmGvse47m1TyhqqOxl4EU0UajeILdDJuF9VfmuIi70=; b=kFFM0TiN/Mc5/RGzqAOf8zFU2pbgKh3TLKQ62m78WGDS0ebfpv2MBuOD +6JwkM+6AFikRGJctseq1HYoPzIwlyCRZQOyb8q7Z+u+pYdHdPufggiXR Nd9yyfr6/OLDpq/7nTUO/hI5Gs8utjSY5GhQwq3y8Pv4fU+YtAGiW4QE+ NKQGV8iP5u3Fdd36T76MKD4WzITtIbGpii3wR7+NTytAZHK5xWrycePjn j+MNk8aYPMRgAXWWHZQmhQ+7Ilcs1qrGaxap7SlCGBcuFp8mO97HRq8G6 p8GmsbBKQTwTgcqtkVzYpNYvf3uXom0qbeYSx14pPELVBYuzsp4WPXBnr g==; X-CSE-ConnectionGUID: dxKGErKQTfyjyfdno1EXyA== X-CSE-MsgGUID: VlIntO9lS8qon9T2+fEVFA== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091711" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091711" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:52 -0700 X-CSE-ConnectionGUID: dfRly6t1RZieXLB738TbLg== X-CSE-MsgGUID: 24ONvpEbSi+IoyvkbY2cjw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402593" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:52 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V2 5/9] perf evsel: Assign abbr name for the branch counter events Date: Thu, 8 Aug 2024 12:33:20 -0700 Message-Id: <20240808193324.2027665-6-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-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 Acked-by: Namhyung Kim Reviewed-by: Andi Kleen --- tools/perf/util/evlist.c | 55 +++++++++++++++++++++++++++++++++++++++- tools/perf/util/evsel.h | 6 +++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 68bbd3ea771b..c0379fa1ccfe 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -33,6 +33,7 @@ #include "util/bpf-filter.h" #include "util/stat.h" #include "util/util.h" +#include "util/env.h" #include "util/intel-tpebs.h" #include #include @@ -1265,15 +1266,67 @@ u64 evlist__combined_branch_type(struct evlist *evl= ist) return branch_type; } =20 +static struct evsel * +evlist__find_dup_event_from_prev(struct evlist *evlist, struct evsel *even= t) +{ + struct evsel *pos; + + evlist__for_each_entry(evlist, pos) { + if (event =3D=3D pos) + break; + if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) && + !strcmp(pos->name, event->name)) + return pos; + } + return NULL; +} + +#define MAX_NR_ABBR_NAME (26 * 11) + +/* + * The abbr name is from A to Z9. If the number of event + * which requires the branch counter > MAX_NR_ABBR_NAME, + * return NA. + */ +static void evlist__new_abbr_name(char *name) +{ + static int idx; + int i =3D idx / 26; + + if (idx >=3D MAX_NR_ABBR_NAME) { + name[0] =3D 'N'; + name[1] =3D 'A'; + name[2] =3D '\0'; + return; + } + + name[0] =3D 'A' + (idx % 26); + + if (!i) + name[1] =3D '\0'; + else { + name[1] =3D '0' + i - 1; + name[2] =3D '\0'; + } + + idx++; +} + void evlist__update_br_cntr(struct evlist *evlist) { - struct evsel *evsel; + struct evsel *evsel, *dup; int i =3D 0; =20 evlist__for_each_entry(evlist, evsel) { if (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) { evsel->br_cntr_idx =3D i++; evsel__leader(evsel)->br_cntr_nr++; + + dup =3D evlist__find_dup_event_from_prev(evlist, evsel); + if (dup) + memcpy(evsel->abbr_name, dup->abbr_name, 3 * sizeof(char)); + else + evlist__new_abbr_name(evsel->abbr_name); } } evlist->nr_br_cntr =3D i; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a393dae1dc96..4316992f6a69 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -153,9 +153,15 @@ struct evsel { * br_cntr_idx: The idx of the branch counter event in the evlist * br_cntr_nr: The number of the branch counter event in the group * (Only available for the leader event) + * abbr_name: The abbreviation name assigned to an event which is + * logged by the branch counter. + * The abbr name is from A to Z9. NA is applied if out + * of the range. */ int br_cntr_idx; int br_cntr_nr; + char abbr_name[3]; + /* * bpf_counter_ops serves two use cases: * 1. perf-stat -b counting events used byBPF programs --=20 2.38.1 From nobody Sat Feb 7 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 18599158D7F; Thu, 8 Aug 2024 19:32:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145578; cv=none; b=uZ1Id0UMuYrdeNCPKAWF9sQXcQt4lByBq7uefXHeM+E+jDPmWmHTYTwF7fJRaQXgbWVVr2GsxP+RYNx4QjU8Fe8d+zwOZrhC//2duF5u1WNmq4mkcMQJtJ1Nop6PRZJTgNj127ZyBz6G3C9Tu5aK1HVBnWd5aYKiUCufn2D6w7A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145578; c=relaxed/simple; bh=uGTVDkdrvwFlvuGrqN9edS0YP1xklyILPlHsg95cnas=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=n8kG9AJ7qGBOiTs3a1MHGnOSr+1+A15bBUFu8M4ydkuxeyzx99VkKCO+1pDpwDM4VaeMgxNw64mdUGML7iMU4jxgUhtJGIIlQJyqp1mofeSdAlE6uYD+O+TXzfosjjc6kk4tuiTxbC/LGDf9A5//22T5Rsvq7P6RYORJF7vK/7A= 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=EbTgIsgm; arc=none smtp.client-ip=198.175.65.14 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="EbTgIsgm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145576; x=1754681576; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uGTVDkdrvwFlvuGrqN9edS0YP1xklyILPlHsg95cnas=; b=EbTgIsgm/k+tEfPK+lXgeQ+NUFPnC3N0OXoa7yHeNxFuqh9PsHOMO6dC WTpGrsjf/tWykoFcx0Rk4n2eSuE3TtkEMUFl/PmaIDRgNT6xt7h2+OL8a 12AmqgDk7GPlzm7dewCNsI1uFTC1BQ9+2aWqTUVS/lhQPTw8fBm19DLVq dBQj3hjdNT1bflBZ7lkNXYvPToNxPGpN+7QKbMOWMX4gclSyHZ6zWfNOP CCXRQMNbTp2uyH9XvxoZmrZWiNLWz3cKJXIoCLkCm1toAIJsIJXsQ/Or8 lix8QDQAb2N/O/E+2KiaBUdQMsy45UPWdTtocrsFR6Z2HztRfUN5aZcmd A==; X-CSE-ConnectionGUID: OqLu8GYsTcG6tLd6qVEMxQ== X-CSE-MsgGUID: GXbBJdevQVqMxzj7KeSB8w== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091715" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091715" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:52 -0700 X-CSE-ConnectionGUID: O6aUIHl0T6OHKF6fRSy74A== X-CSE-MsgGUID: KTUb5YJHTNyHaeBaceLwCQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402597" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:52 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V2 6/9] perf report: Display the branch counter histogram Date: Thu, 8 Aug 2024 12:33:21 -0700 Message-Id: <20240808193324.2027665-7-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-1-kan.liang@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kan Liang Reusing the existing --total-cycles option to display the branch counters. Add a new PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER to display the logged branch counter events. They are shown right after all the cycle-related annotations. Extend the struct block_info to store and pass the branch counter related information. The annotation_br_cntr_entry() is to print the histogram of each branch counter event. If the number of logged events is less than 4, the exact number of the abbr name is printed. Otherwise, using '+' to stands for more than 3 events. Assume the number of logged events is less than 4. The annotation_br_cntr_abbr_list() prints the branch counter's abbreviation list. Press 'B' to display the list in the TUI mode. $perf record -e "{branch-instructions:ppp,branch-misses}:S" -j any,counter $perf report --total-cycles --stdio # To display the perf.data header info, please use --header/--header-only = options. # # # Total Lost Samples: 0 # # Samples: 1M of events 'anon group { branch-instructions:ppp, branch-miss= es }' # Event count (approx.): 1610046 # # Branch counter abbr list: # branch-instructions:ppp =3D A # branch-misses =3D B # '-' No event occurs # '+' Event occurrences may be lost due to branch counter saturated # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles Branch= Counter [Program Block Range] # ............... .............. ........... .......... ..............= ........ .................. # 57.55% 2.5M 0.00% 3 |A = |- | ... 25.27% 1.1M 0.00% 2 |AA = |- | ... 15.61% 667.2K 0.00% 1 |A = |- | ... 0.16% 6.9K 0.81% 575 |A = |- | ... 0.16% 6.8K 1.38% 977 |AA = |- | ... 0.16% 6.8K 0.04% 28 |AA = |B | ... 0.15% 6.6K 1.33% 946 |A = |- | ... 0.11% 4.5K 0.06% 46 |AAA= +|- | ... 0.10% 4.4K 0.88% 624 |A = |- | ... 0.09% 3.7K 0.74% 524 |AAA= +|B | ... With -v applied, # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles Branch= Counter [Program Block Range] # ............... .............. ........... .......... ..............= ........ .................. # 57.55% 2.5M 0.00% 3 A= =3D1 ,B=3D- ... 25.27% 1.1M 0.00% 2 A= =3D2 ,B=3D- ... 15.61% 667.2K 0.00% 1 A= =3D1 ,B=3D- ... 0.16% 6.9K 0.81% 575 A= =3D1 ,B=3D- ... 0.16% 6.8K 1.38% 977 A= =3D2 ,B=3D- ... 0.16% 6.8K 0.04% 28 A= =3D2 ,B=3D1 ... 0.15% 6.6K 1.33% 946 A= =3D1 ,B=3D- ... 0.11% 4.5K 0.06% 46 A= =3D3+,B=3D- ... 0.10% 4.4K 0.88% 624 A= =3D1 ,B=3D- ... 0.09% 3.7K 0.74% 524 A= =3D3+,B=3D1 ... Signed-off-by: Kan Liang Acked-by: Namhyung Kim Reviewed-by: Andi Kleen --- tools/perf/Documentation/perf-report.txt | 1 + tools/perf/builtin-diff.c | 4 +- tools/perf/builtin-report.c | 20 +++- tools/perf/ui/browsers/hists.c | 17 ++- tools/perf/util/annotate.c | 145 +++++++++++++++++++++++ tools/perf/util/annotate.h | 3 + tools/perf/util/block-info.c | 66 +++++++++-- tools/perf/util/block-info.h | 8 +- 8 files changed, 246 insertions(+), 18 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Document= ation/perf-report.txt index d2b1593ef700..7c66d81ab978 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -614,6 +614,7 @@ include::itrace.txt[] 'Avg Cycles%' - block average sampled cycles / sum of total block ave= rage sampled cycles 'Avg Cycles' - block average sampled cycles + 'Branch Counter' - block branch counter histogram (with -v showing the n= umber) =20 --skip-empty:: Do not print 0 results in the --stat output. diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 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 13b41c5f99ed..a8d0135166c0 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; @@ -1120,18 +1127,23 @@ static int __cmd_report(struct report *rep) report__output_resort(rep); =20 if (rep->total_cycles_mode) { - int block_hpps[6] =3D { + int nr_hpps =3D 4; + int block_hpps[PERF_HPP_REPORT__BLOCK_MAX_INDEX] =3D { PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT, PERF_HPP_REPORT__BLOCK_LBR_CYCLES, PERF_HPP_REPORT__BLOCK_CYCLES_PCT, PERF_HPP_REPORT__BLOCK_AVG_CYCLES, - PERF_HPP_REPORT__BLOCK_RANGE, - PERF_HPP_REPORT__BLOCK_DSO, }; =20 + if (session->evlist->nr_br_cntr > 0) + block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER; + + block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_RANGE; + block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_DSO; + rep->block_reports =3D block_info__create_report(session->evlist, rep->total_cycles, - block_hpps, 6, + block_hpps, nr_hpps, &rep->nr_block_reports); if (!rep->block_reports) return -1; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b7219df51236..970f7f349298 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3684,8 +3684,10 @@ int block_hists_tui_browse(struct block_hist *bh, st= ruct evsel *evsel, struct hist_browser *browser; int key =3D -1; struct popup_action action; + char *br_cntr_text =3D NULL; static const char help[] =3D - " q Quit \n"; + " q Quit \n" + " B Branch counter abbr list (Optional)\n"; =20 browser =3D hist_browser__new(hists); if (!browser) @@ -3703,6 +3705,8 @@ int block_hists_tui_browse(struct block_hist *bh, str= uct evsel *evsel, =20 memset(&action, 0, sizeof(action)); =20 + annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false); + while (1) { key =3D hist_browser__run(browser, "? - help", true, 0); =20 @@ -3723,6 +3727,16 @@ int block_hists_tui_browse(struct block_hist *bh, st= ruct evsel *evsel, action.ms.sym =3D browser->selection->sym; do_annotate(browser, &action); continue; + case 'B': + if (br_cntr_text) { + ui__question_window("Branch counter abbr list", + br_cntr_text, "Press any key...", 0); + } else { + ui__question_window("Branch counter abbr list", + "\n The branch counter is not available.\n", + "Press any key...", 0); + } + continue; default: break; } @@ -3730,5 +3744,6 @@ int block_hists_tui_browse(struct block_hist *bh, str= uct evsel *evsel, =20 out: hist_browser__delete(browser); + free(br_cntr_text); return 0; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f3d8e703f81b..0c19133133f2 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" @@ -1718,6 +1720,149 @@ static void ipc_coverage_string(char *bf, int size,= struct annotation *notes) ipc, coverage); } =20 +int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool hea= der) +{ + struct evsel *pos; + struct strbuf sb; + + if (evsel->evlist->nr_br_cntr <=3D 0) + return -ENOTSUP; + + strbuf_init(&sb, /*hint=3D*/ 0); + + if (header && strbuf_addf(&sb, "# Branch counter abbr list:\n")) + goto err; + + evlist__for_each_entry(evsel->evlist, pos) { + if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) + continue; + if (header && strbuf_addf(&sb, "#")) + goto err; + + if (strbuf_addf(&sb, " %s =3D %s\n", pos->name, pos->abbr_name)) + goto err; + } + + if (header && strbuf_addf(&sb, "#")) + goto err; + if (strbuf_addf(&sb, " '-' No event occurs\n")) + goto err; + + if (header && strbuf_addf(&sb, "#")) + goto err; + if (strbuf_addf(&sb, " '+' Event occurrences may be lost due to branch co= unter saturated\n")) + goto err; + + *str =3D strbuf_detach(&sb, NULL); + + return 0; +err: + strbuf_release(&sb); + return -ENOMEM; +} + +/* Assume the branch counter saturated at 3 */ +#define ANNOTATION_BR_CNTR_SATURATION 3 + +int annotation_br_cntr_entry(char **str, int br_cntr_nr, + u64 *br_cntr, int num_aggr, + struct evsel *evsel) +{ + struct evsel *pos =3D evsel ? evlist__first(evsel->evlist) : NULL; + bool saturated =3D false; + int i, j, avg, used; + struct strbuf sb; + + strbuf_init(&sb, /*hint=3D*/ 0); + for (i =3D 0; i < br_cntr_nr; i++) { + used =3D 0; + avg =3D ceil((double)(br_cntr[i] & ~ANNOTATION__BR_CNTR_SATURATED_FLAG) / + (double)num_aggr); + + /* + * A histogram with the abbr name is displayed by default. + * With -v, the exact number of branch counter is displayed. + */ + if (verbose) { + evlist__for_each_entry_from(evsel->evlist, pos) { + if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) = && + (pos->br_cntr_idx =3D=3D i)) + break; + } + if (strbuf_addstr(&sb, pos->abbr_name)) + goto err; + + if (!br_cntr[i]) { + if (strbuf_addstr(&sb, "=3D-")) + goto err; + } else { + if (strbuf_addf(&sb, "=3D%d", avg)) + goto err; + } + if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG) { + if (strbuf_addch(&sb, '+')) + goto err; + } else { + if (strbuf_addch(&sb, ' ')) + goto err; + } + + if ((i < br_cntr_nr - 1) && strbuf_addch(&sb, ',')) + goto err; + continue; + } + + if (strbuf_addch(&sb, '|')) + goto err; + + if (!br_cntr[i]) { + if (strbuf_addch(&sb, '-')) + goto err; + used++; + } else { + evlist__for_each_entry_from(evsel->evlist, pos) { + if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) = && + (pos->br_cntr_idx =3D=3D i)) + break; + } + if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG) + saturated =3D true; + + for (j =3D 0; j < avg; j++, used++) { + /* Print + if the number of logged events > 3 */ + if (j >=3D ANNOTATION_BR_CNTR_SATURATION) { + saturated =3D true; + break; + } + if (strbuf_addstr(&sb, pos->abbr_name)) + goto err; + } + + if (saturated) { + if (strbuf_addch(&sb, '+')) + goto err; + used++; + } + pos =3D list_next_entry(pos, core.node); + } + + for (j =3D used; j < ANNOTATION_BR_CNTR_SATURATION + 1; j++) { + if (strbuf_addch(&sb, ' ')) + goto err; + } + } + + if (!verbose && strbuf_addch(&sb, br_cntr_nr ? '|' : ' ')) + goto err; + + *str =3D strbuf_detach(&sb, NULL); + + return 0; +err: + strbuf_release(&sb); + return -ENOMEM; +} + static void __annotation_line__write(struct annotation_line *al, struct an= notation *notes, bool first_line, bool current_entry, bool change_color, int width, void *obj, unsigned int percent_type, diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 76ccb0e721c7..f0539001472e 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -551,4 +551,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 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 6165F1591ED; Thu, 8 Aug 2024 19:32:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145578; cv=none; b=jWzOKktGk47FuWW9jtMjtGE19UM90bOIHogA9FGrC+A1EYCu40RtH8TArk4vS9Fp19YFwwFI9mdOFM8GXklsN7MX/C26KCqMOTfQkbOTcQXva0HYerX86VuCRduJB3OEMlIkrBTI0Dr+awl0u7qTTjY132su2Zd27lcbUAB8uaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145578; c=relaxed/simple; bh=4Vgvc/9gkwPsauVHET+ZkDc55wPGf919zbFKFnbWKfQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=PF9gyE8ixx6eo73yHoOQcm9pJAKDnZtgLyVw6XSTA4ITYqxXRFMuTMArtuPLn3RkUJzChrXkhixtY7x9bgcO28Oq+8Lwe/eHJSZrwvo3uM7CmnLESgZi8WkjL4J7EDckELFTIxz/RnGOUGt/4h+owWcBUvPIc3yCdPiQX5TTmKk= 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=kf6c5I9r; arc=none smtp.client-ip=198.175.65.14 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="kf6c5I9r" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145577; x=1754681577; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4Vgvc/9gkwPsauVHET+ZkDc55wPGf919zbFKFnbWKfQ=; b=kf6c5I9roNU6SKhPA5YuDbnEv5SwinFnwxEGapJk2pI+wtH4Z9AUkmB1 0ieedJ0bjCnlHxOPfg7yDD4vlBL/Yw0wJ1sv+CFJjK6XjBjurmmdCs3kU zwJEVGuPKZ6HRbplj/uB1g6nX+2rMYZxB5D0HD7lwCBNYe0G9xDMZQle2 xQ2QwC0rilJUZXQIUGL/vG5pTjPomm832ScSVvE0BADRxhoKLct/gMZiH Nvs+eMKN3Sgzo2drWMn2FHp55H3dgTklZ5gn6EraQzCBdNYyIMxTFj7W7 CxgXqiDr4cfwLEFIn/NlfSV3wWIIPByCadmhGRJke2ZzDtwVxu65fuhvt Q==; X-CSE-ConnectionGUID: BaAoGMgETRedAVzrT+zzUg== X-CSE-MsgGUID: itBI/HbbSlaOy2iFIDcWcw== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091719" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091719" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:53 -0700 X-CSE-ConnectionGUID: DjpWjTSfSzGEwlSbU//F7g== X-CSE-MsgGUID: ixm7H/mzSeGxlnmC/5Tpkg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402600" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:52 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang , Tinghao Zhang Subject: [PATCH V2 7/9] perf annotate: Display the branch counter histogram Date: Thu, 8 Aug 2024 12:33:22 -0700 Message-Id: <20240808193324.2027665-8-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-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 Acked-by: Namhyung Kim Reviewed-by: Andi Kleen --- 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 dbe94441e4e9..a6388afcc773 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -919,11 +919,15 @@ int cmd_annotate(int argc, const char **argv) sort_order =3D "dso,symbol"; =20 /* - * Set SORT_MODE__BRANCH so that annotate display IPC/Cycle - * if branch info is in perf data in TUI mode. + * Set SORT_MODE__BRANCH so that annotate displays IPC/Cycle and + * branch counters, if the corresponding branch info is available + * in the perf data in the TUI mode. */ - if ((use_browser =3D=3D 1 || annotate.use_stdio2) && annotate.has_br_stac= k) + if ((use_browser =3D=3D 1 || annotate.use_stdio2) && annotate.has_br_stac= k) { sort__mode =3D SORT_MODE__BRANCH; + if (annotate.session->evlist->nr_br_cntr > 0) + annotate_opts.show_br_cntr =3D true; + } =20 if (setup_sorting(NULL) < 0) usage_with_options(annotate_usage, options); diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index fe991a81256b..d7e727345dab 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -156,6 +156,7 @@ static void annotate_browser__draw_current_jump(struct = ui_browser *browser) struct symbol *sym =3D ms->sym; struct annotation *notes =3D symbol__annotation(sym); u8 pcnt_width =3D annotation__pcnt_width(notes); + u8 cntr_width =3D annotation__br_cntr_width(); int width; int diff =3D 0; =20 @@ -205,13 +206,13 @@ static void annotate_browser__draw_current_jump(struc= t ui_browser *browser) =20 ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); __ui_browser__line_arrow(browser, - pcnt_width + 2 + notes->src->widths.addr + width, + pcnt_width + 2 + notes->src->widths.addr + width + cntr_width, from, to); =20 diff =3D is_fused(ab, cursor); if (diff > 0) { ui_browser__mark_fused(browser, - pcnt_width + 3 + notes->src->widths.addr + width, + pcnt_width + 3 + notes->src->widths.addr + width + cntr_width, from - diff, diff, to > from); } } @@ -714,6 +715,7 @@ static int annotate_browser__run(struct annotate_browse= r *browser, struct annotation *notes =3D symbol__annotation(ms->sym); const char *help =3D "Press 'h' for help on key bindings"; int delay_secs =3D hbt ? hbt->refresh : 0; + char *br_cntr_text =3D NULL; char title[256]; int key; =20 @@ -730,6 +732,8 @@ static int annotate_browser__run(struct annotate_browse= r *browser, =20 nd =3D browser->curr_hot; =20 + annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false); + while (1) { key =3D ui_browser__run(&browser->b, delay_secs); =20 @@ -796,6 +800,7 @@ static int annotate_browser__run(struct annotate_browse= r *browser, "r Run available scripts\n" "p Toggle percent type [local/global]\n" "b Toggle percent base [period/hits]\n" + "B Branch counter abbr list (Optional)\n" "? Search string backwards\n" "f Toggle showing offsets to full address\n"); continue; @@ -904,6 +909,14 @@ static int annotate_browser__run(struct annotate_brows= er *browser, hists__scnprintf_title(hists, title, sizeof(title)); annotate_browser__show(&browser->b, title, help); continue; + case 'B': + if (br_cntr_text) + ui_browser__help_window(&browser->b, br_cntr_text); + else { + ui_browser__help_window(&browser->b, + "\n The branch counter is not available.\n"); + } + continue; case 'f': annotation__toggle_full_addr(notes, ms); continue; @@ -923,6 +936,7 @@ static int annotate_browser__run(struct annotate_browse= r *browser, } out: ui_browser__hide(&browser->b); + free(br_cntr_text); return key; } =20 diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 970f7f349298..49ba82bf3391 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3705,7 +3705,8 @@ int block_hists_tui_browse(struct block_hist *bh, str= uct evsel *evsel, =20 memset(&action, 0, sizeof(action)); =20 - annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false); + if (!annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false)) + annotate_opts.show_br_cntr =3D true; =20 while (1) { key =3D hist_browser__run(browser, "? - help", true, 0); diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 0c19133133f2..e183dae3eab0 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); + } } } } @@ -1959,6 +1977,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); @@ -2055,7 +2089,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 f0539001472e..8556f606409e 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -31,6 +31,7 @@ struct annotated_data_type; #define ANNOTATION__CYCLES_WIDTH 6 #define ANNOTATION__MINMAX_CYCLES_WIDTH 19 #define ANNOTATION__AVG_IPC_WIDTH 36 +#define ANNOTATION__BR_CNTR_WIDTH 30 #define ANNOTATION_DUMMY_LEN 256 =20 struct annotation_options { @@ -44,6 +45,7 @@ struct annotation_options { show_nr_jumps, show_minmax_cycle, show_asm_raw, + show_br_cntr, annotate_src, full_addr; u8 offset_level; @@ -104,6 +106,10 @@ struct annotation_line { char *fileloc; char *path; struct cycles_info *cycles; + int num_aggr; + int br_cntr_nr; + u64 *br_cntr; + struct evsel *evsel; int jump_sources; u32 idx; int idx_asm; @@ -353,6 +359,11 @@ static inline bool annotation_line__filter(struct anno= tation_line *al) return annotate_opts.hide_src_code && al->offset =3D=3D -1; } =20 +static inline u8 annotation__br_cntr_width(void) +{ + return annotate_opts.show_br_cntr ? ANNOTATION__BR_CNTR_WIDTH : 0; +} + void annotation__update_column_widths(struct annotation *notes); void annotation__toggle_full_addr(struct annotation *notes, struct map_sym= bol *ms); =20 diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 22289003e16d..68aae87101bd 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -1014,6 +1014,7 @@ static void annotation_line__exit(struct annotation_l= ine *al) zfree_srcline(&al->path); zfree(&al->line); zfree(&al->cycles); + zfree(&al->br_cntr); } =20 static size_t disasm_line_size(int nr) --=20 2.38.1 From nobody Sat Feb 7 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 9A6F51598E9; Thu, 8 Aug 2024 19:32:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145578; cv=none; b=lopeol6j5QGdKUmebwsYqVRu6lEl9yC3+4EEH2A/kqEr+lqKd1v42RqUO5d9khiCX3eI/DYHObL6GrTxO9y385UK371Kkt9HFumpXF+LAIu79Fq+Ne6F9/h8W6060WWXwqoEgR50RNoxH1G3RV4lQ/c8e2klZzPM5W4eKRFzShw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145578; c=relaxed/simple; bh=nGX4/1SsuB3debswjhQV3ylWUPdQhVBu9G3/DW/tklQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iQ+YrkncsF2UIKZZYn+lbt//Qeug+6SraUXz32qyvyiwGzuPeOZKru7NxP12/0ILjr9ELc6vuH7Dj7SYHDI6qsBniIpz5VhEjFb1oYb/jsW19wpOSc92zC3rVvgg0LQOsR5kWQNhcnoh5ExnK7dJQkCzhASHQgdnPhcZqE26FEc= 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=Lazypx5g; arc=none smtp.client-ip=198.175.65.14 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="Lazypx5g" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145577; x=1754681577; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nGX4/1SsuB3debswjhQV3ylWUPdQhVBu9G3/DW/tklQ=; b=Lazypx5g5fIikQ9Wmjj+2Afk2KLOufUmLFKDTpMEfY9kulHStO1WyB4K pZd/iOqHiZWhvm2NNrqf5JlZAvkM/YHKQEhZfrI+Gn4x8YGcbrqkh8yOy B7wWKbW1uFvp+feyTkRBnTVOHoUJGs0kXSeST00h0wE2pm0yDHtubEM6Q dwy+ZSiVW63hjuAj1Bg/8ikKQY165sL9XyxzrO99r8yU81fljx0467au/ wwOIROFnJNALNhdLPi7bhLAAbdRyfbH3cIqcqkdj1pnPyzWIT2mXmDyl3 bXXZPmwPa4tjjP++I60xNpfxvSrCDaFqz3x/FqZy+wLqNtyiL9o65BiHS g==; X-CSE-ConnectionGUID: uRU1MH8mRZGqJwVYFa1R/Q== X-CSE-MsgGUID: LVAd3nVTSrqBY1KC3edqbQ== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091724" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091724" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:53 -0700 X-CSE-ConnectionGUID: lgt8AILLQhGWKDY95LLL+g== X-CSE-MsgGUID: mVYljkokR+ihid39DcjJyg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402603" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:53 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang , Tinghao Zhang Subject: [PATCH V2 8/9] perf script: Add branch counters Date: Thu, 8 Aug 2024 12:33:23 -0700 Message-Id: <20240808193324.2027665-9-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-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 Acked-by: Namhyung Kim Reviewed-by: Andi Kleen --- 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 21:15:43 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.14]) (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 3A94C15B986; Thu, 8 Aug 2024 19:32:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145579; cv=none; b=i0UQm6nGf5/NyN/oDxUwHnfcG3aObwUaSHksy+fsiGthLfkYvLZTtCKzAcmMWOF4zL06DnLj4XT76EGyLlLFaxWakcB+DMPjbY7cpBE2o5ZBJXOowWOs0HgOMudyH1xXvtmzh1ZDvihFkcH/+dzZa3mMoe+jWt2ehg6NITqZ23s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723145579; c=relaxed/simple; bh=eRSy0qosXqU6Hszy6JkiW6BncOZYM9c0YyE7hCnYkgM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tnfyFtSvZ9gxoOHlfDApmAAzsUYy4bexnXo8lceMIu/a39fhioZMOfmvpVF+mB0GP92z7otwvcuzI1sJmrjia4k3id0/YhPEmXO8rfiWhiO2wVXNO4+2sWx5EvSouKf+HHDXQUrkDjcDZFpz9JxPj0VjV+pBhShAfSlMPlHoQrM= 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=b85OF0wA; arc=none smtp.client-ip=198.175.65.14 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="b85OF0wA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1723145578; x=1754681578; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eRSy0qosXqU6Hszy6JkiW6BncOZYM9c0YyE7hCnYkgM=; b=b85OF0wA68HeifVB+vqhVhVh718IZJW73T6CAXErrXWTikwaoQxAMdXg VwkJSqeP15TlTNjtnVSD0Y7tpS50MxITtvRFh2tN+1qAJyVM768sWQsiS Olh1Sqz8XgBcm1zOOl5vzgX3Izuzoc8CcLeZkP5nnFAIwIDmIvG23vzAr +O00+dcDWxaM/jy7/lfdXNieMJZTYmPWydk3Br99GGXl1OFt2O2w+Q9LC 22UF6M3tWHd/COXtZ2gPzNwaDvu8MzHfg64f+iF9Z7JIsmRkdAydNoYcN pBNvaMPmnKA6WYaMXewRfwUVI5v9DhDZgaAB97K77OWtFYpxwChiBhGWt A==; X-CSE-ConnectionGUID: KVPFH18qT7yg0hNCpjSaSg== X-CSE-MsgGUID: xOgD5xJaQ3+zfWgvFEsWKA== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="25091730" X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="25091730" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Aug 2024 12:32:53 -0700 X-CSE-ConnectionGUID: 7aa5ssSXTvKAi/5GMRzVIw== X-CSE-MsgGUID: t09XSuMsSO6hRoacedCXtg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,274,1716274800"; d="scan'208";a="57402607" Received: from kanliang-dev.jf.intel.com ([10.165.154.102]) by fmviesa010.fm.intel.com with ESMTP; 08 Aug 2024 12:32:53 -0700 From: kan.liang@linux.intel.com To: acme@kernel.org, namhyung@kernel.org, irogers@google.com, peterz@infradead.org, mingo@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, eranian@google.com, Kan Liang Subject: [PATCH V2 9/9] perf test: Add new test cases for the branch counter feature Date: Thu, 8 Aug 2024 12:33:24 -0700 Message-Id: <20240808193324.2027665-10-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20240808193324.2027665-1-kan.liang@linux.intel.com> References: <20240808193324.2027665-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 Acked-by: Namhyung Kim Reviewed-by: Andi Kleen --- 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