From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 30462C433F5 for ; Tue, 22 Mar 2022 22:15:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237608AbiCVWRD (ORCPT ); Tue, 22 Mar 2022 18:17:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229647AbiCVWQ6 (ORCPT ); Tue, 22 Mar 2022 18:16:58 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88392532FA for ; Tue, 22 Mar 2022 15:15:28 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id e7-20020a258747000000b00633ee0cbca5so6449144ybn.23 for ; Tue, 22 Mar 2022 15:15:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=F3HjAwFHmUFqibmCjU1kcbKfjPdPDY91fHBE1nAmJAM=; b=YJh7SVEbpn8oEZu7jCjxg6EQgGaZz+QnjlbSK4QakRjMXo0B3evobQA6gmx04u2l+N 57QSMdXwEcNFlkAyJhaGb3Ge7F/gJfXx/oGQerQ3SdMkPjoBNycjV0QbkgPaLoUhi++q FRYClxoPIA+zghk4KAx7Tf4HURQ0+b7MRpHAFrqS+2t63QSsUOXL32eJlouxFM2OU/bC jwvUO95XNJooPnUlqGOTzQk49GvB3sw3lEtDeGzin37xymcEt1kSbvzFha0sDbmS4MRK Ci9xfNGT49V6slQLa9Eh3yxZoa4Zgg66WTSRWKT976P2kTgZuMht14CPWHyP65pb+hIa LMgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=F3HjAwFHmUFqibmCjU1kcbKfjPdPDY91fHBE1nAmJAM=; b=t0VdTynflY+AZAXgcvR3zI/Rk5+Qnz79pZa0a0+l6zguuRHbUevxIZWq2tPEWSlUbR r6u/WwpIG8bnsAbAeX1yVQX8yk/QrmYBe1H0lfG9qTL9FCXIvJ+BvKGA8Qrb5MfMLTaW A3U96gtsRhoGwfQMhpmdN9HPQ+qtJiupcyLwN1FFesP/DH6iVktjFcdIsn02vR8jM1us AkwTRN8iRXjsoGukiLOs8Rxj9JLGxIX8zbVSVCqhcNG5jbJdwdnunB9+YpwCl8mpalMw G0iXtVTNILJLoBkigF4/vkNMo7QfyprIZHDaSaaEszV+OcI8YDNKV3WD1U56iR5Bhls5 7HBg== X-Gm-Message-State: AOAM5329QpDddYGWeAkcImLzONEfykKeIDVo4yybXr6ttBryHESdBc2R N12RpAYSIGZl7dgC/bsdlBtO+k+17QI/ViNlNC+VBOfzlqtH6LIgv8nphyGxEuzKLc7FTKQVHbJ yfecwWfiwrVG0//RZRBsfvVSsZ/TweUnkd86CEwtP43osRC2S9QNcdhN6FYR34oBu91kSTDbe X-Google-Smtp-Source: ABdhPJzO4ydn2G45VGg8j+cmD4fgAaCMbOgcCbiATHDQT+I6YXG1g30/TWMjkif9Z8Xl/XcMs1WlrgwY3IR5 X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a25:bc6:0:b0:633:b8aa:dc48 with SMTP id 189-20020a250bc6000000b00633b8aadc48mr24211634ybl.587.1647987327716; Tue, 22 Mar 2022 15:15:27 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:05 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-2-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 01/13] perf/core: add perf_clear_branch_entry_bitfields() helper From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make it simpler to reset all the info fields on the perf_branch_entry by adding a helper inline function. The goal is to centralize the initialization to avoid missing a field in case more are added. Signed-off-by: Stephane Eranian --- arch/x86/events/intel/lbr.c | 36 +++++++++++++++++------------------- include/linux/perf_event.h | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index fe1742c4ca49..13179f31fe10 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -769,6 +769,7 @@ void intel_pmu_lbr_disable_all(void) void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) { unsigned long mask =3D x86_pmu.lbr_nr - 1; + struct perf_branch_entry *br =3D cpuc->lbr_entries; u64 tos =3D intel_pmu_lbr_tos(); int i; =20 @@ -784,15 +785,11 @@ void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) =20 rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr); =20 - cpuc->lbr_entries[i].from =3D msr_lastbranch.from; - cpuc->lbr_entries[i].to =3D msr_lastbranch.to; - cpuc->lbr_entries[i].mispred =3D 0; - cpuc->lbr_entries[i].predicted =3D 0; - cpuc->lbr_entries[i].in_tx =3D 0; - cpuc->lbr_entries[i].abort =3D 0; - cpuc->lbr_entries[i].cycles =3D 0; - cpuc->lbr_entries[i].type =3D 0; - cpuc->lbr_entries[i].reserved =3D 0; + perf_clear_branch_entry_bitfields(br); + + br->from =3D msr_lastbranch.from; + br->to =3D msr_lastbranch.to; + br++; } cpuc->lbr_stack.nr =3D i; cpuc->lbr_stack.hw_idx =3D tos; @@ -807,6 +804,7 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) { bool need_info =3D false, call_stack =3D false; unsigned long mask =3D x86_pmu.lbr_nr - 1; + struct perf_branch_entry *br =3D cpuc->lbr_entries; u64 tos =3D intel_pmu_lbr_tos(); int i; int out =3D 0; @@ -878,15 +876,14 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) if (abort && x86_pmu.lbr_double_abort && out > 0) out--; =20 - cpuc->lbr_entries[out].from =3D from; - cpuc->lbr_entries[out].to =3D to; - cpuc->lbr_entries[out].mispred =3D mis; - cpuc->lbr_entries[out].predicted =3D pred; - cpuc->lbr_entries[out].in_tx =3D in_tx; - cpuc->lbr_entries[out].abort =3D abort; - cpuc->lbr_entries[out].cycles =3D cycles; - cpuc->lbr_entries[out].type =3D 0; - cpuc->lbr_entries[out].reserved =3D 0; + perf_clear_branch_entry_bitfields(br+out); + br[out].from =3D from; + br[out].to =3D to; + br[out].mispred =3D mis; + br[out].predicted =3D pred; + br[out].in_tx =3D in_tx; + br[out].abort =3D abort; + br[out].cycles =3D cycles; out++; } cpuc->lbr_stack.nr =3D out; @@ -951,6 +948,8 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *c= puc, to =3D rdlbr_to(i, lbr); info =3D rdlbr_info(i, lbr); =20 + perf_clear_branch_entry_bitfields(e); + e->from =3D from; e->to =3D to; e->mispred =3D get_lbr_mispred(info); @@ -959,7 +958,6 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *c= puc, e->abort =3D !!(info & LBR_INFO_ABORT); e->cycles =3D get_lbr_cycles(info); e->type =3D get_lbr_br_type(info); - e->reserved =3D 0; } =20 cpuc->lbr_stack.nr =3D i; diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 733649184b27..496eb6aa6e54 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1063,6 +1063,22 @@ static inline void perf_sample_data_init(struct perf= _sample_data *data, data->txn =3D 0; } =20 +/* + * Clear all bitfields in the perf_branch_entry. + * The to and from fields are not cleared because they are + * systematically modified by caller. + */ +static inline void perf_clear_branch_entry_bitfields(struct perf_branch_en= try *br) +{ + br->mispred =3D 0; + br->predicted =3D 0; + br->in_tx =3D 0; + br->abort =3D 0; + br->cycles =3D 0; + br->type =3D 0; + br->reserved =3D 0; +} + extern void perf_output_sample(struct perf_output_handle *handle, struct perf_event_header *header, struct perf_sample_data *data, --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45BD9C433EF for ; Tue, 22 Mar 2022 22:15:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237632AbiCVWRG (ORCPT ); Tue, 22 Mar 2022 18:17:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229532AbiCVWQ7 (ORCPT ); Tue, 22 Mar 2022 18:16:59 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E089532FC for ; Tue, 22 Mar 2022 15:15:31 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2d7eaa730d9so161987667b3.13 for ; Tue, 22 Mar 2022 15:15:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=50G7bdvRpnkEWCRx25n5fuGGImUWUWrpu2rzhqm9RSw=; b=Pcua82bNwW6ZhrNJ8K3tV/e5P5U/aHlgnnU7KxmReET5t16D1e4nkVGQ7njJdRSqnO H1nKUN1oBFzVI4daa5JWToQ5UE4J+zFha8+s3mt6eVvr3Q3d1JdlXA9DuaveQG1Ka823 ykzHaLAZ2IQbKUeIrG8PLJ4plllkDenhOEw0Glmkg4BNK2o+CFWBkvsuHq2R7HlKH7/h oC5NTfzGkTkVPfXPgujfjZt3uxB8Q/2jcT5E/CyV7IhbBnHjHG0WVWrijM7aF6J397Pk z42IvcI3hS3kw90xNBCdPbuKXsK2YNscLew2eID/XLCeRAUZxaoyFhQKlds6+4xNNjjP E3Jg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=50G7bdvRpnkEWCRx25n5fuGGImUWUWrpu2rzhqm9RSw=; b=vmQsBLYde20pOwI1c552vhaoTUy/DG4EuJRyuHT+NHN1VJlNM/ntoxfcs0txPJT+ZX rMaLAyT4Kjv+0IWH78/QhT4eqGQzTB3mQllBTl+OTpsrEgd7ekW9fPYlWql6LIvh0/vf xDKIZqKD5/UubBDmiY54vVTIgmcXytiuJ6h9eLu+34r1KGQvOKHNoFwiCRXi3PY4yd+V TNN+sy+kub5SL+N0hAz0ZujUNILuota7Q+RbvSX6yKBByibBopbWGFaJpiwUbIT50CoI wl/pCAeUoVw/q2XIAEYIAJdm0XBIRcRx6181jFr9ZenYj3TcRK2xJxoOTdyBvlgsnv3f P0wA== X-Gm-Message-State: AOAM5307LnVdYPKuS1/usJT0DdjgZXmlu9K8Bgmu68kE510TMLDljLwu CQhvYsyE8TTFOq6gmpYi7pFpiKMJwk0by2uE51/Mf0qip9Ui5RGZ9TkMJiUm84OQwOO9DaXb041 I451v8U+AWCe7/O0IX012gF5ho8+lUwN2dI4O9l3XFsVfoIPOO6q0y+RivCPaSmXQd3+uK/9O X-Google-Smtp-Source: ABdhPJyAcixNySsnaXqbNfFt9CkR18LFPySVrtwaEEbDXutyEY/llA+XXhfjQa6tGwAAUCG+IPj/MFOSGFZC X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a81:6d3:0:b0:2e5:a089:867e with SMTP id 202-20020a8106d3000000b002e5a089867emr31632385ywg.516.1647987330162; Tue, 22 Mar 2022 15:15:30 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:06 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-3-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 02/13] x86/cpufeatures: add AMD Fam19h Branch Sampling feature From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a cpu feature for AMD Fam19h Branch Sampling feature as bit 31 of EBX on CPUID leaf function 0x80000008. Signed-off-by: Stephane Eranian --- arch/x86/include/asm/cpufeatures.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpuf= eatures.h index 9a59e2e73bee..ff3ee4f4ebbb 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -315,6 +315,7 @@ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store= Bypass Disable */ #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass = is fixed in hardware. */ #define X86_FEATURE_CPPC (13*32+27) /* Collaborative Processor Performanc= e Control */ +#define X86_FEATURE_BRS (13*32+31) /* Branch Sampling available */ =20 /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 1= 4 */ #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32B8DC433FE for ; Tue, 22 Mar 2022 22:15:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237652AbiCVWRJ (ORCPT ); Tue, 22 Mar 2022 18:17:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237604AbiCVWRD (ORCPT ); Tue, 22 Mar 2022 18:17:03 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79F265370B for ; Tue, 22 Mar 2022 15:15:33 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2e5d456d198so116397347b3.23 for ; Tue, 22 Mar 2022 15:15:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=d/bMRMAVfBePVqAJ1yFvrO5cGfOd3mplNK66VTMlIkM=; b=a+N61/TEeAeQ4T9VZJ/QCXr6MLgVGPZtrF/RV2vpMRDi95irMmTpfsf05FCedrFL4L 2fH8U8Smnus7yeEaw2tmNfPAS3M1MrMDViNQBeXzmad8bSe3A5WhB/9Y0Lal1P6Q2xzH JbYRyMU6zDMz8BoluBDTiRns7VxgQvoJtTvLM3BFqA7+pj2P9lQuVBsoB2QuyGmNtmw4 VQyQfqDyN21YAgLlSp4BLFISAxP+tBY0oneRunOwNW8s3ON4j6kVsU4XBd13SamyCp/9 w0vI+o2EopSVJLZbzDnU9E+pBRk0rfl+pIPl5mOh56L7l/j6Ub9Fmx0WREVJyW6miZUD Q1pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=d/bMRMAVfBePVqAJ1yFvrO5cGfOd3mplNK66VTMlIkM=; b=N+5qH+W3TfjKjEyQVlXG7VjEWMz5Usr14kRx89rl6D6RcWaTBJFEsN4YvEbMKa+X13 nmasHFxys/NR0lhB3GxD1ZT8N7pRSvn9KjpvCQEIwbTimQoHnNvFCH0ZJpCRHUssdzfV mr0vcVFV6xAeyUwBzUFXQU4Tz1DegI+1UMbG5H3m433L4xdAkE0uZA3eZy2LGrMFNGfW UqMjX5AKMgk37sghLgdZl+geIceq/Yx/zqpjEYZmzzuj5DlWybL00KWYHdsjv+t1e5PR p9NMbkkjwrwkk0xuDR9FLq1xI7n+nujtjfugc1wrEdKPbGhte4LZmvyN8sPnwddmqCiK uVYg== X-Gm-Message-State: AOAM5317sCy4ZsiFS0eeisnV1WdzC24rKR6EOmec5B5PY191iB1XXcYZ NPAViBFzmVyKth41H7epPUsE3+2eEOBiEju+/DkuM6eJvOCwhBAobXBO9X8NjaqN2vkTrrTovzx 3h3TU6F4CS3nQL5QtqDn0ebBlWPY/wXlke9X0XImUntgEqaZmajEyKZsRv3SMeEgu7V5Ax0Hk X-Google-Smtp-Source: ABdhPJyZnDOWa3qRdWZ7MQjXm6Zy/If1yvK1CMWMupYS3FcMuhUKjwCBaV2nVIJjTUhnMWQRNrEbjKtHX4rV X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a5b:94d:0:b0:629:31c4:232d with SMTP id x13-20020a5b094d000000b0062931c4232dmr29979833ybq.455.1647987332702; Tue, 22 Mar 2022 15:15:32 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:07 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-4-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 03/13] perf/x86/amd: add AMD Fam19h Branch Sampling support From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for the AMD Fam19h 16-deep branch sampling feature as described in the AMD PPR Fam19h Model 01h Revision B1. This is a model specific extension. It is not an architected AMD feature. The Branch Sampling (BRS) operates with a 16-deep saturating buffer in MSR registers. There is no branch type filtering. All control flow changes are captured. BRS relies on specific programming of the core PMU of Fam19h. In particular, the following requirements must be met: - the sampling period be greater than 16 (BRS depth) - the sampling period must use a fixed and not frequency mode BRS interacts with the NMI interrupt as well. Because enabling BRS is expensive, it is only activated after P event occurrences, where P is the desired sampling period. At P occurrences of the event, the counter overflows, the CPU catches the interrupt, activates BRS for 16 branches unt= il it saturates, and then delivers the NMI to the kernel. Between the overflow and the time BRS activates more branches may be executed skewing the period. All along, the sampling event keeps counting. The skid may be attenuated by reducing the sampling period by 16 (subsequent patch). BRS is integrated into perf_events seamlessly via the same PERF_RECORD_BRANCH_STACK sample format. BRS generates perf_branch_entry records in the sampling buffer. No prediction information is supported. The branches are stored in reverse order of execution. The most recent branch = is the first entry in each record. No modification to the perf tool is necessary. BRS can be used with any sampling event. However, it is recommended to use the RETIRED_BRANCH_INSTRUCTIONS event because it matches what the BRS captures. $ perf record -b -c 1000037 -e cpu/event=3D0xc2,name=3Dret_br_instructions/= test $ perf report -D 56531696056126 0x193c000 [0x1a8]: PERF_RECORD_SAMPLE(IP, 0x2): 18122/18230:= 0x401d24 period: 1000037 addr: 0 ... branch stack: nr:16 ..... 0: 0000000000401d24 -> 0000000000401d5a 0 cycles 0 ..... 1: 0000000000401d5c -> 0000000000401d24 0 cycles 0 ..... 2: 0000000000401d22 -> 0000000000401d5c 0 cycles 0 ..... 3: 0000000000401d5e -> 0000000000401d22 0 cycles 0 ..... 4: 0000000000401d20 -> 0000000000401d5e 0 cycles 0 ..... 5: 0000000000401d3e -> 0000000000401d20 0 cycles 0 ..... 6: 0000000000401d42 -> 0000000000401d3e 0 cycles 0 ..... 7: 0000000000401d3c -> 0000000000401d42 0 cycles 0 ..... 8: 0000000000401d44 -> 0000000000401d3c 0 cycles 0 ..... 9: 0000000000401d3a -> 0000000000401d44 0 cycles 0 ..... 10: 0000000000401d46 -> 0000000000401d3a 0 cycles 0 ..... 11: 0000000000401d38 -> 0000000000401d46 0 cycles 0 ..... 12: 0000000000401d48 -> 0000000000401d38 0 cycles 0 ..... 13: 0000000000401d36 -> 0000000000401d48 0 cycles 0 ..... 14: 0000000000401d4a -> 0000000000401d36 0 cycles 0 ..... 15: 0000000000401d34 -> 0000000000401d4a 0 cycles 0 ... thread: test:18230 ...... dso: test Signed-off-by: Stephane Eranian --- arch/x86/events/amd/Makefile | 2 +- arch/x86/events/amd/brs.c | 317 +++++++++++++++++++++++++++++++ arch/x86/events/amd/core.c | 233 ++++++++++++++++++++++- arch/x86/events/core.c | 10 +- arch/x86/events/perf_event.h | 101 ++++++++-- arch/x86/include/asm/msr-index.h | 4 + 6 files changed, 645 insertions(+), 22 deletions(-) create mode 100644 arch/x86/events/amd/brs.c diff --git a/arch/x86/events/amd/Makefile b/arch/x86/events/amd/Makefile index 6cbe38d5fd9d..cf323ffab5cd 100644 --- a/arch/x86/events/amd/Makefile +++ b/arch/x86/events/amd/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CPU_SUP_AMD) +=3D core.o +obj-$(CONFIG_CPU_SUP_AMD) +=3D core.o brs.o obj-$(CONFIG_PERF_EVENTS_AMD_POWER) +=3D power.o obj-$(CONFIG_X86_LOCAL_APIC) +=3D ibs.o obj-$(CONFIG_PERF_EVENTS_AMD_UNCORE) +=3D amd-uncore.o diff --git a/arch/x86/events/amd/brs.c b/arch/x86/events/amd/brs.c new file mode 100644 index 000000000000..3c13c484c637 --- /dev/null +++ b/arch/x86/events/amd/brs.c @@ -0,0 +1,317 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Implement support for AMD Fam19h Branch Sampling feature + * Based on specifications published in AMD PPR Fam19 Model 01 + * + * Copyright 2021 Google LLC + * Contributed by Stephane Eranian + */ +#include +#include +#include + +#include "../perf_event.h" + +#define BRS_POISON 0xFFFFFFFFFFFFFFFEULL /* mark limit of valid entries */ + +/* Debug Extension Configuration register layout */ +union amd_debug_extn_cfg { + __u64 val; + struct { + __u64 rsvd0:2, /* reserved */ + brsmen:1, /* branch sample enable */ + rsvd4_3:2,/* reserved - must be 0x3 */ + vb:1, /* valid branches recorded */ + rsvd2:10, /* reserved */ + msroff:4, /* index of next entry to write */ + rsvd3:4, /* reserved */ + pmc:3, /* #PMC holding the sampling event */ + rsvd4:37; /* reserved */ + }; +}; + +static inline unsigned int brs_from(int idx) +{ + return MSR_AMD_SAMP_BR_FROM + 2 * idx; +} + +static inline unsigned int brs_to(int idx) +{ + return MSR_AMD_SAMP_BR_FROM + 2 * idx + 1; +} + +static inline void set_debug_extn_cfg(u64 val) +{ + /* bits[4:3] must always be set to 11b */ + wrmsrl(MSR_AMD_DBG_EXTN_CFG, val | 3ULL << 3); +} + +static inline u64 get_debug_extn_cfg(void) +{ + u64 val; + + rdmsrl(MSR_AMD_DBG_EXTN_CFG, val); + return val; +} + +static bool __init amd_brs_detect(void) +{ + if (!boot_cpu_has(X86_FEATURE_BRS)) + return false; + + switch (boot_cpu_data.x86) { + case 0x19: /* AMD Fam19h (Zen3) */ + x86_pmu.lbr_nr =3D 16; + + /* No hardware filtering supported */ + x86_pmu.lbr_sel_map =3D NULL; + x86_pmu.lbr_sel_mask =3D 0; + break; + default: + return false; + } + + return true; +} + +/* + * Current BRS implementation does not support branch type or privilege le= vel + * filtering. Therefore, this function simply enforces these limitations. = No need for + * a br_sel_map. Software filtering is not supported because it would not = correlate well + * with a sampling period. + */ +int amd_brs_setup_filter(struct perf_event *event) +{ + u64 type =3D event->attr.branch_sample_type; + + /* No BRS support */ + if (!x86_pmu.lbr_nr) + return -EOPNOTSUPP; + + /* Can only capture all branches, i.e., no filtering */ + if ((type & ~PERF_SAMPLE_BRANCH_PLM_ALL) !=3D PERF_SAMPLE_BRANCH_ANY) + return -EINVAL; + + /* can only capture at all priv levels due to the way BRS works */ + if ((type & PERF_SAMPLE_BRANCH_PLM_ALL) !=3D PERF_SAMPLE_BRANCH_PLM_ALL) + return -EINVAL; + + return 0; +} + +/* tos =3D top of stack, i.e., last valid entry written */ +static inline int amd_brs_get_tos(union amd_debug_extn_cfg *cfg) +{ + /* + * msroff: index of next entry to write so top-of-stack is one off + * if BRS is full then msroff is set back to 0. + */ + return (cfg->msroff ? cfg->msroff : x86_pmu.lbr_nr) - 1; +} + +/* + * make sure we have a sane BRS offset to begin with + * especially with kexec + */ +void amd_brs_reset(void) +{ + /* + * Reset config + */ + set_debug_extn_cfg(0); + + /* + * Mark first entry as poisoned + */ + wrmsrl(brs_to(0), BRS_POISON); +} + +int __init amd_brs_init(void) +{ + if (!amd_brs_detect()) + return -EOPNOTSUPP; + + pr_cont("%d-deep BRS, ", x86_pmu.lbr_nr); + + return 0; +} + +void amd_brs_enable(void) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + union amd_debug_extn_cfg cfg; + + /* Activate only on first user */ + if (++cpuc->brs_active > 1) + return; + + cfg.val =3D 0; /* reset all fields */ + cfg.brsmen =3D 1; /* enable branch sampling */ + + /* Set enable bit */ + set_debug_extn_cfg(cfg.val); +} + +void amd_brs_enable_all(void) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + if (cpuc->lbr_users) + amd_brs_enable(); +} + +void amd_brs_disable(void) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + union amd_debug_extn_cfg cfg; + + /* Check if active (could be disabled via x86_pmu_disable_all()) */ + if (!cpuc->brs_active) + return; + + /* Only disable for last user */ + if (--cpuc->brs_active) + return; + + /* + * Clear the brsmen bit but preserve the others as they contain + * useful state such as vb and msroff + */ + cfg.val =3D get_debug_extn_cfg(); + + /* + * When coming in on interrupt and BRS is full, then hw will have + * already stopped BRS, no need to issue wrmsr again + */ + if (cfg.brsmen) { + cfg.brsmen =3D 0; + set_debug_extn_cfg(cfg.val); + } +} + +void amd_brs_disable_all(void) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + if (cpuc->lbr_users) + amd_brs_disable(); +} + +/* + * Caller must ensure amd_brs_inuse() is true before calling + * return: + */ +void amd_brs_drain(void) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + struct perf_event *event =3D cpuc->events[0]; + struct perf_branch_entry *br =3D cpuc->lbr_entries; + union amd_debug_extn_cfg cfg; + u32 i, nr =3D 0, num, tos, start; + u32 shift =3D 64 - boot_cpu_data.x86_virt_bits; + + /* + * BRS event forced on PMC0, + * so check if there is an event. + * It is possible to have lbr_users > 0 but the event + * not yet scheduled due to long latency PMU irq + */ + if (!event) + goto empty; + + cfg.val =3D get_debug_extn_cfg(); + + /* Sanity check [0-x86_pmu.lbr_nr] */ + if (WARN_ON_ONCE(cfg.msroff >=3D x86_pmu.lbr_nr)) + goto empty; + + /* No valid branch */ + if (cfg.vb =3D=3D 0) + goto empty; + + /* + * msr.off points to next entry to be written + * tos =3D most recent entry index =3D msr.off - 1 + * BRS register buffer saturates, so we know we have + * start < tos and that we have to read from start to tos + */ + start =3D 0; + tos =3D amd_brs_get_tos(&cfg); + + num =3D tos - start + 1; + + /* + * BRS is only one pass (saturation) from MSROFF to depth-1 + * MSROFF wraps to zero when buffer is full + */ + for (i =3D 0; i < num; i++) { + u32 brs_idx =3D tos - i; + u64 from, to; + + rdmsrl(brs_to(brs_idx), to); + + /* Entry does not belong to us (as marked by kernel) */ + if (to =3D=3D BRS_POISON) + break; + + rdmsrl(brs_from(brs_idx), from); + + /* + * Sign-extend SAMP_BR_TO to 64 bits, bits 61-63 are reserved. + * Necessary to generate proper virtual addresses suitable for + * symbolization + */ + to =3D (u64)(((s64)to << shift) >> shift); + + perf_clear_branch_entry_bitfields(br+nr); + + br[nr].from =3D from; + br[nr].to =3D to; + + nr++; + } +empty: + /* Record number of sampled branches */ + cpuc->lbr_stack.nr =3D nr; +} + +/* + * Poison most recent entry to prevent reuse by next task + * required because BRS entry are not tagged by PID + */ +static void amd_brs_poison_buffer(void) +{ + union amd_debug_extn_cfg cfg; + unsigned int idx; + + /* Get current state */ + cfg.val =3D get_debug_extn_cfg(); + + /* idx is most recently written entry */ + idx =3D amd_brs_get_tos(&cfg); + + /* Poison target of entry */ + wrmsrl(brs_to(idx), BRS_POISON); +} + +/* + * On context switch in, we need to make sure no samples from previous user + * are left in the BRS. + * + * On ctxswin, sched_in =3D true, called after the PMU has started + * On ctxswout, sched_in =3D false, called before the PMU is stopped + */ +void amd_pmu_brs_sched_task(struct perf_event_context *ctx, bool sched_in) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + + /* no active users */ + if (!cpuc->lbr_users) + return; + + /* + * On context switch in, we need to ensure we do not use entries + * from previous BRS user on that CPU, so we poison the buffer as + * a faster way compared to resetting all entries. + */ + if (sched_in) + amd_brs_poison_buffer(); +} diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 9687a8aef01c..c7ac70d8ed9a 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -325,8 +325,16 @@ static inline bool amd_is_pair_event_code(struct hw_pe= rf_event *hwc) } } =20 +#define AMD_FAM19H_BRS_EVENT 0xc4 /* RETIRED_TAKEN_BRANCH_INSTRUCTIONS */ +static inline int amd_is_brs_event(struct perf_event *e) +{ + return (e->hw.config & AMD64_RAW_EVENT_MASK) =3D=3D AMD_FAM19H_BRS_EVENT; +} + static int amd_core_hw_config(struct perf_event *event) { + int ret =3D 0; + if (event->attr.exclude_host && event->attr.exclude_guest) /* * When HO =3D=3D GO =3D=3D 1 the hardware treats that as GO =3D=3D HO = =3D=3D 0 @@ -343,7 +351,66 @@ static int amd_core_hw_config(struct perf_event *event) if ((x86_pmu.flags & PMU_FL_PAIR) && amd_is_pair_event_code(&event->hw)) event->hw.flags |=3D PERF_X86_EVENT_PAIR; =20 - return 0; + /* + * if branch stack is requested + */ + if (has_branch_stack(event)) { + /* + * Due to interrupt holding, BRS is not recommended in + * counting mode. + */ + if (!is_sampling_event(event)) + return -EINVAL; + + /* + * Due to the way BRS operates by holding the interrupt until + * lbr_nr entries have been captured, it does not make sense + * to allow sampling on BRS with an event that does not match + * what BRS is capturing, i.e., retired taken branches. + * Otherwise the correlation with the event's period is even + * more loose: + * + * With retired taken branch: + * Effective P =3D P + 16 + X + * With any other event: + * Effective P =3D P + Y + X + * + * Where X is the number of taken branches due to interrupt + * skid. Skid is large. + * + * Where Y is the occurences of the event while BRS is + * capturing the lbr_nr entries. + * + * By using retired taken branches, we limit the impact on the + * Y variable. We know it cannot be more than the depth of + * BRS. + */ + if (!amd_is_brs_event(event)) + return -EINVAL; + + /* + * BRS implementation does not work with frequency mode + * reprogramming of the period. + */ + if (event->attr.freq) + return -EINVAL; + /* + * The kernel subtracts BRS depth from period, so it must + * be big enough. + */ + if (event->attr.sample_period <=3D x86_pmu.lbr_nr) + return -EINVAL; + + /* + * Check if we can allow PERF_SAMPLE_BRANCH_STACK + */ + ret =3D amd_brs_setup_filter(event); + + /* only set in case of success */ + if (!ret) + event->hw.flags |=3D PERF_X86_EVENT_AMD_BRS; + } + return ret; } =20 static inline int amd_is_nb_event(struct hw_perf_event *hwc) @@ -366,7 +433,7 @@ static int amd_pmu_hw_config(struct perf_event *event) if (event->attr.precise_ip && get_ibs_caps()) return -ENOENT; =20 - if (has_branch_stack(event)) + if (has_branch_stack(event) && !x86_pmu.lbr_nr) return -EOPNOTSUPP; =20 ret =3D x86_pmu_hw_config(event); @@ -555,6 +622,8 @@ static void amd_pmu_cpu_starting(int cpu) =20 cpuc->amd_nb->nb_id =3D nb_id; cpuc->amd_nb->refcnt++; + + amd_brs_reset(); } =20 static void amd_pmu_cpu_dead(int cpu) @@ -610,6 +679,8 @@ static void amd_pmu_disable_all(void) struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); int idx; =20 + amd_brs_disable_all(); + x86_pmu_disable_all(); =20 /* @@ -634,6 +705,30 @@ static void amd_pmu_disable_all(void) } } =20 +static void amd_pmu_enable_event(struct perf_event *event) +{ + x86_pmu_enable_event(event); +} + +static void amd_pmu_enable_all(int added) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + struct hw_perf_event *hwc; + int idx; + + amd_brs_enable_all(); + + for (idx =3D 0; idx < x86_pmu.num_counters; idx++) { + hwc =3D &cpuc->events[idx]->hw; + + /* only activate events which are marked as active */ + if (!test_bit(idx, cpuc->active_mask)) + continue; + + amd_pmu_enable_event(cpuc->events[idx]); + } +} + static void amd_pmu_disable_event(struct perf_event *event) { x86_pmu_disable_event(event); @@ -651,6 +746,18 @@ static void amd_pmu_disable_event(struct perf_event *e= vent) amd_pmu_wait_on_overflow(event->hw.idx); } =20 +static void amd_pmu_add_event(struct perf_event *event) +{ + if (needs_branch_stack(event)) + amd_pmu_brs_add(event); +} + +static void amd_pmu_del_event(struct perf_event *event) +{ + if (needs_branch_stack(event)) + amd_pmu_brs_del(event); +} + /* * Because of NMI latency, if multiple PMC counters are active or other so= urces * of NMIs are received, the perf NMI handler can handle one or more overf= lowed @@ -671,11 +778,31 @@ static void amd_pmu_disable_event(struct perf_event *= event) */ static int amd_pmu_handle_irq(struct pt_regs *regs) { + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); int handled; + int pmu_enabled; + + /* + * Save the PMU state. + * It needs to be restored when leaving the handler. + */ + pmu_enabled =3D cpuc->enabled; + cpuc->enabled =3D 0; + + /* stop everything (includes BRS) */ + amd_pmu_disable_all(); + + /* Drain BRS is in use (could be inactive) */ + if (cpuc->lbr_users) + amd_brs_drain(); =20 /* Process any counter overflows */ handled =3D x86_pmu_handle_irq(regs); =20 + cpuc->enabled =3D pmu_enabled; + if (pmu_enabled) + amd_pmu_enable_all(0); + /* * If a counter was handled, record a timestamp such that un-handled * NMIs will be claimed if arriving within that window. @@ -897,6 +1024,51 @@ static void amd_put_event_constraints_f17h(struct cpu= _hw_events *cpuc, --cpuc->n_pair; } =20 +/* + * Because of the way BRS operates with an inactive and active phases, and + * the link to one counter, it is not possible to have two events using BRS + * scheduled at the same time. There would be an issue with enforcing the + * period of each one and given that the BRS saturates, it would not be po= ssible + * to guarantee correlated content for all events. Therefore, in situations + * where multiple events want to use BRS, the kernel enforces mutual exclu= sion. + * Exclusion is enforced by chosing only one counter for events using BRS. + * The event scheduling logic will then automatically multiplex the + * events and ensure that at most one event is actively using BRS. + * + * The BRS counter could be any counter, but there is no constraint on Fam= 19h, + * therefore all counters are equal and thus we pick the first one: PMC0 + */ +static struct event_constraint amd_fam19h_brs_cntr0_constraint =3D + EVENT_CONSTRAINT(0, 0x1, AMD64_RAW_EVENT_MASK); + +static struct event_constraint amd_fam19h_brs_pair_cntr0_constraint =3D + __EVENT_CONSTRAINT(0, 0x1, AMD64_RAW_EVENT_MASK, 1, 0, PERF_X86_EVENT_PAI= R); + +static struct event_constraint * +amd_get_event_constraints_f19h(struct cpu_hw_events *cpuc, int idx, + struct perf_event *event) +{ + struct hw_perf_event *hwc =3D &event->hw; + bool has_brs =3D has_amd_brs(hwc); + + /* + * In case BRS is used with an event requiring a counter pair, + * the kernel allows it but only on counter 0 & 1 to enforce + * multiplexing requiring to protect BRS in case of multiple + * BRS users + */ + if (amd_is_pair_event_code(hwc)) { + return has_brs ? &amd_fam19h_brs_pair_cntr0_constraint + : &pair_constraint; + } + + if (has_brs) + return &amd_fam19h_brs_cntr0_constraint; + + return &unconstrained; +} + + static ssize_t amd_event_sysfs_show(char *page, u64 config) { u64 event =3D (config & ARCH_PERFMON_EVENTSEL_EVENT) | @@ -905,12 +1077,19 @@ static ssize_t amd_event_sysfs_show(char *page, u64 = config) return x86_event_sysfs_show(page, config, event); } =20 +static void amd_pmu_sched_task(struct perf_event_context *ctx, + bool sched_in) +{ + if (sched_in && x86_pmu.lbr_nr) + amd_pmu_brs_sched_task(ctx, sched_in); +} + static __initconst const struct x86_pmu amd_pmu =3D { .name =3D "AMD", .handle_irq =3D amd_pmu_handle_irq, .disable_all =3D amd_pmu_disable_all, - .enable_all =3D x86_pmu_enable_all, - .enable =3D x86_pmu_enable_event, + .enable_all =3D amd_pmu_enable_all, + .enable =3D amd_pmu_enable_event, .disable =3D amd_pmu_disable_event, .hw_config =3D amd_pmu_hw_config, .schedule_events =3D x86_schedule_events, @@ -920,6 +1099,8 @@ static __initconst const struct x86_pmu amd_pmu =3D { .event_map =3D amd_pmu_event_map, .max_events =3D ARRAY_SIZE(amd_perfmon_event_map), .num_counters =3D AMD64_NUM_COUNTERS, + .add =3D amd_pmu_add_event, + .del =3D amd_pmu_del_event, .cntval_bits =3D 48, .cntval_mask =3D (1ULL << 48) - 1, .apic =3D 1, @@ -938,6 +1119,37 @@ static __initconst const struct x86_pmu amd_pmu =3D { .amd_nb_constraints =3D 1, }; =20 +static ssize_t branches_show(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu.lbr_nr); +} + +static DEVICE_ATTR_RO(branches); + +static struct attribute *amd_pmu_brs_attrs[] =3D { + &dev_attr_branches.attr, + NULL, +}; + +static umode_t +amd_brs_is_visible(struct kobject *kobj, struct attribute *attr, int i) +{ + return x86_pmu.lbr_nr ? attr->mode : 0; +} + +static struct attribute_group group_caps_amd_brs =3D { + .name =3D "caps", + .attrs =3D amd_pmu_brs_attrs, + .is_visible =3D amd_brs_is_visible, +}; + +static const struct attribute_group *amd_attr_update[] =3D { + &group_caps_amd_brs, + NULL, +}; + static int __init amd_core_pmu_init(void) { u64 even_ctr_mask =3D 0ULL; @@ -989,6 +1201,19 @@ static int __init amd_core_pmu_init(void) x86_pmu.flags |=3D PMU_FL_PAIR; } =20 + /* + * BRS requires special event constraints and flushing on ctxsw. + */ + if (boot_cpu_data.x86 >=3D 0x19 && !amd_brs_init()) { + x86_pmu.get_event_constraints =3D amd_get_event_constraints_f19h; + x86_pmu.sched_task =3D amd_pmu_sched_task; + /* + * put_event_constraints callback same as Fam17h, set above + */ + } + + x86_pmu.attr_update =3D amd_attr_update; + pr_cont("core perfctr, "); return 0; } diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index e686c5e0537b..c2a890caeb0a 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -1338,6 +1338,10 @@ static void x86_pmu_enable(struct pmu *pmu) if (hwc->state & PERF_HES_ARCH) continue; =20 + /* + * if cpuc->enabled =3D 0, then no wrmsr as + * per x86_pmu_enable_event() + */ x86_pmu_start(event, PERF_EF_RELOAD); } cpuc->n_added =3D 0; @@ -1704,11 +1708,15 @@ int x86_pmu_handle_irq(struct pt_regs *regs) * event overflow */ handled++; - perf_sample_data_init(&data, 0, event->hw.last_period); =20 if (!x86_perf_event_set_period(event)) continue; =20 + perf_sample_data_init(&data, 0, event->hw.last_period); + + if (has_branch_stack(event)) + data.br_stack =3D &cpuc->lbr_stack; + if (perf_event_overflow(event, &data, regs)) x86_pmu_stop(event, 0); } diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 150261d929b9..3485a4cf0241 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -67,22 +67,23 @@ static inline bool constraint_match(struct event_constr= aint *c, u64 ecode) /* * struct hw_perf_event.flags flags */ -#define PERF_X86_EVENT_PEBS_LDLAT 0x0001 /* ld+ldlat data address sampling= */ -#define PERF_X86_EVENT_PEBS_ST 0x0002 /* st data address sampling */ -#define PERF_X86_EVENT_PEBS_ST_HSW 0x0004 /* haswell style datala, store */ -#define PERF_X86_EVENT_PEBS_LD_HSW 0x0008 /* haswell style datala, load */ -#define PERF_X86_EVENT_PEBS_NA_HSW 0x0010 /* haswell style datala, unknown= */ -#define PERF_X86_EVENT_EXCL 0x0020 /* HT exclusivity on counter */ -#define PERF_X86_EVENT_DYNAMIC 0x0040 /* dynamic alloc'd constraint */ - -#define PERF_X86_EVENT_EXCL_ACCT 0x0100 /* accounted EXCL event */ -#define PERF_X86_EVENT_AUTO_RELOAD 0x0200 /* use PEBS auto-reload */ -#define PERF_X86_EVENT_LARGE_PEBS 0x0400 /* use large PEBS */ -#define PERF_X86_EVENT_PEBS_VIA_PT 0x0800 /* use PT buffer for PEBS */ -#define PERF_X86_EVENT_PAIR 0x1000 /* Large Increment per Cycle */ -#define PERF_X86_EVENT_LBR_SELECT 0x2000 /* Save/Restore MSR_LBR_SELECT */ -#define PERF_X86_EVENT_TOPDOWN 0x4000 /* Count Topdown slots/metrics even= ts */ -#define PERF_X86_EVENT_PEBS_STLAT 0x8000 /* st+stlat data address sampling= */ +#define PERF_X86_EVENT_PEBS_LDLAT 0x00001 /* ld+ldlat data address samplin= g */ +#define PERF_X86_EVENT_PEBS_ST 0x00002 /* st data address sampling */ +#define PERF_X86_EVENT_PEBS_ST_HSW 0x00004 /* haswell style datala, store = */ +#define PERF_X86_EVENT_PEBS_LD_HSW 0x00008 /* haswell style datala, load */ +#define PERF_X86_EVENT_PEBS_NA_HSW 0x00010 /* haswell style datala, unknow= n */ +#define PERF_X86_EVENT_EXCL 0x00020 /* HT exclusivity on counter */ +#define PERF_X86_EVENT_DYNAMIC 0x00040 /* dynamic alloc'd constraint */ + +#define PERF_X86_EVENT_EXCL_ACCT 0x00100 /* accounted EXCL event */ +#define PERF_X86_EVENT_AUTO_RELOAD 0x00200 /* use PEBS auto-reload */ +#define PERF_X86_EVENT_LARGE_PEBS 0x00400 /* use large PEBS */ +#define PERF_X86_EVENT_PEBS_VIA_PT 0x00800 /* use PT buffer for PEBS */ +#define PERF_X86_EVENT_PAIR 0x01000 /* Large Increment per Cycle */ +#define PERF_X86_EVENT_LBR_SELECT 0x02000 /* Save/Restore MSR_LBR_SELECT */ +#define PERF_X86_EVENT_TOPDOWN 0x04000 /* Count Topdown slots/metrics eve= nts */ +#define PERF_X86_EVENT_PEBS_STLAT 0x08000 /* st+stlat data address samplin= g */ +#define PERF_X86_EVENT_AMD_BRS 0x10000 /* AMD Branch Sampling */ =20 static inline bool is_topdown_count(struct perf_event *event) { @@ -325,6 +326,8 @@ struct cpu_hw_events { * AMD specific bits */ struct amd_nb *amd_nb; + int brs_active; /* BRS is enabled */ + /* Inverted mask of bits to clear in the perf_ctr ctrl registers */ u64 perf_ctr_virt_mask; int n_pair; /* Large increment events */ @@ -1105,6 +1108,11 @@ int x86_pmu_hw_config(struct perf_event *event); =20 void x86_pmu_disable_all(void); =20 +static inline bool has_amd_brs(struct hw_perf_event *hwc) +{ + return hwc->flags & PERF_X86_EVENT_AMD_BRS; +} + static inline bool is_counter_pair(struct hw_perf_event *hwc) { return hwc->flags & PERF_X86_EVENT_PAIR; @@ -1210,6 +1218,50 @@ static inline bool fixed_counter_disabled(int i, str= uct pmu *pmu) #ifdef CONFIG_CPU_SUP_AMD =20 int amd_pmu_init(void); +int amd_brs_init(void); +void amd_brs_disable(void); +void amd_brs_enable(void); +void amd_brs_enable_all(void); +void amd_brs_disable_all(void); +void amd_brs_drain(void); +void amd_brs_disable_all(void); +int amd_brs_setup_filter(struct perf_event *event); +void amd_brs_reset(void); + +static inline void amd_pmu_brs_add(struct perf_event *event) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + + perf_sched_cb_inc(event->ctx->pmu); + cpuc->lbr_users++; + /* + * No need to reset BRS because it is reset + * on brs_enable() and it is saturating + */ +} + +static inline void amd_pmu_brs_del(struct perf_event *event) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + + cpuc->lbr_users--; + WARN_ON_ONCE(cpuc->lbr_users < 0); + + perf_sched_cb_dec(event->ctx->pmu); +} + +void amd_pmu_brs_sched_task(struct perf_event_context *ctx, bool sched_in); + +/* + * check if BRS is activated on the CPU + * active defined as it has non-zero users and DBG_EXT_CFG.BRSEN=3D1 + */ +static inline bool amd_brs_active(void) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + + return cpuc->brs_active; +} =20 #else /* CONFIG_CPU_SUP_AMD */ =20 @@ -1218,6 +1270,23 @@ static inline int amd_pmu_init(void) return 0; } =20 +static inline int amd_brs_init(void) +{ + return 0; +} + +static inline void amd_brs_drain(void) +{ +} + +static inline void amd_brs_enable_all(void) +{ +} + +static inline void amd_brs_disable_all(void) +{ +} + #endif /* CONFIG_CPU_SUP_AMD */ =20 static inline int is_pebs_pt(struct perf_event *event) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-in= dex.h index 87f80f0e5259..0179c72e829a 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -688,6 +688,10 @@ #define MSR_IA32_PERF_CTL 0x00000199 #define INTEL_PERF_CTL_MASK 0xffff =20 +/* AMD Branch Sampling configuration */ +#define MSR_AMD_DBG_EXTN_CFG 0xc000010f +#define MSR_AMD_SAMP_BR_FROM 0xc0010300 + #define MSR_IA32_MPERF 0x000000e7 #define MSR_IA32_APERF 0x000000e8 =20 --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 772F4C433EF for ; Tue, 22 Mar 2022 22:15:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237742AbiCVWRT (ORCPT ); Tue, 22 Mar 2022 18:17:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53128 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237621AbiCVWRF (ORCPT ); Tue, 22 Mar 2022 18:17:05 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A48353A44 for ; Tue, 22 Mar 2022 15:15:36 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id w1-20020a5b08c1000000b00633be107f28so4650407ybq.4 for ; Tue, 22 Mar 2022 15:15:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=SbI28V3sKLSa4XoImm+sfIA9Q4EtRHUUKQBKqzRI7DY=; b=DTSsjBhp5gYYpEzRMYZjo1IxELiQU46lI4846oN1VTD5AoO0wUANZAeEzy98aM+AZJ HX3uctWKzV5DexeN8XQ3JT30wXgLQmW5i7kUTPy4OEEV4RnBdqEP62VncCRhzvFQxbNW p4h4X0Jonj5IszUCjmXkKcbBp70WzW8Fk4Ju/jhMGfltnPSLp/RK8i/elAzGDAqoOtyo feGwk+nIswbQB2anC/ZqAoA8VO1eJlCyBjcxVcHGci7gLPDDgabV2RAOzH7oynwmCmcY rKJ+tXWRv80B7KvSftznyU8MmnRXAnjVtdGAjiSELU6MLLtTZYNNbV6BTCd3C4jiLbeo BXfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=SbI28V3sKLSa4XoImm+sfIA9Q4EtRHUUKQBKqzRI7DY=; b=EVIY28H3q7Mwng7WmeByq4ASCuje5vf4aqFVk1jt8d0hK8U1imBhovajFQeYLMd3uI a013TKyYSQ4CGtcgGUSPP8PLfuHt7Ni5cPYwlqwoRSDUlVHWdqh19PaU0qI+c7KWf0rP Ec9A23OQOB/kYZTY95iIOMZmhbG7/+crY8V8iPJOX21uiKW0CJKcsfHUEMT/14X/Mcgr kCypyf5K8Tn5ygPYO5uQxDFrMGv8euqaaV6toO4MiXpusAXBfJjKmGjWI2DbdMrzM+YH Jj3V6prImSUN+8Xfw7kTvVXSrUssqWavOUSmyc7wwsPUeMReGpUIbdXT/ueCVmnwPtsT xUJA== X-Gm-Message-State: AOAM533YOEiOkXzccZKP5iW0+Q3V+4WaRmq8kqm51RjVLyugZ0tD/MmB ic0Rryx3s02fkX+dENgrW5oXZIYJU4Uol4+X7U1CFlUvhNbuJjjEaGVebeKUkVx78bFePH3BSGK jiGv11JrLllI8dlVbXDXqsg4ejWPyCJdIvIBSBGzqQzgaw+AWJTbQQE8vIzsWEjOlP8MkNeYx X-Google-Smtp-Source: ABdhPJzzv2CTC+EpZ16zirkZ23P+0poq/22QQ+iK1T3zJntMo1771uM4p0PDBfElPR7fZy8uQ9ZUB8wX2931 X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a25:f506:0:b0:628:9da9:cf44 with SMTP id a6-20020a25f506000000b006289da9cf44mr29522401ybe.595.1647987335151; Tue, 22 Mar 2022 15:15:35 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:08 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-5-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 04/13] perf/x86/amd: add branch-brs helper event for Fam19h BRS From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a pseudo event called branch-brs to help use the FAM Fam19h Branch Sampling feature (BRS). BRS samples taken branches, so it is best us= ed when sampling on a retired taken branch event (0xc4) which is what BRS captures. Instead of trying to remember the event code or actual event nam= e, users can simply do: $ perf record -b -e cpu/branch-brs/ -c 1000037 ..... Signed-off-by: Stephane Eranian --- arch/x86/events/amd/core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index c7ac70d8ed9a..f7bce8364fe4 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -1145,8 +1145,23 @@ static struct attribute_group group_caps_amd_brs =3D= { .is_visible =3D amd_brs_is_visible, }; =20 +EVENT_ATTR_STR(branch-brs, amd_branch_brs, + "event=3D" __stringify(AMD_FAM19H_BRS_EVENT)"\n"); + +static struct attribute *amd_brs_events_attrs[] =3D { + EVENT_PTR(amd_branch_brs), + NULL, +}; + +static struct attribute_group group_events_amd_brs =3D { + .name =3D "events", + .attrs =3D amd_brs_events_attrs, + .is_visible =3D amd_brs_is_visible, +}; + static const struct attribute_group *amd_attr_update[] =3D { &group_caps_amd_brs, + &group_events_amd_brs, NULL, }; =20 --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5DB51C433EF for ; Tue, 22 Mar 2022 22:15:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237724AbiCVWRO (ORCPT ); Tue, 22 Mar 2022 18:17:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237638AbiCVWRH (ORCPT ); Tue, 22 Mar 2022 18:17:07 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1A8553B45 for ; Tue, 22 Mar 2022 15:15:38 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id c6-20020a621c06000000b004fa7307e2e0so7409636pfc.6 for ; Tue, 22 Mar 2022 15:15:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=xr6XYf8jb8sbPWyL/uYgYyRzO0ukjO2H3fyJviEcQXg=; b=rGalqej0UnCyQ05se0hm7gNO6QXvs6QeB1cZfj7jAd+Jr+SwvJzUHYJ5roglDEbXCJ 002Wlp1UQgVnPwhz/4tqCVbqBhi/f+Jgorx/odjWpzbabpQr6+eI6V1fBVgGyPfBdaMY TXYrKICh1pI9QUc0JfbvkaPsjwLjMYr7lTMg04UDiD9c/+AHkNorbxOPMrvHFdAulqjT Zvlzb57gEHzGDmMkX5xufPP9Cri6K3UeFUY0afY1IoJhOcPIF80HulEIs/s23NqrTBBv 90p5Ew2EKPpqXBTKrDzn7AHanshLC0rLfLUYZmYkctrZh7iFuSn77yD1Mfduyt2Tsg2b jyIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=xr6XYf8jb8sbPWyL/uYgYyRzO0ukjO2H3fyJviEcQXg=; b=cdIwL4JyB/absE1uTFsFbZVChRMoARhdxnBKnzyBQqOcD2wjpagUGrDgB542jaHPcp j+3WLHZO8Vp6JkAWus6rC0PVNv7tVOROlD1cet8JFIleXcQiedDd8QnzfdIdbOu5nDw8 aYeA6FoKVL57509/W5cOuvW74B2jOF8d/NKSa0DKsVT/eqb5f17akF0RC/HNBrMjoqgs EpPwoYtMCUBB9bfVlilN+UfDilh8qvdX3ghBYlszb8g28ehSuriQNj4bG9WEsbvb66Yf t8Q5UGid8cZPifFMxVdvuOPuUGuAkI1kOE/ULK93hmWDyybLE+Bm4pEFRqXp4NEGN/Sa x1Gg== X-Gm-Message-State: AOAM531SyCWdo++uufuEEVoOI4Vs3BdeCPmvefEO+5GPWpHiBoT2vHxK MCdbLpdk/Yp4d6XJIA54bIiw/i5F87sOdYvBn04GkMJD1kXk3TdtPa9pbfD0XqxWONZE7s23+e4 kH1kEsdNGXasIzMGs0axItjNwM7notwoCyTfSwVa82wexLhtkujMBzaYnFtlkuvUXoC5gABdW X-Google-Smtp-Source: ABdhPJwd9yM6lWfV46wsN89JqFFozvJBmep7JOnBfXXRCzFhjivuXQ9HOcb5Onpis8jt46RzPzdAXqbCwLqG X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:aa7:943a:0:b0:4f6:adc9:d741 with SMTP id y26-20020aa7943a000000b004f6adc9d741mr30858044pfo.30.1647987337937; Tue, 22 Mar 2022 15:15:37 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:09 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-6-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 05/13] perf/x86/amd: enable branch sampling priv level filtering From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The AMD Branch Sampling features does not provide hardware filtering by privilege level. The associated PMU counter does but not the branch sampling by itself. Given how BRS operates there is a possibility that BRS captures kernel level branches even though the event is programmed to count only at the user level. Implement a workaround in software by removing the branches which belong to the wrong privilege level. The privilege level is evaluated on the target of the branch and not the source so as to be compatible with other architectur= es. As a consequence of this patch, the number of entries in the PERF_RECORD_BRANCH_STACK buffer may be less than the maximum (16). It could even be zero. Another consequence is that consecutive entries in the branch stack may not reflect actual code path and may have discontinuities, in case kernel branches were suppressed. But this is no different than what happens on other architectures. Signed-off-by: Stephane Eranian --- arch/x86/events/amd/brs.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/x86/events/amd/brs.c b/arch/x86/events/amd/brs.c index 3c13c484c637..40461c3ce714 100644 --- a/arch/x86/events/amd/brs.c +++ b/arch/x86/events/amd/brs.c @@ -92,10 +92,6 @@ int amd_brs_setup_filter(struct perf_event *event) if ((type & ~PERF_SAMPLE_BRANCH_PLM_ALL) !=3D PERF_SAMPLE_BRANCH_ANY) return -EINVAL; =20 - /* can only capture at all priv levels due to the way BRS works */ - if ((type & PERF_SAMPLE_BRANCH_PLM_ALL) !=3D PERF_SAMPLE_BRANCH_PLM_ALL) - return -EINVAL; - return 0; } =20 @@ -195,6 +191,21 @@ void amd_brs_disable_all(void) amd_brs_disable(); } =20 +static bool amd_brs_match_plm(struct perf_event *event, u64 to) +{ + int type =3D event->attr.branch_sample_type; + int plm_k =3D PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV; + int plm_u =3D PERF_SAMPLE_BRANCH_USER; + + if (!(type & plm_k) && kernel_ip(to)) + return 0; + + if (!(type & plm_u) && !kernel_ip(to)) + return 0; + + return 1; +} + /* * Caller must ensure amd_brs_inuse() is true before calling * return: @@ -252,8 +263,6 @@ void amd_brs_drain(void) if (to =3D=3D BRS_POISON) break; =20 - rdmsrl(brs_from(brs_idx), from); - /* * Sign-extend SAMP_BR_TO to 64 bits, bits 61-63 are reserved. * Necessary to generate proper virtual addresses suitable for @@ -261,6 +270,11 @@ void amd_brs_drain(void) */ to =3D (u64)(((s64)to << shift) >> shift); =20 + if (!amd_brs_match_plm(event, to)) + continue; + + rdmsrl(brs_from(brs_idx), from); + perf_clear_branch_entry_bitfields(br+nr); =20 br[nr].from =3D from; --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C493C433EF for ; Tue, 22 Mar 2022 22:16:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237704AbiCVWR0 (ORCPT ); Tue, 22 Mar 2022 18:17:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237696AbiCVWRK (ORCPT ); Tue, 22 Mar 2022 18:17:10 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 177EB5370C for ; Tue, 22 Mar 2022 15:15:41 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id h16-20020a056902009000b00628a70584b2so15494833ybs.6 for ; Tue, 22 Mar 2022 15:15:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=rjDM4PZxQVnGsW8D6ZRUNvFtAvJliadKtjfByZf01o0=; b=JkuuGgSvC6W5z4yYL1/b9HdlCLYiUXwRQRC5UyKU13aVKsMav/zd2hTZwzFQWxezAU vb1VUUPu0wjVanlY5/XuggY99TEpTxETb4C7qWfPFYilicVrRGUcn+VdP1m5JYDXN0jx qag8N+JDE1MqrY1aEDVRjfjjtk2mMZ7kOD/hr+y4oqrYhCFJg3XZ4H+YuQH2IgOBpZui WVh258SKoUbt/dYevxp92eb23Tvo4/2gC+uLrhzwkkoeyC2rEAGXTG6ESz5n+FhpPcwE Dz6lnPJn6FBw5zLuFIyn+KCIcj/hymZxm6C2dpYbyTnNL/cGx8/LbxCmcA4nkpn9bsxx rItA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=rjDM4PZxQVnGsW8D6ZRUNvFtAvJliadKtjfByZf01o0=; b=bOU7dvcYWP584svdr7qCtfLr3r7ezAJcBApTwdzCuewsudtu3pfOCpGt3T1NfouErQ Sglui3SmHggCE/XteX+sl/AFyZ9yUt/SuY2u71ujZPOixG0V/p0ZrzQ10iSyc9O5CPtq nxRDG4vdd+MwZryxOpwWHCFcHyGgLDBqb1yk7orJAhTAdQgmsf8aV6ExPe/ncVxkZWai nM93kYgy9qMK7oepAF8B65JqZknAZp131lN9sgRqJUAkME8QEzWpiVbUrmeWqLJkFsp+ kP7pk+uybj02vN3gM2SCcakA3e5oi/EunKbrldGUo7E8lrN9WxTFyz6Bbh7gJje/6rco olmg== X-Gm-Message-State: AOAM530sPJmeRQ5eEVRiwQdL/4lZ0ySFLgcN68uc7QhUrEYyKvRk20FX asKGK6U7ttI9EE6/pl4Tr9LKH+V6uC1PlL4i4juNB3x5L7+uDzxAdy//5b9/mqoVQ9oBzmHdA+v wNzF1umT2QwMbJVr8dYXrTaVof+o+nHgMly1Mapi4fV/gU2PhCwfWuhQCKrMzT51j+IS0Thiy X-Google-Smtp-Source: ABdhPJy2169MxJ6wk/bRojYugdoldDuP5WWPT/h2dbIbJ2zV2sHAvMwofe9TGpX72Wqtl9w/BJ8w+KU496DH X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a0d:c6c4:0:b0:2d6:f343:fa99 with SMTP id i187-20020a0dc6c4000000b002d6f343fa99mr31888711ywd.142.1647987340238; Tue, 22 Mar 2022 15:15:40 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:10 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-7-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 06/13] perf/x86/amd: add AMD branch sampling period adjustment From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add code to adjust the sampling event period when used with the Branch Sampling feature (BRS). Given the depth of the BRS (16), the period is reduced by that depth such that in the best case scenario, BRS saturates at the desired sampling period. In practice, though, the processor may execute more branches. Given a desired period P and a depth D, the kernel programs the actual period at P - D. After P occurrences of the sampling event, the counter overflows. It then may take X branches (skid) before the NMI is caught and held by the hardware and BRS activates. Then, after D branches, BRS saturates and the NMI is delivered. With no skid, the effective period would be (P - D) + D =3D P. In practice, however, it will likely be (P - D)= + X + D. There is no way to eliminate X or predict X. Signed-off-by: Stephane Eranian --- arch/x86/events/core.c | 7 +++++++ arch/x86/events/perf_event.h | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index c2a890caeb0a..ed285f640efe 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -1374,6 +1374,13 @@ int x86_perf_event_set_period(struct perf_event *eve= nt) x86_pmu.set_topdown_event_period) return x86_pmu.set_topdown_event_period(event); =20 + /* + * decrease period by the depth of the BRS feature to get + * the last N taken branches and approximate the desired period + */ + if (has_branch_stack(event)) + period =3D amd_brs_adjust_period(period); + /* * If we are way outside a reasonable range then just skip forward: */ diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 3485a4cf0241..25b037b571e4 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1263,6 +1263,14 @@ static inline bool amd_brs_active(void) return cpuc->brs_active; } =20 +static inline s64 amd_brs_adjust_period(s64 period) +{ + if (period > x86_pmu.lbr_nr) + return period - x86_pmu.lbr_nr; + + return period; +} + #else /* CONFIG_CPU_SUP_AMD */ =20 static inline int amd_pmu_init(void) @@ -1287,6 +1295,10 @@ static inline void amd_brs_disable_all(void) { } =20 +static inline s64 amd_brs_adjust_period(s64 period) +{ + return period; +} #endif /* CONFIG_CPU_SUP_AMD */ =20 static inline int is_pebs_pt(struct perf_event *event) --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A975C433EF for ; Tue, 22 Mar 2022 22:16:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237891AbiCVWRc (ORCPT ); Tue, 22 Mar 2022 18:17:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53748 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237675AbiCVWRN (ORCPT ); Tue, 22 Mar 2022 18:17:13 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 880BC53706 for ; Tue, 22 Mar 2022 15:15:43 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id h8-20020a25e208000000b00628c0565607so15577721ybe.0 for ; Tue, 22 Mar 2022 15:15:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7qNmmGdeOZfhSMOT7dCrcgJQwc8RsaRFAUQUg+lLang=; b=GE1fkQSG5UPK9yaBOk8BPYrtG1GL8BXl7+NGttFKQ+cJthceRepKDcVxfFWEaRfBE1 ckAsenBftKkABGhW8mB/aFrSW5uuFKtXbpWgc+lkS/U6/63xgfI647u25IUL4QyWtp0w u4Wqdi2ME2dL+fcdFhqZbbrYfyOl9U8sXqjBjnfdY/3LPgOPlBttyh60cnhBDqzPiy4V VTqrMTzlL9mbzIW7zp6/ZYLqg6DW69rmremv8XduyMKHRoey18L8TU2uf03n/nFVOEFy WR0vuADpZInZrg3IN8ZjrT/e8TcWEHNFUjZ7lmHDEo553wPhnhetbOn8WiR+DlJ71ZK0 u6xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7qNmmGdeOZfhSMOT7dCrcgJQwc8RsaRFAUQUg+lLang=; b=LWGrFTO/rudNfNop5jaEKhIt56zFd8qUfqBkebF58J+i78hkwoevZSpgza+zU1LPFG f+rGZq8ri0F46CDnksv6OoUwnziWsmAPWHX4LZxMdxZ8b7Num6dudwL4XRCuPv2hlVIB BWY+AHfUTw4mCcljOc+XvhzNp8+HUUEwzoWZReq4OmQtkhYPqy+fZt5VtiO0pw/xlDIi gDVCyoLlMbLhTjtdD8JRUKTQFE5bMfFgzkabXCj2IXcJzCaVwzoj/k4yn7yh+ByZ1eR3 LhVdFwzLbFNPeGrKLRW8cjTxR45VgpIQKZOX5RxcRfWkiJDMaDDis0HwP+3AhW/7/8eM e+UQ== X-Gm-Message-State: AOAM531IV+RI6Q7+LSwJ5p3Z0nyYgLhoFI6Hg9HmejnC6F4quR/buTI3 6Nv+sOuwDVb8VB7N87blWfPssPpWJtXXfMpOLDOKU658cJKFl2zNrW+wZJCwIjwJ9aapf/L6xNW LzwMZfBjm4gbf4RICs8epHxWE6DY9Ps8I6eQUWYnVxxVSsHqo/bhOeVfAEwydxNq0XBHkRYMz X-Google-Smtp-Source: ABdhPJwhoiDQ88LuSGeOkBVk+NzZlC9VxWnNNrRnEvUWD7IUchPhBkAD0OGNSHEQzq1JWSkKFrnM91nBN9FZ X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a25:c58b:0:b0:629:5064:894c with SMTP id v133-20020a25c58b000000b006295064894cmr29761335ybe.590.1647987342642; Tue, 22 Mar 2022 15:15:42 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:11 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-8-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 07/13] perf/x86/amd: make Zen3 branch sampling opt-in From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a kernel config option CONFIG_PERF_EVENTS_AMD_BRS to make the support for AMD Zen3 Branch Sampling (BRS) an opt-in compile time option. Signed-off-by: Stephane Eranian --- arch/x86/events/Kconfig | 8 ++++++ arch/x86/events/amd/Makefile | 3 ++- arch/x86/events/perf_event.h | 49 ++++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/arch/x86/events/Kconfig b/arch/x86/events/Kconfig index d6cdfe631674..09c56965750a 100644 --- a/arch/x86/events/Kconfig +++ b/arch/x86/events/Kconfig @@ -44,4 +44,12 @@ config PERF_EVENTS_AMD_UNCORE =20 To compile this driver as a module, choose M here: the module will be called 'amd-uncore'. + +config PERF_EVENTS_AMD_BRS + depends on PERF_EVENTS && CPU_SUP_AMD + bool "AMD Zen3 Branch Sampling support" + help + Enable AMD Zen3 branch sampling support (BRS) which samples up to + 16 consecutive taken branches in registers. + endmenu diff --git a/arch/x86/events/amd/Makefile b/arch/x86/events/amd/Makefile index cf323ffab5cd..b9f5d4610256 100644 --- a/arch/x86/events/amd/Makefile +++ b/arch/x86/events/amd/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CPU_SUP_AMD) +=3D core.o brs.o +obj-$(CONFIG_CPU_SUP_AMD) +=3D core.o +obj-$(CONFIG_PERF_EVENTS_AMD_BRS) +=3D brs.o obj-$(CONFIG_PERF_EVENTS_AMD_POWER) +=3D power.o obj-$(CONFIG_X86_LOCAL_APIC) +=3D ibs.o obj-$(CONFIG_PERF_EVENTS_AMD_UNCORE) +=3D amd-uncore.o diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 25b037b571e4..4d050579dcbd 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1218,6 +1218,8 @@ static inline bool fixed_counter_disabled(int i, stru= ct pmu *pmu) #ifdef CONFIG_CPU_SUP_AMD =20 int amd_pmu_init(void); + +#ifdef CONFIG_PERF_EVENTS_AMD_BRS int amd_brs_init(void); void amd_brs_disable(void); void amd_brs_enable(void); @@ -1252,25 +1254,52 @@ static inline void amd_pmu_brs_del(struct perf_even= t *event) =20 void amd_pmu_brs_sched_task(struct perf_event_context *ctx, bool sched_in); =20 -/* - * check if BRS is activated on the CPU - * active defined as it has non-zero users and DBG_EXT_CFG.BRSEN=3D1 - */ -static inline bool amd_brs_active(void) +static inline s64 amd_brs_adjust_period(s64 period) { - struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + if (period > x86_pmu.lbr_nr) + return period - x86_pmu.lbr_nr; =20 - return cpuc->brs_active; + return period; +} +#else +static inline int amd_brs_init(void) +{ + return 0; } +static inline void amd_brs_disable(void) {} +static inline void amd_brs_enable(void) {} +static inline void amd_brs_drain(void) {} +static inline void amd_brs_lopwr_init(void) {} +static inline void amd_brs_disable_all(void) {} +static inline int amd_brs_setup_filter(struct perf_event *event) +{ + return 0; +} +static inline void amd_brs_reset(void) {} =20 -static inline s64 amd_brs_adjust_period(s64 period) +static inline void amd_pmu_brs_add(struct perf_event *event) { - if (period > x86_pmu.lbr_nr) - return period - x86_pmu.lbr_nr; +} + +static inline void amd_pmu_brs_del(struct perf_event *event) +{ +} + +static inline void amd_pmu_brs_sched_task(struct perf_event_context *ctx, = bool sched_in) +{ +} =20 +static inline s64 amd_brs_adjust_period(s64 period) +{ return period; } =20 +static inline void amd_brs_enable_all(void) +{ +} + +#endif + #else /* CONFIG_CPU_SUP_AMD */ =20 static inline int amd_pmu_init(void) --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 17F52C433EF for ; Tue, 22 Mar 2022 22:16:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237696AbiCVWRi (ORCPT ); Tue, 22 Mar 2022 18:17:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54550 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237780AbiCVWRY (ORCPT ); Tue, 22 Mar 2022 18:17:24 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0DCE7546B2 for ; Tue, 22 Mar 2022 15:15:45 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2e5bcae3665so133049267b3.16 for ; Tue, 22 Mar 2022 15:15:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=x5KPGBSUSbYd8r6Fxn0mzFbKXE7+7xB0auo11QNIbWU=; b=QLdsZED2n4IqW8UKETQ8GKP2zRviwfaK8u+UJCNNX/EOS5b5PRE4DBTaE2edFLbtV7 AJUk6+u1351fvM95T4Rk6c7p1Nm4K+AR5LoufJBbvGzLsXNQB54gQjTjBogO5ZtluMu4 nFNONXZzu469cpjKIJiIpFauUQ1OMOgDwnyrWAO+XIVE9/y4joINUlrLxn0FkynJcX0E 9ziIMHvJE5PaVIOOuyT8Li4D2jEuezPz3qrNgtA/e6L11x4lX2EZHY3I/niv5HuFCPq8 xsd3+S1IIQn/oFYWLHuCbT8s4H1ADuf76irwyeDYRXa1K+R21u3EDa7geMqAkbNFlZwI FazA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=x5KPGBSUSbYd8r6Fxn0mzFbKXE7+7xB0auo11QNIbWU=; b=beCu3PCRVfuIlySbZCyn93Ow55lbG7C0YO/fBxGfKbld3k7XtZmVhwWhoO3bxq5euq svh2ianrjww7H0hOSUyaf41c3kkdNqPlLEXedi7JBvAdGbcAFclZ7xYRQg6v08EXwNvk JwMl/Tq0xYeUE2qHjvJBLaB0kj5pIKd7im5KTBUEESUfc/dEtfATe3Dsix2dw/URacss WS9ieXOFAfpO2H4F/ouy4756GVCEaO7ovekb4PUz/xHiS8sSslKBmawVqhpsIqXMECxG cLGp2vHmD+JD/iUztLgVCQ5u8CZYR5j1RXIU1MyFhdmnA06CliDUx9ZkqxJgkRQLOMS+ qLYQ== X-Gm-Message-State: AOAM533tNzFYhK9kpuAQgUKsO9GD7Paiym5OeCUquDt3T4gvmcvRluIn mkpCJibMOclWLtICgXPy7xupbkM7awoRLWu+bW9h7UKC0Bb0PLrMs0VkU5lotvP/eMBnnX4pE7R XZt5ybsPCLkOFLx+kB1aQ5Vjk/wYebmyP7dkgX8KgZxJvlgHoVA+sUwXswElZUwiWhe1G35fD X-Google-Smtp-Source: ABdhPJzSL9g/xvSn9I3A0Fn3susXUMd/DqEzperr0Rp1LQzVJ6gC9KCObJzOOKppSekjWHIifoJvEeUd+zLZ X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a81:39d7:0:b0:2e5:2b46:1963 with SMTP id g206-20020a8139d7000000b002e52b461963mr31224365ywa.372.1647987345029; Tue, 22 Mar 2022 15:15:45 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:12 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-9-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 08/13] ACPI: add perf low power callback From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add an optional callback needed by some PMU features, e.g., AMD BRS, to give a chance to the perf_events code to change its state before a CPU goes to low power and after it comes back. The callback is void when the PERF_NEEDS_LOPWR_CB flag is not set. This flag must be set in arch specific perf_event.h header whenever needed. When not set, there is no impact on the ACPI code. Signed-off-by: Stephane Eranian --- drivers/acpi/acpi_pad.c | 6 ++++++ drivers/acpi/processor_idle.c | 5 +++++ include/linux/perf_event.h | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index f45979aa2d64..a306a07a60b5 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -164,6 +164,9 @@ static int power_saving_thread(void *data) tsc_marked_unstable =3D 1; } local_irq_disable(); + + perf_lopwr_cb(true); + tick_broadcast_enable(); tick_broadcast_enter(); stop_critical_timings(); @@ -172,6 +175,9 @@ static int power_saving_thread(void *data) =20 start_critical_timings(); tick_broadcast_exit(); + + perf_lopwr_cb(false); + local_irq_enable(); =20 if (time_before(expire_time, jiffies)) { diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f8e9fa82cb9b..f83596960d9a 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -21,6 +21,7 @@ #include #include #include +#include #include =20 /* @@ -549,6 +550,8 @@ static void wait_for_freeze(void) */ static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx) { + perf_lopwr_cb(true); + if (cx->entry_method =3D=3D ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cx); @@ -559,6 +562,8 @@ static void __cpuidle acpi_idle_do_entry(struct acpi_pr= ocessor_cx *cx) inb(cx->address); wait_for_freeze(); } + + perf_lopwr_cb(false); } =20 /** diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 496eb6aa6e54..1b98e46588bc 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1676,4 +1676,10 @@ typedef int (perf_snapshot_branch_stack_t)(struct pe= rf_branch_entry *entries, unsigned int cnt); DECLARE_STATIC_CALL(perf_snapshot_branch_stack, perf_snapshot_branch_stack= _t); =20 +#ifndef PERF_NEEDS_LOPWR_CB +static inline void perf_lopwr_cb(bool mode) +{ +} +#endif + #endif /* _LINUX_PERF_EVENT_H */ --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50FEFC433F5 for ; Tue, 22 Mar 2022 22:16:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237805AbiCVWRm (ORCPT ); Tue, 22 Mar 2022 18:17:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53566 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237806AbiCVWRY (ORCPT ); Tue, 22 Mar 2022 18:17:24 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 742C654BD9 for ; Tue, 22 Mar 2022 15:15:48 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-2e5db04460cso107023327b3.17 for ; Tue, 22 Mar 2022 15:15:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ZQAAS74opi8sj3DsdS3WYbPGk9CAmygqU3vFxd41V8g=; b=V+8Arq7RPuNgR78gOc2Lgu0jG8uK8Q5I/dG5j+tMJq3wK7We+b3Pyxb9WBoD/mkyN4 Z51hmsYgbQdw+CV2cnJlEf/wqKaTBl2AqdDtTalFXign7/AgYpV+OLaBJ2D7ek2k4Jtk u7iDVBCPIkGmRRwdkFNWlhFZD7YSCN9q5+PhfHilKW3kOBAamvpMhgmHu8FzVDMI3KQz elvSfFzlWdlJjf6rkjUd0l8JSfjx6Tx9ibn3ymuMP1nLxF0Hku2suY/5BDG3UXLRYBJ0 Mts2OfT7o/+61dR16OIs9/nitAXIzS2s48QOYl1IkL11eD3VGiOqywl+JHmRxIS84Z5g X4Uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZQAAS74opi8sj3DsdS3WYbPGk9CAmygqU3vFxd41V8g=; b=GAwNQXP2hKR6sH99hmmGF7s5kZJsx0SNjA2XkJHLJG8FPOkhmejcjfvCLSw0X5KXau rspvYwCO8+jcEbrgicNRAlHkswuOVAnmcTGB/7qsgcHPeP1dx3JusskAYxrXX5NQyYCi 6eRUhhDdZtdDG69N4miKbQnWKyi6mE0hdDbVyhsul4OImfJuVzzD2QXUL70x6GIXP50s 8lE4g0ht+tQG9huEJAE0E6k0EjRXU49vBW51z1eTogguxhDoNrbSsan0UJfhmxx5sn1/ +MjF1iRPEufpnmF/RLu+601PO9M/xWjxN8hxYncI5GjwZNnppAteU/VxlotOt4mMhzQ2 fqPw== X-Gm-Message-State: AOAM5306RwhSDfNBRx9ttTl6weX71Q2sowFXiAUI/SohqfcXjr1NOhY5 YlIWA5iezannKqWWPvf9qlAOBNyLanZ/tNNI/llyLki6MAWroFCvpTIoHsvYjLcYeowpNjKmHSJ zPVRbte/yWDK1bhIZFqbmqnViv1DCi7fUXSIW0dk0akRxVDyR0ys9twwh6WlFVK7TlMR1HWuY X-Google-Smtp-Source: ABdhPJxRkohH32T3Vy8NMLmcvAC4ShJI4tOMfhoCBl6l0+MyCv0wQ6aE9Jo8WwCiF3YSAzK41a9gIkgEROkv X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a25:86cf:0:b0:633:8702:1bb3 with SMTP id y15-20020a2586cf000000b0063387021bb3mr29936265ybm.515.1647987347460; Tue, 22 Mar 2022 15:15:47 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:13 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-10-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 09/13] perf/x86/amd: add idle hooks for branch sampling From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On AMD Fam19h Zen3, the branch sampling (BRS) feature must be disabled befo= re entering low power and re-enabled (if was active) when returning from low power. Otherwise, the NMI interrupt may be held up for too long and cause problems. Stopping BRS will cause the NMI to be delivered if it was held up. Define a perf_amd_brs_lopwr_cb() callback to stop/restart BRS. The callback is protected by a jump label which is enabled only when AMD BRS is detected. In all other cases, the callback is never called. Signed-off-by: Stephane Eranian --- arch/x86/events/amd/brs.c | 32 +++++++++++++++++++++++++++++++ arch/x86/events/amd/core.c | 4 ++++ arch/x86/events/perf_event.h | 1 + arch/x86/include/asm/perf_event.h | 21 ++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/arch/x86/events/amd/brs.c b/arch/x86/events/amd/brs.c index 40461c3ce714..185a58cea917 100644 --- a/arch/x86/events/amd/brs.c +++ b/arch/x86/events/amd/brs.c @@ -7,6 +7,7 @@ * Contributed by Stephane Eranian */ #include +#include #include #include =20 @@ -329,3 +330,34 @@ void amd_pmu_brs_sched_task(struct perf_event_context = *ctx, bool sched_in) if (sched_in) amd_brs_poison_buffer(); } + +DEFINE_STATIC_KEY_FALSE(perf_lopwr_needed); + +/* + * called from ACPI processor_idle.c or acpi_pad.c + * with interrupts disabled + */ +void perf_amd_brs_lopwr_cb(bool lopwr_in) +{ + struct cpu_hw_events *cpuc =3D this_cpu_ptr(&cpu_hw_events); + union amd_debug_extn_cfg cfg; + + /* + * on mwait in, we may end up in non C0 state. + * we must disable branch sampling to avoid holding the NMI + * for too long. We disable it in hardware but we + * keep the state in cpuc, so we can re-enable. + * + * The hardware will deliver the NMI if needed when brsmen cleared + */ + if (cpuc->brs_active) { + cfg.val =3D get_debug_extn_cfg(); + cfg.brsmen =3D !lopwr_in; + set_debug_extn_cfg(cfg.val); + } +} + +void __init amd_brs_lopwr_init(void) +{ + static_branch_enable(&perf_lopwr_needed); +} diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index f7bce8364fe4..8e1e818f8195 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include #include #include #include @@ -1225,6 +1226,9 @@ static int __init amd_core_pmu_init(void) /* * put_event_constraints callback same as Fam17h, set above */ + + /* branch sampling must be stopped when entering low power */ + amd_brs_lopwr_init(); } =20 x86_pmu.attr_update =3D amd_attr_update; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 4d050579dcbd..2ed7bf5b51b1 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1226,6 +1226,7 @@ void amd_brs_enable(void); void amd_brs_enable_all(void); void amd_brs_disable_all(void); void amd_brs_drain(void); +void amd_brs_lopwr_init(void); void amd_brs_disable_all(void); int amd_brs_setup_filter(struct perf_event *event); void amd_brs_reset(void); diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_= event.h index 58d9e4b1fa0a..42753a9dc3ed 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -513,6 +513,27 @@ static inline void intel_pt_handle_vmx(int on) #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) extern void amd_pmu_enable_virt(void); extern void amd_pmu_disable_virt(void); + +#if defined(CONFIG_PERF_EVENTS_AMD_BRS) + +#define PERF_NEEDS_LOPWR_CB 1 + +/* + * architectural low power callback impacts + * drivers/acpi/processor_idle.c + * drivers/acpi/acpi_pad.c + */ +extern void perf_amd_brs_lopwr_cb(bool lopwr_in); +DECLARE_STATIC_KEY_FALSE(perf_lopwr_needed); + +static inline void perf_lopwr_cb(bool mode) +{ + /* key enabled only when BRS is available */ + if (static_branch_unlikely(&perf_lopwr_needed)) + perf_amd_brs_lopwr_cb(mode); +} +#endif /* PERF_NEEDS_LOPWR_CB */ + #else static inline void amd_pmu_enable_virt(void) { } static inline void amd_pmu_disable_virt(void) { } --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3296C433EF for ; Tue, 22 Mar 2022 22:16:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237865AbiCVWRq (ORCPT ); Tue, 22 Mar 2022 18:17:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237833AbiCVWRY (ORCPT ); Tue, 22 Mar 2022 18:17:24 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B530D54F92 for ; Tue, 22 Mar 2022 15:15:50 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id h16-20020a056902009000b00628a70584b2so15495073ybs.6 for ; Tue, 22 Mar 2022 15:15:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=v+NxYHkXHWjVO4PNbOTAVqrC0ZMmbKrhZhd7x0jggDI=; b=mE0EL6e1Fw7OYLCEfqt8cvrBe/km4//WG57F5jR3ixKkAeGSVpbuN+rmcVW60shPGL vHcxm9Vri8/G+NBRMZRnHjpSAbwrFqYbc75VDSVWjvkmTvGjJNq2FpQt5oGwqGxOfwiI feJUh5Gg1DNOhLJ1PVC3eqOrgyuR0rrah1mTac755l3/IApvS/za15epIAAoQ+gDFjNo PGbY3qhCBAtSob1yMh1eHEVyeT4YRFPa4hIASscSL4HMk0IS+SsSzRHRbLKgvykxIG7n ZeGQF28JO+uEijc/Eqq3gJTqiV7k7M54/iil2GaHsLn5ozpIuvzdcQ+eSkysxTTYYaK5 Ut8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=v+NxYHkXHWjVO4PNbOTAVqrC0ZMmbKrhZhd7x0jggDI=; b=px/yavcvo3FY+R9TPPsVaqjhxOQGNc9+cugo/is+MIeIPR1gSsRmZikCNm3q3kGgdW dhAZAjfETumtwh3fO9JkavTw2orPqlxWDYSoc1DbsQ/JB/w0EZgjgJGq8VH9/0pHsh++ 3OlxkDe1W5+mjR8jqK0BJFOQczH0K544GzO7QvKRRP2X1wwURj52FMVYTzfKXhLbEhBa QYKgHP4KbzT66UyxWjBoozROYV829KFuydjRkeuzA8nx6HXFUZy74GH3LPe8u7fW+DLb 5E1GmTxSGo5mvbcPGi6x9MwrXVIvSg5BnvuMMLk3DHTyNeZGBJcceGnhcNjJkSAUPNOl +FVw== X-Gm-Message-State: AOAM530U65r/8bxq7btLgE8qmAtWAFCIe+GPV61HS8PlM2hb1QN6+pkT VLQK0payHudCgzSM9jEHDevFSBjfCCPPz6m12JqglpusmhCiP/7TjGhkNEXtjHVZeY+dyeqPz1M SGFEYDBtjx3QWa/SmED+NxP5LLboYm8ehzYnSpNMhAAkKhhK0SK9pp/2x9hrhCkk5/WqRnjtQ X-Google-Smtp-Source: ABdhPJzaoT4iLrTHYsXveucSjrRohNyigHNWvS5bZcxQB9lNPVLB4vr7DBkPm0o/TeQRZwfVLLYoJ+z1APDN X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a5b:2ca:0:b0:634:3ebd:de88 with SMTP id h10-20020a5b02ca000000b006343ebdde88mr4660444ybp.33.1647987349834; Tue, 22 Mar 2022 15:15:49 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:14 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-11-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 10/13] perf tools: fix NULL point in evsel__env() From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" evsel_env() cannot return NULL. In case evsel->evlist->env is NULL default to perf_env. Fixes crashes in evsel__open_strerror() Signed-off-by: Ravi Bangoria Reviewed-by: Stephane Eranian --- tools/perf/util/evsel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 22d3267ce294..14b0e7ffa2c7 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2965,7 +2965,7 @@ int evsel__open_strerror(struct evsel *evsel, struct = target *target, =20 struct perf_env *evsel__env(struct evsel *evsel) { - if (evsel && evsel->evlist) + if (evsel && evsel->evlist && evsel->evlist->env) return evsel->evlist->env; return &perf_env; } --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72527C4332F for ; Tue, 22 Mar 2022 22:16:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238321AbiCVWR4 (ORCPT ); Tue, 22 Mar 2022 18:17:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237801AbiCVWR3 (ORCPT ); Tue, 22 Mar 2022 18:17:29 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12BC85370C for ; Tue, 22 Mar 2022 15:15:53 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 190-20020a2505c7000000b00629283fec72so15593011ybf.5 for ; Tue, 22 Mar 2022 15:15:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=2fFnNoJQ3H9hVlBp1UXUfdC5Kvmn9rISGKDSRRVelmI=; b=FeK8lZX/ROxlGZdXcfs3viVelDZve+bBs7HH6xjHv4eJzGcbkdJsHU3ntygvtCUVdv NkJDOEKDSVaTVVsIpTZvk2RI17GNfD/pBO6FMzyEfAAbKW81vTjR5OG4LDX28/UbGB7/ GwS0ShbbmF6ggSA0boU17tSlUhud+E45xsmvm2cLow8VusQXIHaREHjTh7IB91L018Kj 2l3o0VFKO2Nsot2yfkJ6lw7/CZXbVQeSRXc0FYiGtpKMxtpVSQgObgpjSNFtzlC+RA1A y5H4DxQtg+OLmsSv2AILaNhpYcEaomltUcM87D/LWfe6DNXBZ2T1iUBKz3sRh9N2mrmY tT2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=2fFnNoJQ3H9hVlBp1UXUfdC5Kvmn9rISGKDSRRVelmI=; b=A7FV1NgXXvmLSJoBqEa3NWG2ZRz1y8J8iu4lNMQOZEr5UNPOSYyLB94HKen0r7GiXv 1ihEeOs5gGpVjw0gtZy5rh+7d8W3h8QZexCT6XPetFe00IAdecjfN66ADFPGpwGuSYta EoCDqvfFlUtMlG3LCV5Pbfqpbn/zjPEeU8S2ZyrBgf7kjVRaxnPboyPX2Jpa+jLNPwNe Fsw3f/949xDn/2EiO+jfBRXwyQvZAdGS8BHK5VmZ2PG3uLpsxZmC0MzX/rWaDDs4tRmJ k7pNWCBZPrgFk7EM3Zd+5F0ZoQnt/6iyQna694FOPt5lBVl+qs3huBa4/TgncUsOGxPs eAbw== X-Gm-Message-State: AOAM5321/Kfn71b4OejGjQElFXZR6GowXZ7cXUlWo3c/wLpS+d5Zb+yz wK4d83TUq+aeoGCgHj9bzmoiYMpCYAg0DuwrsjVKBQpL/vCNPfNTPbXwxQcEGmIi81DELVWSgeI NCLE9/QH4cW2R7Y63W6Vj5v56WQerBK+el7QUED+OqPRDR17tc+ic+3wx8O+MVtxakFAuyLWf X-Google-Smtp-Source: ABdhPJw3TC+WRfnFqahAcvGue3nO6s3yog1WpVhe27t0TXbnHPo6u9I//9ZYQkF2rNY9FfXGVLe011cHC51i X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a25:3246:0:b0:633:af97:a3eb with SMTP id y67-20020a253246000000b00633af97a3ebmr25789591yby.274.1647987352324; Tue, 22 Mar 2022 15:15:52 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:15 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-12-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 11/13] perf tools: Improve IBS error handling From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kim Phillips improve the error message returned on failed perf_event_open() on AMD when using IBS. Output of executing 'perf record -e ibs_op// true' BEFORE this patch: The sys_perf_event_open() syscall returned with 22 (Invalid argument)for ev= ent (ibs_op//u). /bin/dmesg | grep -i perf may provide additional information. Output after: AMD IBS cannot exclude kernel events. Try running at a higher privilege le= vel. Output of executing 'sudo perf record -e ibs_op// true' BEFORE this patch: Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for e= vent (ibs_op//). /bin/dmesg | grep -i perf may provide additional information. Output after: Error: AMD IBS may only be available in system-wide/per-cpu mode. Try using -a, o= r -C and workload affinity Signed-off-by: Kim Phillips Cc: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Boris Ostrovsky Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Joao Martins Cc: Konrad Rzeszutek Wilk Cc: Mark Rutland Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Robert Richter Cc: Stephane Eranian Tested-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 14b0e7ffa2c7..e8ff7a4bd490 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2847,9 +2847,23 @@ static bool find_process(const char *name) return ret ? false : true; } =20 +static bool is_amd(const char *arch, const char *cpuid) +{ + return arch && !strcmp("x86", arch) && cpuid && strstarts(cpuid, "Authent= icAMD"); +} + +static bool is_amd_ibs(struct evsel *evsel) +{ + return evsel->core.attr.precise_ip + || (evsel->pmu_name && !strncmp(evsel->pmu_name, "ibs", 3)); +} + int evsel__open_strerror(struct evsel *evsel, struct target *target, int err, char *msg, size_t size) { + struct perf_env *env =3D evsel__env(evsel); + const char *arch =3D perf_env__arch(env); + const char *cpuid =3D perf_env__cpuid(env); char sbuf[STRERR_BUFSIZE]; int printed =3D 0, enforced =3D 0; =20 @@ -2949,6 +2963,17 @@ int evsel__open_strerror(struct evsel *evsel, struct= target *target, return scnprintf(msg, size, "Invalid event (%s) in per-thread mode, enable system wide with '-a'.", evsel__name(evsel)); + if (is_amd(arch, cpuid)) { + if (is_amd_ibs(evsel)) { + if (evsel->core.attr.exclude_kernel) + return scnprintf(msg, size, + "AMD IBS can't exclude kernel events. Try running at a higher privilege = level."); + if (!evsel->core.system_wide) + return scnprintf(msg, size, + "AMD IBS may only be available in system-wide/per-cpu mode. Try using -a= , or -C and workload affinity"); + } + } + break; case ENODATA: return scnprintf(msg, size, "Cannot collect data source with the load la= tency event alone. " --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 819DFC433FE for ; Tue, 22 Mar 2022 22:16:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238426AbiCVWR6 (ORCPT ); Tue, 22 Mar 2022 18:17:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237813AbiCVWR1 (ORCPT ); Tue, 22 Mar 2022 18:17:27 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F75953B5D for ; Tue, 22 Mar 2022 15:15:55 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2dbda4f6331so160960457b3.11 for ; Tue, 22 Mar 2022 15:15:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=6vrbVWZeWSTE7ExL6L9z77MiqrapvH5PS+af5bIC2bo=; b=pft1iLeDozdW+aGLGObBlQ4RXWkQkZNt/AsY15aagO6QDGpISgR1GoRUFWjmimQpCI fRq/a5H9rGLIKm9S7rd568cwUVCTUaL7lEYrFxKOLSawGaB8rmt5RyGel8F1ztJNEmmc PLCJdph2gEpJ7h8d4TD+frrZQBR8ThPqjgIIWcBRmRbBpqewd9rEupyPSTeIazmPO+sK DlIENIaLVp5nUcTO8BWpoNposDuU1CFUNw3oa0G3LqBHrsy0xFSJThxmbz8U/sAwl6Hn pz36XeZxDVrgpI8Ow4AvNe6N3dxUeFvOpqdRxK+0v8EV59YXOUa2xA56v54taPBKYNFs cAhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=6vrbVWZeWSTE7ExL6L9z77MiqrapvH5PS+af5bIC2bo=; b=VUoiqwTTWHDIGJHWIcCK0WqASHV/hFX+5QFb/HoZ7Xz+MJHSxXq0mBMG42eupowuKq 7amJqllWI+0fbt2zxwVd6cnMb/5VBW4XMHOqtN9fRxTiW0CKqPmRz8TODXRwuMn/Q4Jb SxHFbyJ4txPNfzlEGt8rkhFM7oFDORQLMMePoUQ05DykMNyMRwAI2YP5/nrks9VxPB2j HPTTz3OrYcej5HrM9ZeXHQNefalaAHPL+3MC/DnITJOwAWIr8FpfIm/k8dwWAl5WYfBu dkF5114dN74llwFZMfhD9eOVfYa/7kpRnTOVwmgg2f8Vbq9AVjlmVbdjlfj4FWiIe6a1 Ixzw== X-Gm-Message-State: AOAM533VXmnhv+AFREFVhx+pRc9YWU4kbdkJK4Tm0dgOl7OJhwhSNpS1 StmUwQ5jE7VLqubqZJL4RlD7Tt9zygaIKsThfM2gd3KFWk2rS2GGdCToMbXsaIMiDVmqDdePzZQ OTUx9Dqzjj37EKBHa1wSRv1s/iaTu9VBmOndlNvlek3y5XUp3DFcBCpOnq7a+d65wKk5Als4O X-Google-Smtp-Source: ABdhPJyYUP0ELMvZXftTbIvTFbsq1bERG/w+ZBHS5SRMTw0bT6eC7BF5oah4p48aG7jyrrv+M8xNgH6fy0KA X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a25:358:0:b0:633:7a26:5ff4 with SMTP id 85-20020a250358000000b006337a265ff4mr28403773ybd.97.1647987354532; Tue, 22 Mar 2022 15:15:54 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:16 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-13-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 12/13] perf tools: Improve error handling of AMD Branch Sampling From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Improve the error message printed by perf when perf_event_open() fails on AMD Zen3 when using the branch sampling feature. In the case of EINVAL, the= re are two main reasons: frequency mode or period is smaller than the depth of the branch sampling buffer (16). The patch checks the parameters of the call and tries to print a relevant message to explain the error: $ perf record -b -e cpu/branch-brs/ -c 10 ls Error: AMD Branch Sampling does not support sampling period smaller than what is r= eported in /sys/devices/cpu/caps/branches. $ perf record -b -e cpu/branch-brs/ ls Error: AMD Branch Sampling does not support frequency mode sampling, must pass a f= ixed sampling period via -c option or cpu/branch-brs,period=3Dxxxx/. Signed-off-by: Stephane Eranian [Rebased on commit 9fe8895a27a84 ("perf env: Add perf_env__cpuid, perf_env_= _{nr_}pmu_mappings")] Signed-off-by: Kim Phillips --- tools/perf/util/evsel.c | 43 ++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e8ff7a4bd490..03f720a85764 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2858,6 +2858,16 @@ static bool is_amd_ibs(struct evsel *evsel) || (evsel->pmu_name && !strncmp(evsel->pmu_name, "ibs", 3)); } =20 +static bool is_amd_brs_event(struct evsel *evsel) +{ + return (evsel->core.attr.config & 0xff) =3D=3D 0xc4; +} + +static bool has_amd_brs(struct evsel *evsel) +{ + return (evsel->core.attr.sample_type & PERF_SAMPLE_BRANCH_STACK); +} + int evsel__open_strerror(struct evsel *evsel, struct target *target, int err, char *msg, size_t size) { @@ -2947,6 +2957,28 @@ int evsel__open_strerror(struct evsel *evsel, struct= target *target, "We found oprofile daemon running, please stop it and try again."); break; case EINVAL: + if (is_amd(arch, cpuid)) { + if (is_amd_ibs(evsel)) { + if (evsel->core.attr.exclude_kernel) + return scnprintf(msg, size, + "AMD IBS can't exclude kernel events. Try running at a higher privilege = level."); + if (!evsel->core.system_wide) + return scnprintf(msg, size, + "AMD IBS may only be available in system-wide/per-cpu mode. Try using -a= , or -C and workload affinity"); + } + if (has_amd_brs(evsel)) { + if (!is_amd_brs_event(evsel)) + return scnprintf(msg, size, + "AMD Branch Sampling can only be used with the cpu/branch-brs,period=3Dxx= xx/ event or equivalent encodings."); + if (evsel->core.attr.freq) + return scnprintf(msg, size, + "AMD Branch Sampling does not support frequency mode sampling, must pass = a fixed sampling period via -c option or cpu/branch-brs,period=3Dxxxx/."); + /* another reason is that the period is too small */ + return scnprintf(msg, size, + "AMD Branch Sampling does not support sampling period smaller than what i= s reported in /sys/devices/cpu/caps/branches."); + } + } + if (evsel->core.attr.sample_type & PERF_SAMPLE_CODE_PAGE_SIZE && perf_mi= ssing_features.code_page_size) return scnprintf(msg, size, "Asking for the code page size isn't suppor= ted by this kernel."); if (evsel->core.attr.sample_type & PERF_SAMPLE_DATA_PAGE_SIZE && perf_mi= ssing_features.data_page_size) @@ -2963,17 +2995,6 @@ int evsel__open_strerror(struct evsel *evsel, struct= target *target, return scnprintf(msg, size, "Invalid event (%s) in per-thread mode, enable system wide with '-a'.", evsel__name(evsel)); - if (is_amd(arch, cpuid)) { - if (is_amd_ibs(evsel)) { - if (evsel->core.attr.exclude_kernel) - return scnprintf(msg, size, - "AMD IBS can't exclude kernel events. Try running at a higher privilege = level."); - if (!evsel->core.system_wide) - return scnprintf(msg, size, - "AMD IBS may only be available in system-wide/per-cpu mode. Try using -a= , or -C and workload affinity"); - } - } - break; case ENODATA: return scnprintf(msg, size, "Cannot collect data source with the load la= tency event alone. " --=20 2.35.1.894.gb6a874cedc-goog From nobody Mon Jun 22 14:08:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D7D8C433F5 for ; Tue, 22 Mar 2022 22:16:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238007AbiCVWRt (ORCPT ); Tue, 22 Mar 2022 18:17:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237872AbiCVWRb (ORCPT ); Tue, 22 Mar 2022 18:17:31 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE87D53A41 for ; Tue, 22 Mar 2022 15:15:57 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2e589b1f3c4so162015737b3.9 for ; Tue, 22 Mar 2022 15:15:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=IFcDibgpn0vlUx5klEldQIKKp75EyTDULtjsHv0DNvY=; b=tad2jhx4Umf5A2kCDkwwGNzszum5Dc2eDtUta2sz3zzL3FFQOCPXTRZh2DLabasSi3 vNZwwswrem1gkDDO7N5dgJU05DZmAJx386sfz2S1MXRMXYiwDlQEMdd2XhCYhztsP93z Qd+8pMjYRDTMC7VZ7Z0cvR9dFIIigLbbcIeDMZdMabgsbMx2MkeqfAFbH2uQ4K7gfye+ u6xKAjIxmzmba60kwiY+vpxnUOa/BX3FZx4AWhOFKNQUj1d0o3mBUZJbKEWYydUUnvBv pX8IcBrnhxcyTpp/UrMxSUOAu2qeBb+LKpAd3cWfEJX3OFCZvll5DiBZeXYQpUHsCn+j C+sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=IFcDibgpn0vlUx5klEldQIKKp75EyTDULtjsHv0DNvY=; b=TGhhanyIW05ltmJx/6ObqfaZ6496OzLXGHkzG5bhlvaaUAR0HthrDBUlEhb4DQUI3U +NZvuIUSoq/gbp59IE7ika4hvaPIkSWHWjQp67tCxslUd7G1i+x4AnqFyLSc4rsvWL/l K51UbjnasIenCIHiGn512t+b0dpOBACyw3O4NOsYddS/WCByqboym86QcR54IBJ05FQb AGKr3DJ4bBENETvMCL9XbXaFNs4Jgc84IsnoLQzdmd2/miJI9OEiuc4lZk39SMZOas9a FFDUAOqVDWwZuq5eXnO/F2qVoJ2z1LK3862Hyy7yCIwn5po3MYlq8OmW6Wi3BMjUvFuU r+YQ== X-Gm-Message-State: AOAM532/HELY+pA38VUu8TaWW74ROs55/Ws28pbsLr0zuf9RgLvloA8E h+cY3JNSbCgBUS/MTyK94Uy/4GOWHse1NN9FcI7Hw0Sa/YeCQlfzjDxboWYFot1HsJ0qi4IWkSD 9k01eMXTqZBHSyY2s70zBYTt2au67rLX5Rjaf7xT6S/RevPVQdAbHFnExtSnW5ldh3PPMQ5Xx X-Google-Smtp-Source: ABdhPJxm7g07BsBKHFKVBpqO3WdlncMyiNIe3uYedQ0RuKtII9njtpCnbie+rVEt8H6c5z5/07qMRmu7aS8/ X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:1817:acc9:c45f:d133]) (user=eranian job=sendgmr) by 2002:a05:6902:1022:b0:634:5ae6:2a41 with SMTP id x2-20020a056902102200b006345ae62a41mr2884524ybt.446.1647987356860; Tue, 22 Mar 2022 15:15:56 -0700 (PDT) Date: Tue, 22 Mar 2022 15:15:17 -0700 In-Reply-To: <20220322221517.2510440-1-eranian@google.com> Message-Id: <20220322221517.2510440-14-eranian@google.com> Mime-Version: 1.0 References: <20220322221517.2510440-1-eranian@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH v7 13/13] perf report: add addr_from/addr_to sort dimensions From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com, rafael@kernel.org, ravi.bangoria@amd.com, sandipan.das@amd.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" With the existing symbol_from/symbol_to, branches captured in the same function would be collapsed into a single function if the latencies associa= ted with the each branch (cycles) were all the same. That is the case on Intel Broadwell, for instance. Since Intel Skylake, the latency is captured by hardware and therefore is used to disambiguate branches. Add addr_from/addr_to sort dimensions to sort branches based on their addresses and not the function there are in. The output is still the functi= on name but the offset within the function is provided to uniquely identify ea= ch branch. These new sort dimensions also help with annotate because they cre= ate different entries in the histogram which, in turn, generates proper branch annotations. Here is an example using AMD's branch sampling: $ perf record -a -b -c 1000037 -e cpu/branch-brs/ test_prg $ perf report Samples: 6M of event 'cpu/branch-brs/', Event count (approx.): 6901276 Overhead Command Source Shared Object Source Symbol = Target Symbol Basic= Block Cycle 99.65% test_prg test_prg [.] test_thread = [.] test_thread - 0.02% test_prg [kernel.vmlinux] [k] asm_sysvec_apic_timer_= interrupt [k] error_entry - $ perf report -F overhead,comm,dso,addr_from,addr_to Samples: 6M of event 'cpu/branch-brs/', Event count (approx.): 6901276 Overhead Command Shared Object Source Address Target= Address 4.22% test_prg test_prg [.] test_thread+0x3c [.] te= st_thread+0x4 4.13% test_prg test_prg [.] test_thread+0x4 [.] te= st_thread+0x3a 4.09% test_prg test_prg [.] test_thread+0x3a [.] te= st_thread+0x6 4.08% test_prg test_prg [.] test_thread+0x2 [.] te= st_thread+0x3c 4.06% test_prg test_prg [.] test_thread+0x3e [.] te= st_thread+0x2 3.87% test_prg test_prg [.] test_thread+0x6 [.] te= st_thread+0x38 3.84% test_prg test_prg [.] test_thread [.] te= st_thread+0x3e 3.76% test_prg test_prg [.] test_thread+0x1e [.] te= st_thread 3.76% test_prg test_prg [.] test_thread+0x38 [.] te= st_thread+0x8 3.56% test_prg test_prg [.] test_thread+0x22 [.] te= st_thread+0x1e 3.54% test_prg test_prg [.] test_thread+0x8 [.] te= st_thread+0x36 3.47% test_prg test_prg [.] test_thread+0x1c [.] te= st_thread+0x22 3.45% test_prg test_prg [.] test_thread+0x36 [.] te= st_thread+0xa 3.28% test_prg test_prg [.] test_thread+0x24 [.] te= st_thread+0x1c 3.25% test_prg test_prg [.] test_thread+0xa [.] te= st_thread+0x34 3.24% test_prg test_prg [.] test_thread+0x1a [.] te= st_thread+0x24 3.20% test_prg test_prg [.] test_thread+0x34 [.] te= st_thread+0xc 3.04% test_prg test_prg [.] test_thread+0x26 [.] te= st_thread+0x1a 3.01% test_prg test_prg [.] test_thread+0xc [.] te= st_thread+0x32 2.98% test_prg test_prg [.] test_thread+0x18 [.] te= st_thread+0x26 2.94% test_prg test_prg [.] test_thread+0x32 [.] te= st_thread+0xe 2.76% test_prg test_prg [.] test_thread+0x28 [.] te= st_thread+0x18 2.73% test_prg test_prg [.] test_thread+0xe [.] te= st_thread+0x30 2.67% test_prg test_prg [.] test_thread+0x30 [.] te= st_thread+0x10 2.67% test_prg test_prg [.] test_thread+0x16 [.] te= st_thread+0x28 2.46% test_prg test_prg [.] test_thread+0x10 [.] te= st_thread+0x2e 2.44% test_prg test_prg [.] test_thread+0x2a [.] te= st_thread+0x16 2.38% test_prg test_prg [.] test_thread+0x14 [.] te= st_thread+0x2a 2.32% test_prg test_prg [.] test_thread+0x2e [.] te= st_thread+0x12 2.28% test_prg test_prg [.] test_thread+0x12 [.] te= st_thread+0x2c 2.16% test_prg test_prg [.] test_thread+0x2c [.] te= st_thread+0x14 0.02% test_prg [kernel.vmlinux] [k] asm_sysvec_apic_ti+0x5 [k= ] error_entry Signed-off-by: Stephane Eranian --- tools/perf/util/hist.c | 2 + tools/perf/util/hist.h | 2 + tools/perf/util/sort.c | 128 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/sort.h | 2 + 4 files changed, 134 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0a8033b09e28..1c085ab56534 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -124,6 +124,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) } else { symlen =3D unresolved_col_width + 4 + 2; hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); + hists__new_col_len(hists, HISTC_ADDR_FROM, symlen); hists__set_unres_dso_col_len(hists, HISTC_DSO_FROM); } =20 @@ -138,6 +139,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) } else { symlen =3D unresolved_col_width + 4 + 2; hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); + hists__new_col_len(hists, HISTC_ADDR_TO, symlen); hists__set_unres_dso_col_len(hists, HISTC_DSO_TO); } =20 diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 2a15e22fb89c..7ed4648d2fc2 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -77,6 +77,8 @@ enum hist_column { HISTC_GLOBAL_INS_LAT, HISTC_LOCAL_P_STAGE_CYC, HISTC_GLOBAL_P_STAGE_CYC, + HISTC_ADDR_FROM, + HISTC_ADDR_TO, HISTC_NR_COLS, /* Last entry */ }; =20 diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 2da081ef532b..6d5588e80935 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -990,6 +990,128 @@ struct sort_entry sort_sym_to =3D { .se_width_idx =3D HISTC_SYMBOL_TO, }; =20 +static int _hist_entry__addr_snprintf(struct map_symbol *ms, + u64 ip, char level, char *bf, size_t size, + unsigned int width) +{ + struct symbol *sym =3D ms->sym; + struct map *map =3D ms->map; + size_t ret =3D 0, offs; + + ret +=3D repsep_snprintf(bf + ret, size - ret, "[%c] ", level); + if (sym && map) { + if (sym->type =3D=3D STT_OBJECT) { + ret +=3D repsep_snprintf(bf + ret, size - ret, "%s", sym->name); + ret +=3D repsep_snprintf(bf + ret, size - ret, "+0x%llx", + ip - map->unmap_ip(map, sym->start)); + } else { + ret +=3D repsep_snprintf(bf + ret, size - ret, "%.*s", + width - ret, + sym->name); + offs =3D ip - sym->start; + if (offs) + ret +=3D repsep_snprintf(bf + ret, size - ret, "+0x%llx", offs); + } + } else { + size_t len =3D BITS_PER_LONG / 4; + ret +=3D repsep_snprintf(bf + ret, size - ret, "%-#.*llx", + len, ip); + } + + return ret; +} + +static int hist_entry__addr_from_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) +{ + if (he->branch_info) { + struct addr_map_symbol *from =3D &he->branch_info->from; + + return _hist_entry__addr_snprintf(&from->ms, from->al_addr, + he->level, bf, size, width); + } + + return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); +} + +static int hist_entry__addr_to_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) +{ + if (he->branch_info) { + struct addr_map_symbol *to =3D &he->branch_info->to; + + return _hist_entry__addr_snprintf(&to->ms, to->al_addr, + he->level, bf, size, width); + } + + return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); +} + +static int64_t +sort__addr_from_cmp(struct hist_entry *left, struct hist_entry *right) +{ + struct addr_map_symbol *from_l; + struct addr_map_symbol *from_r; + int64_t ret; + + if (!left->branch_info || !right->branch_info) + return cmp_null(left->branch_info, right->branch_info); + + from_l =3D &left->branch_info->from; + from_r =3D &right->branch_info->from; + + /* + * comparing symbol address alone is not enough since it's a + * relative address within a dso. + */ + ret =3D _sort__dso_cmp(from_l->ms.map, from_r->ms.map); + if (ret !=3D 0) + return ret; + + return _sort__addr_cmp(from_l->addr, from_r->addr); +} + +static int64_t +sort__addr_to_cmp(struct hist_entry *left, struct hist_entry *right) +{ + struct addr_map_symbol *to_l; + struct addr_map_symbol *to_r; + int64_t ret; + + if (!left->branch_info || !right->branch_info) + return cmp_null(left->branch_info, right->branch_info); + + to_l =3D &left->branch_info->to; + to_r =3D &right->branch_info->to; + + /* + * comparing symbol address alone is not enough since it's a + * relative address within a dso. + */ + ret =3D _sort__dso_cmp(to_l->ms.map, to_r->ms.map); + if (ret !=3D 0) + return ret; + + return _sort__addr_cmp(to_l->addr, to_r->addr); +} + +struct sort_entry sort_addr_from =3D { + .se_header =3D "Source Address", + .se_cmp =3D sort__addr_from_cmp, + .se_snprintf =3D hist_entry__addr_from_snprintf, + .se_filter =3D hist_entry__sym_from_filter, /* shared with sym_from */ + .se_width_idx =3D HISTC_ADDR_FROM, +}; + +struct sort_entry sort_addr_to =3D { + .se_header =3D "Target Address", + .se_cmp =3D sort__addr_to_cmp, + .se_snprintf =3D hist_entry__addr_to_snprintf, + .se_filter =3D hist_entry__sym_to_filter, /* shared with sym_to */ + .se_width_idx =3D HISTC_ADDR_TO, +}; + + static int64_t sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right) { @@ -1893,6 +2015,8 @@ static struct sort_dimension bstack_sort_dimensions[]= =3D { DIM(SORT_SRCLINE_FROM, "srcline_from", sort_srcline_from), DIM(SORT_SRCLINE_TO, "srcline_to", sort_srcline_to), DIM(SORT_SYM_IPC, "ipc_lbr", sort_sym_ipc), + DIM(SORT_ADDR_FROM, "addr_from", sort_addr_from), + DIM(SORT_ADDR_TO, "addr_to", sort_addr_to), }; =20 #undef DIM @@ -3126,6 +3250,10 @@ static bool get_elide(int idx, FILE *output) return __get_elide(symbol_conf.dso_from_list, "dso_from", output); case HISTC_DSO_TO: return __get_elide(symbol_conf.dso_to_list, "dso_to", output); + case HISTC_ADDR_FROM: + return __get_elide(symbol_conf.sym_from_list, "addr_from", output); + case HISTC_ADDR_TO: + return __get_elide(symbol_conf.sym_to_list, "addr_to", output); default: break; } diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index f994261888e1..2ddc00d1c464 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -251,6 +251,8 @@ enum sort_type { SORT_SRCLINE_FROM, SORT_SRCLINE_TO, SORT_SYM_IPC, + SORT_ADDR_FROM, + SORT_ADDR_TO, =20 /* memory mode specific sort keys */ __SORT_MEMORY_MODE, --=20 2.35.1.894.gb6a874cedc-goog