From patchwork Tue Jan 28 04:59:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Kumar Patra X-Patchwork-Id: 13952032 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E340DC0218D for ; Tue, 28 Jan 2025 05:15:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=8bYgqzdVcJEs+5Om17+8npB3p9rTqd8el94+SSiomKA=; b=bWM5mLIuy2VacXDrCQd64oMjzB 0HQUes6F/3jwHbTqRozOdWeGYPpTjtR2MSwAydHXyq7pNeQSyrls3Fw66kp60r7Z39ZyF/fW+t0o/ FJCqhnLQLcu/gQUtkUxWwxM6ZRHSKnWpyc5P8wRa942RzG4HZi1vi63B8DHeIEtfbTM8a3pnWsbxH HjlKsOTo5jkgcG8uNl5DXv6CNM6VsZtf6r0MDupztyeVijiRFPeYNhKtWzhlrwdDhmeIF9Avur88Q Wv4ZrTB6lOQKx6uUIBg+AMFOEIzpdEBRuu/zR5kHwQ3+Czb4FW+6aVgU9TlqQjB+blgTv0NhnmGXq crXybYxw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tcdw7-000000048GD-0RNG; Tue, 28 Jan 2025 05:14:55 +0000 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tcdhp-000000044cU-12yu for linux-arm-kernel@lists.infradead.org; Tue, 28 Jan 2025 05:00:11 +0000 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2eed82ca5b4so8830724a91.2 for ; Mon, 27 Jan 2025 21:00:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1738040409; x=1738645209; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=8bYgqzdVcJEs+5Om17+8npB3p9rTqd8el94+SSiomKA=; b=Oqp7pxHaShFy4qsL35sUlSKsbbOj6hgltz9/G2xz20mB//dWjAZAJanSfidO/RA8ft 9OrDZX2wRrirjpCQTOLvDXYlviWSvO2RgKkkTOHwYdypOarayoOX8DGbgu4fzTkA69Ax 2uVFQ7m705onmeOIzafVE6WFJ/3vxKZD/59meDZ7oCQilZ5QFcQyO+IpEKfMIgxsJdXW zs2O1xurYbbRfCfg/W2pqjPUe3ljKoxiowh74/AJ/HvxOQltYd8Dqitv0vVUiI1UFSSV +0LMhjDDPAItQB4HVnq8jsQFQPKsBpFY2+sKHmc/GSHrBdyLhhAK0AeE+o0jmaENx2fu BQ1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738040409; x=1738645209; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8bYgqzdVcJEs+5Om17+8npB3p9rTqd8el94+SSiomKA=; b=cSUxrVqm8F/R3jz+H94Jhk0++qxYMEjKm1JGPU7f+BhI+LmqACXWOJ++vziCwwoywq qjqsQkFvkpue0cNyKmcmSK/Rrb9bStPN/vpY8Ip+yHeZQrY2jZEF8ZTjGi2hKvSQRPBX JAncz5ZizKLWpNILfZBD1yWt9XblrEZDEdn5sF5CQ7/Idjt+/pBgUG9ArWu2L9unKIk/ Y+b/Ps0rSZxLaJhHICjfwMMiSz+T28l3jj3WqPSMZzw4lrAd1OIQfqNdjnY/kx4WusL1 zAShCCFMUynhFmjJI1xr70138BY9dhgzysNOleQUV2iZpm1BLe/eiR1brZDhHC8rQRQ4 c+Gg== X-Forwarded-Encrypted: i=1; AJvYcCX628x2f1NXqrUoCLvCtwxavJoF1vKb/qo/0rSJ6OuqefF8DbwQxpHL/uT0Ocz/4weHyfmL/AWFG9A4hlH71gjE@lists.infradead.org X-Gm-Message-State: AOJu0Yx5Z6K6gBFkPfGd1g46FFqnUy5l76cec7Owgtb0ZWr4uUwJc59Z vUfl3uAsjRgcs7p05isVx6bwKdaW0RY4YHCsCJA7OR/ibqbJvHgVj5YiP0qavUo= X-Gm-Gg: ASbGncvUpz1vVejJAOsGfPnTuq6n1jMH4Eq95LeLbhrqTi4QUsBK0cHX5H8qGiyWFOU 03S1buB9DasxN1hrls9dQ79zliwB34QSvo88fP80SvEx4LuPOshZzc3Ylrl+SfAqQIUH/OKVFzm daaD95zQ2wwdAV5pThHdqaZz9eUYOhPXHytq3wBpMOIsbE/6mGMiVaf0bWgTun3tjySf+9pRl9X 8qtWvA4AYtwKHt+Kz54q9V+n3jqk0l9D+OpwPWt47vsD4SHpmRwjs/i2hbEW7AXnK5EDBblnGkh Nn3Urt0e+7dVsVyvf/qkplCKuCoN X-Google-Smtp-Source: AGHT+IGLp1UCkGagpEBSjEvSyu6FWwXgcrQZ9ubpPbhJGTYHTG61vJv8BZTr3/TOZQCrUeRv8fNh1w== X-Received: by 2002:a17:90a:c883:b0:2ea:77d9:6345 with SMTP id 98e67ed59e1d1-2f782d3299emr53146392a91.22.1738040408675; Mon, 27 Jan 2025 21:00:08 -0800 (PST) Received: from atishp.ba.rivosinc.com ([64.71.180.162]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2f7ffa5a7f7sm8212776a91.11.2025.01.27.21.00.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 21:00:08 -0800 (PST) From: Atish Patra Date: Mon, 27 Jan 2025 20:59:53 -0800 Subject: [PATCH v3 12/21] RISC-V: perf: Modify the counter discovery mechanism MIME-Version: 1.0 Message-Id: <20250127-counter_delegation-v3-12-64894d7e16d5@rivosinc.com> References: <20250127-counter_delegation-v3-0-64894d7e16d5@rivosinc.com> In-Reply-To: <20250127-counter_delegation-v3-0-64894d7e16d5@rivosinc.com> To: Paul Walmsley , Palmer Dabbelt , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Anup Patel , Atish Patra , Will Deacon , Mark Rutland , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , weilin.wang@intel.com Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Conor Dooley , devicetree@vger.kernel.org, kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, Atish Patra X-Mailer: b4 0.15-dev-13183 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250127_210009_374088_F823264D X-CRM114-Status: GOOD ( 28.55 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org If both counter delegation and SBI PMU is present, the counter delegation will be used for hardware pmu counters while the SBI PMU will be used for firmware counters. Thus, the driver has to probe the counters info via SBI PMU to distinguish the firmware counters. The hybrid scheme also requires improvements of the informational logging messages to indicate the user about underlying interface used for each use case. Signed-off-by: Atish Patra --- drivers/perf/riscv_pmu_dev.c | 118 ++++++++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/drivers/perf/riscv_pmu_dev.c b/drivers/perf/riscv_pmu_dev.c index b69654554288..c7adda948b5d 100644 --- a/drivers/perf/riscv_pmu_dev.c +++ b/drivers/perf/riscv_pmu_dev.c @@ -66,6 +66,10 @@ static bool sbi_v2_available; static DEFINE_STATIC_KEY_FALSE(sbi_pmu_snapshot_available); #define sbi_pmu_snapshot_available() \ static_branch_unlikely(&sbi_pmu_snapshot_available) +static DEFINE_STATIC_KEY_FALSE(riscv_pmu_sbi_available); +static DEFINE_STATIC_KEY_FALSE(riscv_pmu_cdeleg_available); +static bool cdeleg_available; +static bool sbi_available; static struct attribute *riscv_arch_formats_attr[] = { &format_attr_event.attr, @@ -88,7 +92,8 @@ static int sysctl_perf_user_access __read_mostly = SYSCTL_USER_ACCESS; /* * This structure is SBI specific but counter delegation also require counter - * width, csr mapping. Reuse it for now. + * width, csr mapping. Reuse it for now we can have firmware counters for + * platfroms with counter delegation support. * RISC-V doesn't have heterogeneous harts yet. This need to be part of * per_cpu in case of harts with different pmu counters */ @@ -100,6 +105,8 @@ static unsigned int riscv_pmu_irq; /* Cache the available counters in a bitmask */ static unsigned long cmask; +/* Cache the available firmware counters in another bitmask */ +static unsigned long firmware_cmask; struct sbi_pmu_event_data { union { @@ -778,35 +785,49 @@ static int rvpmu_sbi_find_num_ctrs(void) return sbi_err_map_linux_errno(ret.error); } -static int rvpmu_sbi_get_ctrinfo(int nctr, unsigned long *mask) +static int rvpmu_deleg_find_ctrs(void) +{ + /* TODO */ + return -1; +} + +static int rvpmu_sbi_get_ctrinfo(int nsbi_ctr, int ndeleg_ctr) { struct sbiret ret; - int i, num_hw_ctr = 0, num_fw_ctr = 0; + int i, num_hw_ctr = 0, num_fw_ctr = 0, num_ctr = 0; union sbi_pmu_ctr_info cinfo; - pmu_ctr_list = kcalloc(nctr, sizeof(*pmu_ctr_list), GFP_KERNEL); - if (!pmu_ctr_list) - return -ENOMEM; - - for (i = 0; i < nctr; i++) { + for (i = 0; i < nsbi_ctr; i++) { ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_GET_INFO, i, 0, 0, 0, 0, 0); if (ret.error) /* The logical counter ids are not expected to be contiguous */ continue; - *mask |= BIT(i); - cinfo.value = ret.value; if (cinfo.type == SBI_PMU_CTR_TYPE_FW) num_fw_ctr++; - else + + if (!cdeleg_available) { num_hw_ctr++; - pmu_ctr_list[i].value = cinfo.value; + cmask |= BIT(i); + pmu_ctr_list[i].value = cinfo.value; + } else if (cinfo.type == SBI_PMU_CTR_TYPE_FW) { + /* Track firmware counters in a different mask */ + firmware_cmask |= BIT(i); + pmu_ctr_list[i].value = cinfo.value; + } + } - pr_info("%d firmware and %d hardware counters\n", num_fw_ctr, num_hw_ctr); + if (cdeleg_available) { + pr_info("%d firmware and %d hardware counters\n", num_fw_ctr, ndeleg_ctr); + num_ctr = num_fw_ctr + ndeleg_ctr; + } else { + pr_info("%d firmware and %d hardware counters\n", num_fw_ctr, num_hw_ctr); + num_ctr = nsbi_ctr; + } - return 0; + return num_ctr; } static inline void rvpmu_sbi_stop_all(struct riscv_pmu *pmu) @@ -1067,16 +1088,33 @@ static void rvpmu_ctr_stop(struct perf_event *event, unsigned long flag) /* TODO: Counter delegation implementation */ } -static int rvpmu_find_num_ctrs(void) +static int rvpmu_find_ctrs(void) { - return rvpmu_sbi_find_num_ctrs(); - /* TODO: Counter delegation implementation */ -} + int num_sbi_counters = 0, num_deleg_counters = 0, num_counters = 0; -static int rvpmu_get_ctrinfo(int nctr, unsigned long *mask) -{ - return rvpmu_sbi_get_ctrinfo(nctr, mask); - /* TODO: Counter delegation implementation */ + /* + * We don't know how many firmware counters available. Just allocate + * for maximum counters driver can support. The default is 64 anyways. + */ + pmu_ctr_list = kcalloc(RISCV_MAX_COUNTERS, sizeof(*pmu_ctr_list), + GFP_KERNEL); + if (!pmu_ctr_list) + return -ENOMEM; + + if (cdeleg_available) + num_deleg_counters = rvpmu_deleg_find_ctrs(); + + /* This is required for firmware counters even if the above is true */ + if (sbi_available) + num_sbi_counters = rvpmu_sbi_find_num_ctrs(); + + if (num_sbi_counters >= RISCV_MAX_COUNTERS || num_deleg_counters >= RISCV_MAX_COUNTERS) + return -ENOSPC; + + /* cache all the information about counters now */ + num_counters = rvpmu_sbi_get_ctrinfo(num_sbi_counters, num_deleg_counters); + + return num_counters; } static int rvpmu_event_map(struct perf_event *event, u64 *econfig) @@ -1377,12 +1415,21 @@ static int rvpmu_device_probe(struct platform_device *pdev) int ret = -ENODEV; int num_counters; - pr_info("SBI PMU extension is available\n"); + if (cdeleg_available) { + pr_info("hpmcounters will use the counter delegation ISA extension\n"); + if (sbi_available) + pr_info("Firmware counters will be use SBI PMU extension\n"); + else + pr_info("Firmware counters will be not available as SBI PMU extension is not present\n"); + } else if (sbi_available) { + pr_info("Both hpmcounters and firmware counters will use SBI PMU extension\n"); + } + pmu = riscv_pmu_alloc(); if (!pmu) return -ENOMEM; - num_counters = rvpmu_find_num_ctrs(); + num_counters = rvpmu_find_ctrs(); if (num_counters < 0) { pr_err("SBI PMU extension doesn't provide any counters\n"); goto out_free; @@ -1394,9 +1441,6 @@ static int rvpmu_device_probe(struct platform_device *pdev) pr_info("SBI returned more than maximum number of counters. Limiting the number of counters to %d\n", num_counters); } - /* cache all the information about counters now */ - if (rvpmu_get_ctrinfo(num_counters, &cmask)) - goto out_free; ret = rvpmu_setup_irqs(pmu, pdev); if (ret < 0) { @@ -1486,13 +1530,27 @@ static int __init rvpmu_devinit(void) int ret; struct platform_device *pdev; - if (sbi_spec_version < sbi_mk_version(0, 3) || - !sbi_probe_extension(SBI_EXT_PMU)) { - return 0; + if (sbi_spec_version >= sbi_mk_version(0, 3) && + sbi_probe_extension(SBI_EXT_PMU)) { + static_branch_enable(&riscv_pmu_sbi_available); + sbi_available = true; } if (sbi_spec_version >= sbi_mk_version(2, 0)) sbi_v2_available = true; + /* + * We need all three extensions to be present to access the counters + * in S-mode via Supervisor Counter delegation. + */ + if (riscv_isa_extension_available(NULL, SSCCFG) && + riscv_isa_extension_available(NULL, SMCDELEG) && + riscv_isa_extension_available(NULL, SSCSRIND)) { + static_branch_enable(&riscv_pmu_cdeleg_available); + cdeleg_available = true; + } + + if (!(sbi_available || cdeleg_available)) + return 0; ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_RISCV_STARTING, "perf/riscv/pmu:starting",