From nobody Mon Feb 9 19:37:56 2026 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A66AE24333F for ; Thu, 16 Jan 2025 23:10:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737069037; cv=none; b=Np+sIfQgs7RWWpu4mIGDpw3y1yL7DqIe/9I8P3KvHRRi6qYiffIqOs1/I+UB1NFtxQj7uvwg4WG88oTopuscxEvHMbHm0r+s1OJY5IcHTjNImO066LSAMhhFh9IE+pASjihZCx2hz/XCQ1QPr9GGE2WDZtp3VYRyG7D+CJNChCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737069037; c=relaxed/simple; bh=rGHKedXfHrDo3lqW3oF9DMphEKq6q03N6Xzb1G1zBm4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mtBQTFX0o86LmJxfc3x35+aKu9xY+Dzfs5/CXTcalMlgOouzadM8webdiLHQHD4AW2c0ucgdOEu18ZvDMSJN0XR5Gd6hXBBiAZvmjzrwZGcl+DDG+5L+OBWPR8tF8yv3Ph03nKMKs3uJHQUmvw4AkKeK+OtPCh1K8HCpDsHGOYU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=OMlDtd0o; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="OMlDtd0o" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-436249df846so9653535e9.3 for ; Thu, 16 Jan 2025 15:10:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737069033; x=1737673833; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Hcwn1RBtRoJipu7fOBlFbI2SRrDtGNtcTvKQWm9rBOc=; b=OMlDtd0oJOyDbmeB0eGjFNN0ndVHgPCk9/Kzyxrz7gNodc/FoSUrBALiNQIhD2GO4c HSg31vbmtISLJk5xcVzcfm15LWOKz/MXoSEJAsVgSumZ8/ocgqWKu7/ZS3uEyfK/HyyF 0u4ZL/kfDfGWIUlyDPWflQD7q4h8vSpwm89hF+QN5OkAB3d3sLttWGWe6W16XwHhzIID vCdBN7JRcEAHk1I3YycTedpqaNzyCio2EhtxuUQDpKbhTkmtcntReQUt6/swMMF5Ju+U mwqGABTWwLzHj70lWUA1e4pLb+kKz5XP9aRtuJHvKJ0jC+U+dQ0K7IfczpgHbui79ms6 P7kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737069033; x=1737673833; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Hcwn1RBtRoJipu7fOBlFbI2SRrDtGNtcTvKQWm9rBOc=; b=SbOxutXHUSRy2azoFmd0rSoO1uuYmkrPMNkKzaOlBFSQs/xQo76VPeav3TddM0SIMF haoKXEFfDgFOFIgUjOMwIx4Za4Ii9lTwquyV9UxuEo68s1EZ8Ub+u7f4O45ImLPfNteo /apHlLD34cWiLuBDG8G14HPVkR72rohfGp2t6l6pU5YZxBTQkbgRFeJzBECgf6GJLlp+ 4xwh+t+MAhc0J8Axz6atEtxpqJIpWNgTU1nrJaDtGykP/2NmOiAYP84WIzd/MmhwC65C P2htMWkv0zAVAVJ6D4kduWTbvLNyYPZSozPrmMW+SqpWj/Tmfvc+Ni4Re5WhFxAiRS4k fIjg== X-Gm-Message-State: AOJu0Yxq6PfFlvUolToUqyOrA1fghJXICpEe/Fmc2GUDtV9qyPmkEUkZ L0L+XXJ3MFpCj+El6zeo6o4LEAJr9K14aj4i2cd4idTEE7wlSvsGw/um5UFgIwz2YS3mbhsIems n X-Gm-Gg: ASbGncss0EFqa/3q4HfPbAhTjxANdmV62Gv4Am9gRwCW3Vb7Y++Of4RHGEu1aWT4H/o dgenKH2RFjsWkClZJlCppW9C5DgKw+Hbp/wDN/13ocSuuMYNozJaIce5M6jswYdFX7us6OFdbpo bUtCIOkFNhuQhlsHHL/B9CvCavEgnhW2jNDOtbKyKJRYnkKk6c1l+GyrfsXBJmFqvvzAgGF51Ev tm47rccuIu7jSw+X3PxNvr8W6jUtbtdZX95OJ4qt6XGyKt0lKFpsH3c2CxfYqCYoJWwBSn7hxLO NTfNPnsslDvjH2ji X-Google-Smtp-Source: AGHT+IGhZmz9Itp7KaTHT92wABYL6U7X2X4dHUE4Or0Kr1OPRGRfA1au2n+XsimRBSL8IAL2MNW8AQ== X-Received: by 2002:a05:600c:3d06:b0:434:eb73:b0c0 with SMTP id 5b1f17b1804b1-438913c7e31mr4321905e9.5.1737069032813; Thu, 16 Jan 2025 15:10:32 -0800 (PST) Received: from rkanwal-XPS-15-9520.uk.rivosinc.com ([2a02:c7c:75ac:6300:b3f2:3a24:1767:7db0]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38bf322b337sm974991f8f.59.2025.01.16.15.10.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2025 15:10:32 -0800 (PST) From: Rajnesh Kanwal To: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org Cc: linux-perf-users@vger.kernel.org, adrian.hunter@intel.com, alexander.shishkin@linux.intel.com, ajones@ventanamicro.com, anup@brainfault.org, acme@kernel.org, atishp@rivosinc.com, beeman@rivosinc.com, brauner@kernel.org, conor@kernel.org, heiko@sntech.de, irogers@google.com, mingo@redhat.com, james.clark@arm.com, renyu.zj@linux.alibaba.com, jolsa@kernel.org, jisheng.teoh@starfivetech.com, palmer@dabbelt.com, will@kernel.org, kaiwenxue1@gmail.com, vincent.chen@sifive.com, Rajnesh Kanwal Subject: [PATCH v2 5/7] riscv: pmu: Add infrastructure for Control Transfer Record Date: Thu, 16 Jan 2025 23:09:53 +0000 Message-Id: <20250116230955.867152-6-rkanwal@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250116230955.867152-1-rkanwal@rivosinc.com> References: <20250116230955.867152-1-rkanwal@rivosinc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To support Control Transfer Records (CTR) extension, we need to extend the riscv_pmu framework with some basic infrastructure for branch stack samplin= g. Subsequent patches will use this to add support for CTR in the riscv_pmu_dev driver. With CTR, the branches are stored into a hardware FIFO, which will be sampl= ed by software when perf events overflow. A task may be context-switched betwe= en overflows, and to avoid leaking samples we need to clear the last task's records when a task is context-switched in. To do this we will be using the pmu::sched_task() callback added in this patch. Signed-off-by: Rajnesh Kanwal --- drivers/perf/riscv_pmu_common.c | 20 ++++++++++++++++++++ drivers/perf/riscv_pmu_dev.c | 17 +++++++++++++++++ drivers/perf/riscv_pmu_legacy.c | 2 ++ include/linux/perf/riscv_pmu.h | 18 ++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/drivers/perf/riscv_pmu_common.c b/drivers/perf/riscv_pmu_commo= n.c index 7644147d50b4..c4c4b5d6bed0 100644 --- a/drivers/perf/riscv_pmu_common.c +++ b/drivers/perf/riscv_pmu_common.c @@ -157,6 +157,19 @@ u64 riscv_pmu_ctr_get_width_mask(struct perf_event *ev= ent) return GENMASK_ULL(cwidth, 0); } =20 +static void riscv_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx, + bool sched_in) +{ + struct riscv_pmu *pmu; + + if (!pmu_ctx) + return; + + pmu =3D to_riscv_pmu(pmu_ctx->pmu); + if (pmu->sched_task) + pmu->sched_task(pmu_ctx, sched_in); +} + u64 riscv_pmu_event_update(struct perf_event *event) { struct riscv_pmu *rvpmu =3D to_riscv_pmu(event->pmu); @@ -269,6 +282,8 @@ static int riscv_pmu_add(struct perf_event *event, int = flags) cpuc->events[idx] =3D event; cpuc->n_events++; hwc->state =3D PERF_HES_UPTODATE | PERF_HES_STOPPED; + if (rvpmu->ctr_add) + rvpmu->ctr_add(event, flags); if (flags & PERF_EF_START) riscv_pmu_start(event, PERF_EF_RELOAD); =20 @@ -286,6 +301,9 @@ static void riscv_pmu_del(struct perf_event *event, int= flags) =20 riscv_pmu_stop(event, PERF_EF_UPDATE); cpuc->events[hwc->idx] =3D NULL; + if (rvpmu->ctr_del) + rvpmu->ctr_del(event, flags); + /* The firmware need to reset the counter mapping */ if (rvpmu->ctr_stop) rvpmu->ctr_stop(event, RISCV_PMU_STOP_FLAG_RESET); @@ -402,6 +420,7 @@ struct riscv_pmu *riscv_pmu_alloc(void) for_each_possible_cpu(cpuid) { cpuc =3D per_cpu_ptr(pmu->hw_events, cpuid); cpuc->n_events =3D 0; + cpuc->ctr_users =3D 0; for (i =3D 0; i < RISCV_MAX_COUNTERS; i++) cpuc->events[i] =3D NULL; cpuc->snapshot_addr =3D NULL; @@ -416,6 +435,7 @@ struct riscv_pmu *riscv_pmu_alloc(void) .start =3D riscv_pmu_start, .stop =3D riscv_pmu_stop, .read =3D riscv_pmu_read, + .sched_task =3D riscv_pmu_sched_task, }; =20 return pmu; diff --git a/drivers/perf/riscv_pmu_dev.c b/drivers/perf/riscv_pmu_dev.c index d28d60abaaf2..b9b257607b76 100644 --- a/drivers/perf/riscv_pmu_dev.c +++ b/drivers/perf/riscv_pmu_dev.c @@ -1027,6 +1027,12 @@ static void rvpmu_sbi_ctr_stop(struct perf_event *ev= ent, unsigned long flag) } } =20 +static void pmu_sched_task(struct perf_event_pmu_context *pmu_ctx, + bool sched_in) +{ + /* Call CTR specific Sched hook. */ +} + static int rvpmu_sbi_find_num_ctrs(void) { struct sbiret ret; @@ -1569,6 +1575,14 @@ static int rvpmu_deleg_ctr_get_idx(struct perf_event= *event) return -ENOENT; } =20 +static void rvpmu_ctr_add(struct perf_event *event, int flags) +{ +} + +static void rvpmu_ctr_del(struct perf_event *event, int flags) +{ +} + static void rvpmu_ctr_start(struct perf_event *event, u64 ival) { struct hw_perf_event *hwc =3D &event->hw; @@ -1984,6 +1998,8 @@ static int rvpmu_device_probe(struct platform_device = *pdev) else pmu->pmu.attr_groups =3D riscv_sbi_pmu_attr_groups; pmu->cmask =3D cmask; + pmu->ctr_add =3D rvpmu_ctr_add; + pmu->ctr_del =3D rvpmu_ctr_del; pmu->ctr_start =3D rvpmu_ctr_start; pmu->ctr_stop =3D rvpmu_ctr_stop; pmu->event_map =3D rvpmu_event_map; @@ -1995,6 +2011,7 @@ static int rvpmu_device_probe(struct platform_device = *pdev) pmu->event_mapped =3D rvpmu_event_mapped; pmu->event_unmapped =3D rvpmu_event_unmapped; pmu->csr_index =3D rvpmu_csr_index; + pmu->sched_task =3D pmu_sched_task; =20 ret =3D riscv_pm_pmu_register(pmu); if (ret) diff --git a/drivers/perf/riscv_pmu_legacy.c b/drivers/perf/riscv_pmu_legac= y.c index 93c8e0fdb589..bee6742d35fa 100644 --- a/drivers/perf/riscv_pmu_legacy.c +++ b/drivers/perf/riscv_pmu_legacy.c @@ -115,6 +115,8 @@ static void pmu_legacy_init(struct riscv_pmu *pmu) BIT(RISCV_PMU_LEGACY_INSTRET); pmu->ctr_start =3D pmu_legacy_ctr_start; pmu->ctr_stop =3D NULL; + pmu->ctr_add =3D NULL; + pmu->ctr_del =3D NULL; pmu->event_map =3D pmu_legacy_event_map; pmu->ctr_get_idx =3D pmu_legacy_ctr_get_idx; pmu->ctr_get_width =3D pmu_legacy_ctr_get_width; diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h index e58f83811988..883781f12ae0 100644 --- a/include/linux/perf/riscv_pmu.h +++ b/include/linux/perf/riscv_pmu.h @@ -46,6 +46,13 @@ }, \ } =20 +#define MAX_BRANCH_RECORDS 256 + +struct branch_records { + struct perf_branch_stack branch_stack; + struct perf_branch_entry branch_entries[MAX_BRANCH_RECORDS]; +}; + struct cpu_hw_events { /* currently enabled events */ int n_events; @@ -65,6 +72,12 @@ struct cpu_hw_events { bool snapshot_set_done; /* A shadow copy of the counter values to avoid clobbering during multipl= e SBI calls */ u64 snapshot_cval_shcopy[RISCV_MAX_COUNTERS]; + + /* Saved branch records. */ + struct branch_records *branches; + + /* Active events requesting branch records */ + int ctr_users; }; =20 struct riscv_pmu { @@ -78,6 +91,8 @@ struct riscv_pmu { int (*ctr_get_idx)(struct perf_event *event); int (*ctr_get_width)(int idx); void (*ctr_clear_idx)(struct perf_event *event); + void (*ctr_add)(struct perf_event *event, int flags); + void (*ctr_del)(struct perf_event *event, int flags); void (*ctr_start)(struct perf_event *event, u64 init_val); void (*ctr_stop)(struct perf_event *event, unsigned long flag); int (*event_map)(struct perf_event *event, u64 *config); @@ -85,10 +100,13 @@ struct riscv_pmu { void (*event_mapped)(struct perf_event *event, struct mm_struct *mm); void (*event_unmapped)(struct perf_event *event, struct mm_struct *mm); uint8_t (*csr_index)(struct perf_event *event); + void (*sched_task)(struct perf_event_pmu_context *ctx, bool sched_in); =20 struct cpu_hw_events __percpu *hw_events; struct hlist_node node; struct notifier_block riscv_pm_nb; + + unsigned int ctr_depth; }; =20 #define to_riscv_pmu(p) (container_of(p, struct riscv_pmu, pmu)) --=20 2.34.1