From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (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 66D6132ED3F for ; Thu, 13 Nov 2025 18:05:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057146; cv=none; b=Mh7XolIueNPV6PVqPN1XMOoEhykku2Xau6qCHcVHj3j50S3ofIVhkrqcbU5YbM2W1InFBuCd8lsk2D5ZOKSbtfPzERjlQqKc1Dt+ZSPkqmHbNbNFeVrCu8WiYpTIR7Gg1W5X1Q6Dl+d/HNM2yejbxD4gteIZU80on82cA424yvo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057146; c=relaxed/simple; bh=0G/j/xJj1qsweoCKMUXKGFzeFo7TvQZ/7fH1qwVBjpI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=FUo+MXoeiLQ6Tixw3rWoBwlLqtpKmrNCauAa9TANOqag2xvPmY04NPX51iWBI5qZSIejen7AE+FxqxPogYNJb5TqR1TQgs4Wr9pmp4D6v4Yi1HI+S7v7AMU+GpNHLFfYMejDdd7oj1fiDfUYGNjWvjrkH9iLPZhNUlzuvSuURMU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=xDcZvJIE; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="xDcZvJIE" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-bbcf3bd4c8fso1047020a12.0 for ; Thu, 13 Nov 2025 10:05:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057145; x=1763661945; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=BwL0flbR67e6mq7ibhkhVdiS0tjPyP1QzI5zBDpL9cA=; b=xDcZvJIErPpu7Z/SU4vqwwY7t35sXRCkgfC01ash+1zIwWCCD+e3eOxUsotIb88hTZ Le6Lp+GpLTgRFvUBIIiHTfA1kyuvWBcSsYfQVP98jXDVViwDtgfoPbgLvb0MABSzURp6 g8zIGRdkqOBSOFjGV5D94LfIj6vtIFELdSlp2/muFz9Qs9uYamoeXcilcqN4VsSGSP1Q MfYH4cbpZSRQx5DcaRMt27a6Xgf37hvaDi4qPZUovVz+UvutIZ4ekxNwIz16pBn2tx2w dWwmK7jp3dLsRHY4ghNolDA5YqOaXc5DBx3YSenlPF6AVln82YXUsO3DYny5+2k3WxU5 04zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057145; x=1763661945; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=BwL0flbR67e6mq7ibhkhVdiS0tjPyP1QzI5zBDpL9cA=; b=eYIZomNmtPIqwpZuKdqixYVtwKWjBgmxCT+LYnfXpf29RjeUXGux8Y2Z6WoTkOSX6N sNeduB1I9WqVNPWwXDj+1jO+E8CJxE1/zwl64ViraM0LHITQ31wwVymdOL3fFfWLM/K+ Pnv0CdRSFmKtHYXCRGmDhk+ELffzr6t/Fx3iZL/fmrhrXFehWifrgRCtmcy8LTSAfpzt HK2O0G5Y4siyi85SKi3rBfM/fmaFOfxkskOrWYwm1WW3GTo4mfo2pz3GyoF8PAIt+4Zx etc3SxJvaeILZeS0buXxCLcQSlAMU6So5Ken/TzpH6lXID7JRgAZsZJVZiT1Rk2NaVb8 Fp1g== X-Forwarded-Encrypted: i=1; AJvYcCUpaz6K2OYshBbBNhNvhHatqtzn9XkehE5NUStvWwnCeCWo769TkmURRrPHgetITApkJMueEIGnLjnFD0k=@vger.kernel.org X-Gm-Message-State: AOJu0YyRhOMn+SwH0Iss/5CqewLVcxK6ZEOCrhl5U/6NeBDCmol3u8na Y2/ysCF32kPc3p447SLgJsOsMgeolFTuWJSRXzstWsexdzC/IogeNGCcdUzTvZU+H94ijTksRaQ 0vnkscU+UAw== X-Google-Smtp-Source: AGHT+IF6Jd/RowQsFfWnNU8wA7E0ssHBi+qEZJ0B7mLoneITR8fS1wlRdblP/48yXPF2vGHx7hvFukXw9/Mb X-Received: from dlbqc12.prod.google.com ([2002:a05:7023:a8c:b0:11a:3b81:6bc6]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6624:b0:11a:468a:cf9b with SMTP id a92af1059eb24-11b034b5b0amr155103c88.9.1763057144586; Thu, 13 Nov 2025 10:05:44 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:07 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-2-irogers@google.com> Subject: [PATCH v4 01/10] libperf cpumap: Reduce allocations and sorting in intersect From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On hybrid platforms the CPU maps are often disjoint. Rather than copy CPUs and trim, compute the number of common CPUs, if none early exit, otherwise copy in an sorted order. This avoids memory allocation in the disjoint case and avoids a second malloc and useless sort in the previous trim cases. Signed-off-by: Ian Rogers --- tools/lib/perf/cpumap.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index b20a5280f2b3..7e88417ba84d 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -453,21 +453,33 @@ int perf_cpu_map__merge(struct perf_cpu_map **orig, s= truct perf_cpu_map *other) struct perf_cpu_map *perf_cpu_map__intersect(struct perf_cpu_map *orig, struct perf_cpu_map *other) { - struct perf_cpu *tmp_cpus; - int tmp_len; int i, j, k; - struct perf_cpu_map *merged =3D NULL; + struct perf_cpu_map *merged; =20 if (perf_cpu_map__is_subset(other, orig)) return perf_cpu_map__get(orig); if (perf_cpu_map__is_subset(orig, other)) return perf_cpu_map__get(other); =20 - tmp_len =3D max(__perf_cpu_map__nr(orig), __perf_cpu_map__nr(other)); - tmp_cpus =3D malloc(tmp_len * sizeof(struct perf_cpu)); - if (!tmp_cpus) + i =3D j =3D k =3D 0; + while (i < __perf_cpu_map__nr(orig) && j < __perf_cpu_map__nr(other)) { + if (__perf_cpu_map__cpu(orig, i).cpu < __perf_cpu_map__cpu(other, j).cpu) + i++; + else if (__perf_cpu_map__cpu(orig, i).cpu > __perf_cpu_map__cpu(other, j= ).cpu) + j++; + else { /* CPUs match. */ + i++; + j++; + k++; + } + } + if (k =3D=3D 0) /* Maps are completely disjoint. */ return NULL; =20 + merged =3D perf_cpu_map__alloc(k); + if (!merged) + return NULL; + /* Entries are added to merged in sorted order, so no need to sort again.= */ i =3D j =3D k =3D 0; while (i < __perf_cpu_map__nr(orig) && j < __perf_cpu_map__nr(other)) { if (__perf_cpu_map__cpu(orig, i).cpu < __perf_cpu_map__cpu(other, j).cpu) @@ -476,11 +488,8 @@ struct perf_cpu_map *perf_cpu_map__intersect(struct pe= rf_cpu_map *orig, j++; else { j++; - tmp_cpus[k++] =3D __perf_cpu_map__cpu(orig, i++); + RC_CHK_ACCESS(merged)->map[k++] =3D __perf_cpu_map__cpu(orig, i++); } } - if (k) - merged =3D cpu_map__trim_new(k, tmp_cpus); - free(tmp_cpus); return merged; } --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (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 50FE334F486 for ; Thu, 13 Nov 2025 18:05:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057148; cv=none; b=hstlDy7hCAIlxMeHh3IwH8HBPLsY2cN2XjhjdHUINE80txIwpjcdBA1k4h/MGpsXXnCtfCU1vhKmeZnri3b717k2O5KQ4nMlmUIrLvXCFpUGOPOGhKYnf8FoZvHB1qzL+peSPQ2YKT6gqyePYbzlRQmDAngSdVDISm+AOMdaX8o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057148; c=relaxed/simple; bh=Kgo7sxJNHAVdmzHf5VuG0p/PQfK1697phqEp6Xwcyo0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=XBTItfSJkpWRRcftodc99o4hvypUMhIrkW1jFy6/5xDbn1pRARZo9SHOjX2qMwJR33Cfk3TpTvLdV24Sx9aKaFO6srHHJlB1igXF9TEZeEU4rdojlK9PfiR+tBNyatCPV9J2/dFvClY1pZ0Zs9kIksp/zeYemI7n0Oct6522Sj8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=mkxLh1Qu; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="mkxLh1Qu" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b99763210e5so1078961a12.3 for ; Thu, 13 Nov 2025 10:05:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057147; x=1763661947; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=PLwg+2AiO3F/YfbdpvnrnBijRms/bsxixJsYS/jBPB8=; b=mkxLh1Qu4AFd3Ts3SYZtceIj/gBo6/jXqiJwrBjtPQtKxFcd8NRwYzd6I18gzmGGW8 BsGaYbci91Y2O4h8gUoNCNoGBegpvsLVWOy7RpSperd3fjsNyJeAIjZ2z9ntPCa/VICv 9hIV4NzIlgjR1TxTbBz9+RCmz4JGxRtJlwvhpzsaD2PoMoe7oJ0uAU8dAU/oUtOOkl8m ksOAZxEHD1YRHwGkJBXXSr/G+hn27InamWJddFQFu0URVx61WnXPzvcXFtHlHrZkNEZm QjZfWN5zwo+ZiOyqKknQqZv+u+TK9+6Sa6jNxddLFucKWOI/5xOdgESVkG7uQ0DH+ulY vFgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057147; x=1763661947; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PLwg+2AiO3F/YfbdpvnrnBijRms/bsxixJsYS/jBPB8=; b=FeGwRMAiCv3M7hbFATF9GUAMgJiDnWIs5xt9Gw6/4OIYidkF7+MgLhaDXTPFssMFTa d9Jd/gq6s9zie41owRxf5x3PQ7N5ylK4SGmbGsf+KjbArfNi+haaQZW7oddFiiBwHjxV IAyZfIit2Jbb3gr/juIKf6qtnloMQATeMb3bedVMEcaSsmNffICj0XHebSQu4ySgQwko rniJVFkSE97axHseGPIAT7wEgOoKbKL1SHk0Gd61uDByaO9dX0zmd1xbKJoq3QhvuFiV 0+pznzcKmPeYVGhXt01q2OXC4IyhtIuKc3qsaUR2trelYnSPeHuBZRzYo8biPDf3K8ds /tyg== X-Forwarded-Encrypted: i=1; AJvYcCWpXvp1nOw3VfRfRTpBufvUKBjYQA+5vM5uaAdeiORTmK8lMpybEm5J9jtUsYPKwwdGDrpDidKORL9/WeM=@vger.kernel.org X-Gm-Message-State: AOJu0Yz9JGCjzVcQdE9S1n2V9nHu1hOrojDFpwpY+ri8Rw9U6GUfMPLA HxNRwPQYaVsr83ruUmkZq8yH0Yt3F/DKP8j3VOtz97u9VAQHJmSP/K6igF8Q9VShmPRAzsabJsI /76DcnbZaJg== X-Google-Smtp-Source: AGHT+IFbajqAQB2d6aMONKVtiXudHvRLHNhAEQeFC1FWchyERaniAWCZhVAeMlCzIly02rNyk9QLl/YT3gO5 X-Received: from dlbbq7.prod.google.com ([2002:a05:7022:6707:b0:11b:65e:f6a]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:ce8e:b0:2a4:3593:6453 with SMTP id 5a478bee46e88-2a4ab88119cmr103806eec.3.1763057146678; Thu, 13 Nov 2025 10:05:46 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:08 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-3-irogers@google.com> Subject: [PATCH v4 02/10] perf pmu: perf_cpu_map__new_int to avoid parsing a string From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Prefer perf_cpu_map__new_int(0) to perf_cpu_map__new("0") as it avoids strings parsing. Signed-off-by: Ian Rogers --- tools/perf/util/drm_pmu.c | 2 +- tools/perf/util/hwmon_pmu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/drm_pmu.c b/tools/perf/util/drm_pmu.c index 98d4d2b556d4..fc864bde4cb2 100644 --- a/tools/perf/util/drm_pmu.c +++ b/tools/perf/util/drm_pmu.c @@ -119,7 +119,7 @@ static struct drm_pmu *add_drm_pmu(struct list_head *pm= us, char *line, size_t li return NULL; } =20 - drm->pmu.cpus =3D perf_cpu_map__new("0"); + drm->pmu.cpus =3D perf_cpu_map__new_int(0); if (!drm->pmu.cpus) { perf_pmu__delete(&drm->pmu); return NULL; diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c index 5c27256a220a..279d6b1a47f0 100644 --- a/tools/perf/util/hwmon_pmu.c +++ b/tools/perf/util/hwmon_pmu.c @@ -376,7 +376,7 @@ struct perf_pmu *hwmon_pmu__new(struct list_head *pmus,= const char *hwmon_dir, perf_pmu__delete(&hwm->pmu); return NULL; } - hwm->pmu.cpus =3D perf_cpu_map__new("0"); + hwm->pmu.cpus =3D perf_cpu_map__new_int(0); if (!hwm->pmu.cpus) { perf_pmu__delete(&hwm->pmu); return NULL; --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (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 90B5D35970C for ; Thu, 13 Nov 2025 18:05:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057151; cv=none; b=otLFuATu70kGtGu07nDHvUvl+s5YMSJgIzL0EoajXYI27Zq7LKikVsQXa49ZguqE7vmlkVFQj+Rv8hLBtzM+c7A/GzBHL2I6k8odVcftYVoqdejIcKtkxMOxp8hh1f8vxBMGAzybcfkp2NKIw91nR6Ts9NWP5LGYW11vbtMdNrU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057151; c=relaxed/simple; bh=74ic2NR19Qj1jkhqoFr5/GAzNGfc9K6j6Uwf4Hjc/ss=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=KYLQJincppqa5OLzqY1o93rAUggqNx+fjWVPfZTps+GwJ8evpA/b2yaInnfUYgXUIL6p6sdkN+V1rhAHD+SPW8gxDQop6h24L9NXmRSkSceTooFVrUuQ1OiuLhiwT369AT7rieysgknoABFDkt/XTCKrKjkadVvoaBVCDljgNtI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=mri/KYzG; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="mri/KYzG" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b99763210e5so1078997a12.3 for ; Thu, 13 Nov 2025 10:05:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057149; x=1763661949; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=JvaqfEqqQj/hZXmBgRInugRb7NiwpIIhCyLsGdqnH4o=; b=mri/KYzGgwNibHkgXkR6nA8YW7d7+yF4GCCymoKxubSUAMemno6qhBFsk+x6Ng8MC3 bo2W5Har5/+mQrt0JDaTCT12rV1YUFBsWYdIjOUcZWi9Vr8NqNt1jtIAdsT8VbTbVaKI wacYDUBBMHc4uUPMrwT6nbe3oMhW1J58g8FcHCkYNW4XSsrq6CPQlUzkw6IS3K9Gz6Ol LusZ43K+033Pm3IEKJcZQj7FKCCDrEy6p8DU7cS67OECI6hg5VgmZhQl+8yHIanof7Og zSbHeeItWQhY4XNFAXabmDIlUSAQBB6yaC85ZRIexyofaEWG2Jb54tWA5F73ztpXbBaF dzRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057149; x=1763661949; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JvaqfEqqQj/hZXmBgRInugRb7NiwpIIhCyLsGdqnH4o=; b=goYvWjuP0dw6C5sgn5FPcGCvoy90ZiNwMC9C/tdYmXvu91zIdioJBcyibUf5UQ+Ibk CDDcw/y5CbS5Q6j6YxcC3ZfLHdgi6GjgQdmV93tAxJu8hAMEwi+DtJpphawF7At3aF5V v7eN1JZnhslrA43Md0CsS2z3Gauxjt67dOEOWcsQzyuQU3BZ0+2Pzss7PgwjXA4Geaoo HnFRLdqgFITCzsRb5xlQHWSyZf7M6VMlEJlcTqBXe/qSRz4q+a0Veo5Vp/7DdZEdqWU1 vH2Fn4g0qVwq64Iq4aGZE2qLr/IS7dzbL909iwwoalUBo4QL/3gNIe4JIu1amXyg5Rr5 FTcw== X-Forwarded-Encrypted: i=1; AJvYcCXSV3o6VVMWWuDKhHQRKOGFB+LwX62xlPS4ak99IBJPqNUS/NSZt8x0rTA+TYERIsk7Zdi3Lm0DoN/KdVA=@vger.kernel.org X-Gm-Message-State: AOJu0YzCR/EkY2TAZ6HFI0wcpV1zpcelT8X5QR6Au25FakfhCcgijT+9 GzVK6OTAYjQlTqQf2QcA9KejSb+Zhkfiunu4A0uMvZYs19jsB9PzfqZTqNkP57jXv9hq9rARCBf jUTtVeWZ9hw== X-Google-Smtp-Source: AGHT+IF0NwPOIq3TmGs4pfWbaVyz7eK77f2zPBftHfCowiKCgIk6oaj+NWaIDUfX61uCgGqUhOiGvhsMQt2A X-Received: from dycne3.prod.google.com ([2002:a05:7301:c83:b0:2a4:51e8:c5c8]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:bc1a:b0:2a4:3593:6466 with SMTP id 5a478bee46e88-2a4abb1cf05mr160511eec.22.1763057148729; Thu, 13 Nov 2025 10:05:48 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:09 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-4-irogers@google.com> Subject: [PATCH v4 03/10] perf tool_pmu: Use old_count when computing count values for time events From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When running in interval mode every third count of a time event isn't showing properly: ``` $ perf stat -e duration_time -a -I 1000 1.001082862 1,002,290,425 duration_time 2.004264262 1,003,183,516 duration_time 3.007381401 duration_time 4.011160141 1,003,705,631 duration_time 5.014515385 1,003,290,110 duration_time 6.018539680 duration_time 7.022065321 1,003,591,720 duration_time ``` The regression came in with a different fix, found through bisection, commit 68cb1567439f ("perf tool_pmu: Fix aggregation on duration_time"). The issue is caused by the enabled and running time of the event matching the old_count's and creating a delta of 0, which is indicative of an error. Fixes: 68cb1567439f ("perf tool_pmu: Fix aggregation on duration_time") Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 16 +++++++++-- tools/perf/util/tool_pmu.c | 59 +++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 095016b2209e..654f840f7a2f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -283,17 +283,27 @@ static int read_single_counter(struct evsel *counter,= int cpu_map_idx, int threa if (err && cpu_map_idx =3D=3D 0 && (evsel__tool_event(counter) =3D=3D TOOL_PMU__EVENT_USER_TIME || evsel__tool_event(counter) =3D=3D TOOL_PMU__EVENT_SYSTEM_TIME)) { - u64 val, *start_time; struct perf_counts_values *count =3D perf_counts(counter->counts, cpu_map_idx, thread); + struct perf_counts_values *old_count =3D NULL; + u64 val; + + if (counter->prev_raw_counts) + old_count =3D perf_counts(counter->prev_raw_counts, cpu_map_idx, thread= ); =20 - start_time =3D xyarray__entry(counter->start_times, cpu_map_idx, thread); if (evsel__tool_event(counter) =3D=3D TOOL_PMU__EVENT_USER_TIME) val =3D ru_stats.ru_utime_usec_stat.mean; else val =3D ru_stats.ru_stime_usec_stat.mean; - count->ena =3D count->run =3D *start_time + val; + count->val =3D val; + if (old_count) { + count->run =3D old_count->run + 1; + count->ena =3D old_count->ena + 1; + } else { + count->run++; + count->ena++; + } return 0; } return err; diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index a72c665ee644..6a9df3dc0e07 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -446,16 +446,39 @@ bool tool_pmu__read_event(enum tool_pmu_event ev, } } =20 +static void perf_counts__update(struct perf_counts_values *count, + const struct perf_counts_values *old_count, + bool raw, u64 val) +{ + /* + * The values of enabled and running must make a ratio of 100%. The + * exact values don't matter as long as they are non-zero to avoid + * issues with evsel__count_has_error. + */ + if (old_count) { + count->val =3D raw ? val : old_count->val + val; + count->run =3D old_count->run + 1; + count->ena =3D old_count->ena + 1; + count->lost =3D old_count->lost; + } else { + count->val =3D val; + count->run++; + count->ena++; + count->lost =3D 0; + } +} + int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread) { __u64 *start_time, cur_time, delta_start; - u64 val; - int fd, err =3D 0; + int err =3D 0; struct perf_counts_values *count, *old_count =3D NULL; bool adjust =3D false; enum tool_pmu_event ev =3D evsel__tool_event(evsel); =20 count =3D perf_counts(evsel->counts, cpu_map_idx, thread); + if (evsel->prev_raw_counts) + old_count =3D perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); =20 switch (ev) { case TOOL_PMU__EVENT_HAS_PMEM: @@ -466,12 +489,11 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu= _map_idx, int thread) case TOOL_PMU__EVENT_NUM_PACKAGES: case TOOL_PMU__EVENT_SLOTS: case TOOL_PMU__EVENT_SMT_ON: - case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: case TOOL_PMU__EVENT_CORE_WIDE: case TOOL_PMU__EVENT_TARGET_CPU: - if (evsel->prev_raw_counts) - old_count =3D perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); - val =3D 0; + case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: { + u64 val =3D 0; + if (cpu_map_idx =3D=3D 0 && thread =3D=3D 0) { if (!tool_pmu__read_event(ev, evsel, stat_config.system_wide, @@ -481,16 +503,9 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_= map_idx, int thread) val =3D 0; } } - if (old_count) { - count->val =3D old_count->val + val; - count->run =3D old_count->run + 1; - count->ena =3D old_count->ena + 1; - } else { - count->val =3D val; - count->run++; - count->ena++; - } + perf_counts__update(count, old_count, /*raw=3D*/false, val); return 0; + } case TOOL_PMU__EVENT_DURATION_TIME: /* * Pretend duration_time is only on the first CPU and thread, or @@ -506,9 +521,9 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_m= ap_idx, int thread) case TOOL_PMU__EVENT_USER_TIME: case TOOL_PMU__EVENT_SYSTEM_TIME: { bool system =3D evsel__tool_event(evsel) =3D=3D TOOL_PMU__EVENT_SYSTEM_T= IME; + int fd =3D FD(evsel, cpu_map_idx, thread); =20 start_time =3D xyarray__entry(evsel->start_times, cpu_map_idx, thread); - fd =3D FD(evsel, cpu_map_idx, thread); lseek(fd, SEEK_SET, 0); if (evsel->pid_stat) { /* The event exists solely on 1 CPU. */ @@ -542,17 +557,9 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_= map_idx, int thread) if (adjust) { __u64 ticks_per_sec =3D sysconf(_SC_CLK_TCK); =20 - delta_start *=3D 1000000000 / ticks_per_sec; + delta_start *=3D 1e9 / ticks_per_sec; } - count->val =3D delta_start; - count->lost =3D 0; - /* - * The values of enabled and running must make a ratio of 100%. The - * exact values don't matter as long as they are non-zero to avoid - * issues with evsel__count_has_error. - */ - count->ena++; - count->run++; + perf_counts__update(count, old_count, /*raw=3D*/true, delta_start); return 0; } =20 --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (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 85CA0359FBE for ; Thu, 13 Nov 2025 18:05:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057153; cv=none; b=YZPbHC/ScRLsngMyxOm2SsxuR5Tk/+XgD1WxTSSAeGLIjNEBYvkf1taQZDNa9zMvytAc8+HE3En22+dxubmi2rxP8lkf3P1Ua688FF+JL4IDxAVAz56EJq+WME4NW6m1b9/2+DVlKi1idZo9gdIWnZBAfxYRsxIZ3FL67EsHgLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057153; c=relaxed/simple; bh=hVJICGlrUy8MMJWuUtg1ckaMNBO234W7zrw4C+CGyhw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=ZcNyxS+hqmaaaJCeYVEylKOOuhQttS/geap3hypja7nTNxZEBGbUFLhUhaiTZoHKYPCGhco40K7rCC1lyvpLoeS3RyDKGETNkLGvfTnbTHpuzTI6BQWHuJwXcIE4zesSNLjjpi5ab1Fa3oVdh768U5N6sT2DD0b8PzUXv3m+7U8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=q/IN6cYR; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="q/IN6cYR" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b95d06db747so1745506a12.1 for ; Thu, 13 Nov 2025 10:05:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057151; x=1763661951; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=g1FXHzBhA2SQQSmsUII/uTyO8cL2QPYiQNF1YetQubM=; b=q/IN6cYR5aISncm8WszH5O+k5QUcR+2VJG6+Yfdu4X0qmIig8sBmOQ2kbnrGZKOQES W0PA2GVuqHqfOByDtUez47QiSaNE+kno6cwAN27JvLTE8q7nHKdYAvzmJVuMgHkbcmDk c2sRJEdtYSstP72R4ipL+EcSlJXoPqDIHj40BuqMuvB75tJkfv9gD9giKGZijfBXmC8g 24AULUJrKElH9nhPBKxaEUHCfpiLckp0WLLWJHkMPN2NLB55ehhX1RyTRVDdNPqsT6C6 sLSVnYW6FB9AKR9dwrD+U6U5bZ5+YGY9q+c7oc7S88p1CgSvAZA7SY2PAvR8rDYkbm3F I57g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057151; x=1763661951; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=g1FXHzBhA2SQQSmsUII/uTyO8cL2QPYiQNF1YetQubM=; b=woExxGhkQgbbqfO7vQP7VzBtg3ZIJGOeOsK4a4Z3hcVZL7CochP8X29eDIRJ3S39B0 B1gNfjdrJQVyRr7Zt52UpRrWrc9v4KAjkgB0fmoeVwoGBVCmeRLGnvotthR3YbNEBkrc jvXz76cazy1WOhTY2GPYuVVSYqv4XvtzlsGcNczYp+9S/SZ1JMbSbDqf0lHvn4fk9DVI rxYK8r0bfbIBrCe1yAYmTp3r02KZYvRDpImlNACi6W6H90rgf93mXYppdrvEWUDnatfS CWHOwZAs2u2UnydGG8cN+LJA1Igo++vonslGwS1pIsyldMwiTBfJ26W20BY1/uI47YXs wXXQ== X-Forwarded-Encrypted: i=1; AJvYcCV+IQs+68jA3b+S0pxFPvQaNCpWkLAecxf29Lg/v3Wt0ytMGtPvk88JSTGgUT6s/yESf6/mG1p0d/6tiwU=@vger.kernel.org X-Gm-Message-State: AOJu0YxKY0waKSW1okdGoXmpRsLbBLxZyznNVtELW4aXqupIF59p38KN dvVcKOgSe5GxfL0NsYVNv5SJho3AO7BYWV9HKtIFmsoZ12smC2d7DprulReGHL+bCIOCKCSS3q3 p3bv8/tL4pw== X-Google-Smtp-Source: AGHT+IGtzsF5urWKveWPScCG0h+dMh3vXRquU320w0u1H20MqrHGTFvpU8Dd08FOYTy1HNYzKtEOtnJe5xyJ X-Received: from dykh19.prod.google.com ([2002:a05:7300:5713:b0:2a4:738e:9908]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:fd03:b0:2a4:3593:ccb9 with SMTP id 5a478bee46e88-2a4ab230e56mr118302eec.0.1763057150808; Thu, 13 Nov 2025 10:05:50 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:10 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-5-irogers@google.com> Subject: [PATCH v4 04/10] perf stat-shadow: Read tool events directly From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When reading time values for metrics don't use the globals updated in builtin-stat, just read the events as regular events. The only exception is for time events where nanoseconds need converting to seconds as metrics assume time metrics are in seconds. Signed-off-by: Ian Rogers --- tools/perf/util/stat-shadow.c | 149 +++++++++++++++------------------- 1 file changed, 66 insertions(+), 83 deletions(-) diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index b3b482e1808f..6c1ad78604e1 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -26,7 +26,32 @@ void perf_stat__reset_shadow_stats(void) memset(&ru_stats, 0, sizeof(ru_stats)); } =20 -static int prepare_metric(const struct metric_expr *mexp, +static bool tool_pmu__is_time_event(const struct perf_stat_config *config, + const struct evsel *evsel, int *tool_aggr_idx) +{ + enum tool_pmu_event event =3D evsel__tool_event(evsel); + int aggr_idx; + + if (event !=3D TOOL_PMU__EVENT_DURATION_TIME && + event !=3D TOOL_PMU__EVENT_USER_TIME && + event !=3D TOOL_PMU__EVENT_SYSTEM_TIME) + return false; + + if (config) { + cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) { + if (config->aggr_map->map[aggr_idx].cpu.cpu =3D=3D 0) { + *tool_aggr_idx =3D aggr_idx; + return true; + } + } + pr_debug("Unexpected CPU0 missing in aggregation for tool event.\n"); + } + *tool_aggr_idx =3D 0; /* Assume the first aggregation index works. */ + return true; +} + +static int prepare_metric(struct perf_stat_config *config, + const struct metric_expr *mexp, const struct evsel *evsel, struct expr_parse_ctx *pctx, int aggr_idx) @@ -36,93 +61,51 @@ static int prepare_metric(const struct metric_expr *mex= p, int i; =20 for (i =3D 0; metric_events[i]; i++) { + int source_count =3D 0, tool_aggr_idx; + bool is_tool_time =3D + tool_pmu__is_time_event(config, metric_events[i], &tool_aggr_idx); + struct perf_stat_evsel *ps =3D metric_events[i]->stats; + struct perf_stat_aggr *aggr; char *n; double val; - int source_count =3D 0; =20 - if (evsel__is_tool(metric_events[i])) { - struct stats *stats; - double scale; - - switch (evsel__tool_event(metric_events[i])) { - case TOOL_PMU__EVENT_DURATION_TIME: - stats =3D &walltime_nsecs_stats; - scale =3D 1e-9; - break; - case TOOL_PMU__EVENT_USER_TIME: - stats =3D &ru_stats.ru_utime_usec_stat; - scale =3D 1e-6; + /* + * If there are multiple uncore PMUs and we're not reading the + * leader's stats, determine the stats for the appropriate + * uncore PMU. + */ + if (evsel && evsel->metric_leader && + evsel->pmu !=3D evsel->metric_leader->pmu && + mexp->metric_events[i]->pmu =3D=3D evsel->metric_leader->pmu) { + struct evsel *pos; + + evlist__for_each_entry(evsel->evlist, pos) { + if (pos->pmu !=3D evsel->pmu) + continue; + if (pos->metric_leader !=3D mexp->metric_events[i]) + continue; + ps =3D pos->stats; + source_count =3D 1; break; - case TOOL_PMU__EVENT_SYSTEM_TIME: - stats =3D &ru_stats.ru_stime_usec_stat; - scale =3D 1e-6; - break; - case TOOL_PMU__EVENT_NONE: - pr_err("Invalid tool event 'none'"); - abort(); - case TOOL_PMU__EVENT_MAX: - pr_err("Invalid tool event 'max'"); - abort(); - case TOOL_PMU__EVENT_HAS_PMEM: - case TOOL_PMU__EVENT_NUM_CORES: - case TOOL_PMU__EVENT_NUM_CPUS: - case TOOL_PMU__EVENT_NUM_CPUS_ONLINE: - case TOOL_PMU__EVENT_NUM_DIES: - case TOOL_PMU__EVENT_NUM_PACKAGES: - case TOOL_PMU__EVENT_SLOTS: - case TOOL_PMU__EVENT_SMT_ON: - case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: - case TOOL_PMU__EVENT_CORE_WIDE: - case TOOL_PMU__EVENT_TARGET_CPU: - default: - pr_err("Unexpected tool event '%s'", evsel__name(metric_events[i])); - abort(); } - val =3D avg_stats(stats) * scale; - source_count =3D 1; - } else { - struct perf_stat_evsel *ps =3D metric_events[i]->stats; - struct perf_stat_aggr *aggr; - + } + /* Time events are always on CPU0, the first aggregation index. */ + aggr =3D &ps->aggr[is_tool_time ? tool_aggr_idx : aggr_idx]; + if (!aggr || !metric_events[i]->supported) { /* - * If there are multiple uncore PMUs and we're not - * reading the leader's stats, determine the stats for - * the appropriate uncore PMU. + * Not supported events will have a count of 0, which + * can be confusing in a metric. Explicitly set the + * value to NAN. Not counted events (enable time of 0) + * are read as 0. */ - if (evsel && evsel->metric_leader && - evsel->pmu !=3D evsel->metric_leader->pmu && - mexp->metric_events[i]->pmu =3D=3D evsel->metric_leader->pmu) { - struct evsel *pos; - - evlist__for_each_entry(evsel->evlist, pos) { - if (pos->pmu !=3D evsel->pmu) - continue; - if (pos->metric_leader !=3D mexp->metric_events[i]) - continue; - ps =3D pos->stats; - source_count =3D 1; - break; - } - } - aggr =3D &ps->aggr[aggr_idx]; - if (!aggr) - break; - - if (!metric_events[i]->supported) { - /* - * Not supported events will have a count of 0, - * which can be confusing in a - * metric. Explicitly set the value to NAN. Not - * counted events (enable time of 0) are read as - * 0. - */ - val =3D NAN; - source_count =3D 0; - } else { - val =3D aggr->counts.val; - if (!source_count) - source_count =3D evsel__source_count(metric_events[i]); - } + val =3D NAN; + source_count =3D 0; + } else { + val =3D aggr->counts.val; + if (is_tool_time) + val *=3D 1e-9; /* Convert time event nanoseconds to seconds. */ + if (!source_count) + source_count =3D evsel__source_count(metric_events[i]); } n =3D strdup(evsel__metric_id(metric_events[i])); if (!n) @@ -168,7 +151,7 @@ static void generic_metric(struct perf_stat_config *con= fig, pctx->sctx.user_requested_cpu_list =3D strdup(config->user_requested_cpu= _list); pctx->sctx.runtime =3D runtime; pctx->sctx.system_wide =3D config->system_wide; - i =3D prepare_metric(mexp, evsel, pctx, aggr_idx); + i =3D prepare_metric(config, mexp, evsel, pctx, aggr_idx); if (i < 0) { expr__ctx_free(pctx); return; @@ -229,7 +212,7 @@ double test_generic_metric(struct metric_expr *mexp, in= t aggr_idx) if (!pctx) return NAN; =20 - if (prepare_metric(mexp, /*evsel=3D*/NULL, pctx, aggr_idx) < 0) + if (prepare_metric(/*config=3D*/NULL, mexp, /*evsel=3D*/NULL, pctx, aggr_= idx) < 0) goto out; =20 if (expr__parse(&ratio, pctx, mexp->metric_expr)) --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (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 ACE7E35A13F for ; Thu, 13 Nov 2025 18:05:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057155; cv=none; b=tpFoeEG1g268RMBNt0n6Db7kekMZiAL87YZr/BCB+0OnJ6ZDgngcef9cXErRgqg6UZ8q0Skp75kHD5CIhdQGfHlPXUyiflERAouAq3bMj8AWXbkJFuty0xosFdf2eeLFeoEYH8Knti4qKsJC5aoSfIO5s+9G9NWAltd02XL1q+w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057155; c=relaxed/simple; bh=uV3AqahuvBOAec4rbwf3PNsJdf98h98d2CbuPAwnjNo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=RwOWi9N/LdJvAPSLPKBdRhFTTfkE667ff7wV6Vg6yLTxTBF05nawktVzLYZHA99nkBxhYsD/BukLYw7CMamU4XNXg/Ji7LB+rkJUZAw8oiYywTQakhrdh3OwNVT4ogeFZHoLG7f/6OyTgSamyESRiN6Ds+vW1cvMZcIX2jsNTpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Lsq11ilV; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Lsq11ilV" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-bc316e9d60eso1017840a12.1 for ; Thu, 13 Nov 2025 10:05:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057153; x=1763661953; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=MEiCVcfmBq7/07PDARSKfpxXyKmbnJgNjTv23W0kYR0=; b=Lsq11ilV25+4mCxwa2bWiQuZx0CV9GCMwgd4VC94bmeN55hCkhP30LRbBqmXhX2eCi FNsLLHtZRlXkKk3HuOk4Gr5rzzs3y79kUMGQ9539riyZxSwlA1QdNsTb6DEr81PzHOmb FhGSHZvmctmqPIta2smBLmruhTskrc79rhMvx879FDX6+/WHNxAm+OIg9O9Dyk2GN2FA Ewy5v7jxoahVQvrjKFYhlN2+N3+Y8JKlpEkVRS73ZqLFCa2Ujjl4SjwuIy0UEQzxvXlq dhHh6r0nrLLAGNex5Q1VTQqIcVy38LoDnKg9PNixR8UyvFogBLQ//hmRe0aARjxs0GZg 23OQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057153; x=1763661953; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=MEiCVcfmBq7/07PDARSKfpxXyKmbnJgNjTv23W0kYR0=; b=HJNFl4h+umI+pg7jTmEhPegQuN5PRFyUU3XqCponHl5V2ZRHDr+O03OGaDGXI6vs25 y4Qj2kfdWQ8xcNREDg18bYNMiGCWrXLvfviR9ZZeXqhmf3nvPQoTHK7+FGx/IvvEgXx9 x85qQOlWwYacS0ZrgMyrsjgnwj5cNUp95+j9Eiwf7JFbB5tbsSwYcKEfPsTCPq97B+r6 kWhH4R9trXx3v/170peCPnZSiW0WZhSRB0NVbsrOcaR4iJhDZVg8u9WmATTt+UEVMMys ENitP2V53BYQP/eKQx/MtgMvtll8Nz+JEf8KYBe8g5P17ged/Te9lnk4n7zAxfQ6KhRs NL6A== X-Forwarded-Encrypted: i=1; AJvYcCWz9oDcIyxc1vdU6jTKtMq/D1FxLeEivq8oZuguRmM/95npgGu32ZcgOuD3RuRK81evhaqpWlTnUNZoOv0=@vger.kernel.org X-Gm-Message-State: AOJu0YxNiyKOOfLTHzwsv3PGwitJ0I5Vydkcwxa3WiTsUAlw/3yw8McU tx9aJnnjyPmOSjLrgBFdfcip5qATKmIr/dMlBSN+u75ImfLLWnxpUcfg0VWDDjdgrX5IIHYBDRF fzBApZ5GAtA== X-Google-Smtp-Source: AGHT+IGlqFaqOqL8Z5qwpdJ2PvxfOLh9uRRj8qgwXUyX3PabwIarjuBObD5fLJzc8iTeTO7Mp1A5S+tlFZzh X-Received: from dycuf3.prod.google.com ([2002:a05:7300:103:b0:2a4:5a4a:cc6d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:bc1a:b0:2a4:3593:6466 with SMTP id 5a478bee46e88-2a4abb1cf05mr160639eec.22.1763057153014; Thu, 13 Nov 2025 10:05:53 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:11 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-6-irogers@google.com> Subject: [PATCH v4 05/10] perf stat: Reduce scope of ru_stats From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The ru_stats are used to capture user and system time stats when a process exits. These are then applied to user and system time tool events if their reads fail due to the process terminating. Reduce the scope now the metric code no longer reads these values. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 19 ++++++++++++++++++- tools/perf/util/config.c | 1 - tools/perf/util/stat-shadow.c | 2 -- tools/perf/util/stat.h | 21 --------------------- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 654f840f7a2f..d6f4c84f7d7e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -104,6 +104,11 @@ #define DEFAULT_SEPARATOR " " #define FREEZE_ON_SMI_PATH "bus/event_source/devices/cpu/freeze_on_smi" =20 +struct rusage_stats { + struct stats ru_utime_usec_stat; + struct stats ru_stime_usec_stat; +}; + static void print_counters(struct timespec *ts, int argc, const char **arg= v); =20 static struct evlist *evsel_list; @@ -133,6 +138,7 @@ static bool interval_count; static const char *output_name; static int output_fd; static char *metrics; +static struct rusage_stats ru_stats; =20 struct perf_stat { bool record; @@ -730,6 +736,17 @@ static int create_perf_stat_counter(struct evsel *evse= l, evsel->core.threads); } =20 +static void update_rusage_stats(const struct rusage *rusage) +{ + const u64 us_to_ns =3D 1000; + const u64 s_to_ns =3D 1000000000; + + update_stats(&ru_stats.ru_utime_usec_stat, + (rusage->ru_utime.tv_usec * us_to_ns + rusage->ru_utime.tv_sec * s_to_ns= )); + update_stats(&ru_stats.ru_stime_usec_stat, + (rusage->ru_stime.tv_usec * us_to_ns + rusage->ru_stime.tv_sec * s_to_ns= )); +} + static int __run_perf_stat(int argc, const char **argv, int run_idx) { int interval =3D stat_config.interval; @@ -979,7 +996,7 @@ static int __run_perf_stat(int argc, const char **argv,= int run_idx) evlist__reset_aggr_stats(evsel_list); } else { update_stats(&walltime_nsecs_stats, t1 - t0); - update_rusage_stats(&ru_stats, &stat_config.ru_data); + update_rusage_stats(&stat_config.ru_data); } =20 /* diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 6f914620c6ff..cc0746f494f4 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -45,7 +45,6 @@ struct perf_stat_config stat_config =3D { .run_count =3D 1, .metric_only_len =3D METRIC_ONLY_LEN, .walltime_nsecs_stats =3D &walltime_nsecs_stats, - .ru_stats =3D &ru_stats, .big_num =3D true, .ctl_fd =3D -1, .ctl_fd_ack =3D -1, diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 6c1ad78604e1..cb7c741a1ebb 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -18,12 +18,10 @@ #include "tool_pmu.h" =20 struct stats walltime_nsecs_stats; -struct rusage_stats ru_stats; =20 void perf_stat__reset_shadow_stats(void) { memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats)); - memset(&ru_stats, 0, sizeof(ru_stats)); } =20 static bool tool_pmu__is_time_event(const struct perf_stat_config *config, diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index b42da4a29c44..055b95d18106 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -56,11 +56,6 @@ enum aggr_mode { AGGR_MAX }; =20 -struct rusage_stats { - struct stats ru_utime_usec_stat; - struct stats ru_stime_usec_stat; -}; - typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *confi= g, struct perf_cpu cpu); =20 struct perf_stat_config { @@ -102,7 +97,6 @@ struct perf_stat_config { const char *csv_sep; struct stats *walltime_nsecs_stats; struct rusage ru_data; - struct rusage_stats *ru_stats; struct cpu_aggr_map *aggr_map; aggr_get_id_t aggr_get_id; struct cpu_aggr_map *cpus_aggr_map; @@ -132,25 +126,10 @@ static inline void init_stats(struct stats *stats) stats->max =3D 0; } =20 -static inline void init_rusage_stats(struct rusage_stats *ru_stats) { - init_stats(&ru_stats->ru_utime_usec_stat); - init_stats(&ru_stats->ru_stime_usec_stat); -} - -static inline void update_rusage_stats(struct rusage_stats *ru_stats, stru= ct rusage* rusage) { - const u64 us_to_ns =3D 1000; - const u64 s_to_ns =3D 1000000000; - update_stats(&ru_stats->ru_utime_usec_stat, - (rusage->ru_utime.tv_usec * us_to_ns + rusage->ru_utime.tv_s= ec * s_to_ns)); - update_stats(&ru_stats->ru_stime_usec_stat, - (rusage->ru_stime.tv_usec * us_to_ns + rusage->ru_stime.tv_s= ec * s_to_ns)); -} - struct evsel; struct evlist; =20 extern struct stats walltime_nsecs_stats; -extern struct rusage_stats ru_stats; =20 enum metric_threshold_classify { METRIC_THRESHOLD_UNKNOWN, --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (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 693A335A134 for ; Thu, 13 Nov 2025 18:05:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057157; cv=none; b=FAanttEejZ3f/7PpdixZ6nnO5MGMTubfj1QQ+AQH+0dY5hxktkMTXLZi0Hk5g8s7mB2XtWl8pxOVqNzlwwgC1aqBMpWaFE7rop8qIRY17dEWMefPwCRQpGeeEav71ihQ1FAmK8vl5YTQbOGP6S6UT5x0iC+Wnlt6YTWsGwuYf/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057157; c=relaxed/simple; bh=fEvoaHFmoaJ+2+tIFCMQtgnwukgReVbMkmGkb5xkpR4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=MPLod9xZOzZe3zQClbzREa117S3OvH59pf2GdZq3vETwmea2zX/KeYm2quCk6Esu8WVB9d6AmuENQOiMrwlr4FqOR8+gS+UgOMceH3dR/BzbSnkD3KaWbkI2UuG2nPO4iLYDeYau1rwZV/2kR/ekLaqAJISLyyA6iBLmfG4hvEE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=yHpnY4+Y; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="yHpnY4+Y" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b9b9e8b0812so2479654a12.0 for ; Thu, 13 Nov 2025 10:05:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057155; x=1763661955; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=41JzJBl0/lQZ4jR+Z1Nm/tB7c9vLw1945nKhgQp8mD0=; b=yHpnY4+YmmyuMkG0W1JSEgqpmvUjwuMo418YfPm9tP3zKa3CSWr7pe1PHh4ooR+io8 V4xneKqiTk6Bn277+rETQtdciZuB7X7A336lJlpB9dSLu1CHxoQM9Ohr1+5fjjGk1nCi FHuX/hlBZIEcfPBRezZscRky2SOJ2eG91e88sS36mW5lx2gpxGVtVjxNqWJ3nGRSdSlv TH6k1IiiyeMz+CxMkJ3wbzsT4t0UAJBTRDSDsy6jO0Vyvnp64O+BvifW9pnefJp6WjJa /Nt9KK6P4vv0ASMs5xbzuOk8hAOU0CNQLHpD16zW2uhULCg44pU40XRptoYFw6H83EMp Gf0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057155; x=1763661955; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=41JzJBl0/lQZ4jR+Z1Nm/tB7c9vLw1945nKhgQp8mD0=; b=oPvwBxyFY4ad9x4Q/q+DtbHVOVeVMmtEuPZgx/psC/LeKs+639pzcP21UAxfbdYIH0 nfZIHnnNEAEFcwETeGKzXGRtuL3ggu8brqFg4GByBEmM+Z1HwhPWgmfZEtfvfFbadCTc nREJhgwUYs5nR6KP+9fuSREStrZShfQXPejF9jzC6Al0Ndo2gUJlz/mP81WzSlgJljMu vEGoHioim78EVybIYy2mnP9FYPa+Dhf20vT9zBPMqj2r7XRJtmVPQFJuwdkWI6N7SNoS sDgrUn3uaeYr7+bezizxh7c0X1vk5qckHwvNc9swURZs/qcMyncF4B5om4pqWSQ0LMPF 6nEA== X-Forwarded-Encrypted: i=1; AJvYcCVhl2dEUx1blHzGaCswwGCIwi3Yoq5lvQblRgD4B8Evg47L3XjGomSgb9bIKC8iN7tB6vmdvh3x9CVt8OM=@vger.kernel.org X-Gm-Message-State: AOJu0YxMIaV1l0T2B2C40J7nMES64t4YJukGEQJwGZstLBO2E9p5fAyJ okRZYVlb2vyxTx76CpJKmORzLiyVkDCMjfEQa6zRClj5kfFkfkDGFv20QvWETIBMhqE9J6MlQn0 Z927G19LgCw== X-Google-Smtp-Source: AGHT+IHhm5PLUXvrIrKLsniSTSgeWCsqDeSP0Hg/Mc9l08DaMLq5jjeBC+yyy63MuLZMHCRAJ2hL1QDSthUq X-Received: from dlbbs44.prod.google.com ([2002:a05:7022:92c:b0:119:9f33:34a9]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:7e07:b0:119:e56c:189e with SMTP id a92af1059eb24-11b40f9ee6dmr162862c88.6.1763057154836; Thu, 13 Nov 2025 10:05:54 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:12 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-7-irogers@google.com> Subject: [PATCH v4 06/10] perf stat: Reduce scope of walltime_nsecs_stats From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" walltime_nsecs_stats is no longer used for counter values, move into that stat_config where it controls certain things like noise measurement. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 16 ++++++++-------- tools/perf/tests/parse-metric.c | 2 -- tools/perf/tests/pmu-events.c | 2 -- tools/perf/util/config.c | 2 ++ tools/perf/util/stat-shadow.c | 7 ------- tools/perf/util/stat.h | 2 -- 6 files changed, 10 insertions(+), 21 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d6f4c84f7d7e..ca1c80c141b6 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -239,7 +239,7 @@ static inline void diff_timespec(struct timespec *r, st= ruct timespec *a, static void perf_stat__reset_stats(void) { evlist__reset_stats(evsel_list); - perf_stat__reset_shadow_stats(); + memset(stat_config.walltime_nsecs_stats, 0, sizeof(*stat_config.walltime_= nsecs_stats)); } =20 static int process_synthesized_event(const struct perf_tool *tool __maybe_= unused, @@ -455,8 +455,8 @@ static void process_interval(void) pr_err("failed to write stat round event\n"); } =20 - init_stats(&walltime_nsecs_stats); - update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000ULL); + init_stats(stat_config.walltime_nsecs_stats); + update_stats(stat_config.walltime_nsecs_stats, stat_config.interval * 100= 0000ULL); print_counters(&rs, 0, NULL); } =20 @@ -988,14 +988,14 @@ static int __run_perf_stat(int argc, const char **arg= v, int run_idx) if (interval && stat_config.summary) { stat_config.interval =3D 0; stat_config.stop_read_counter =3D true; - init_stats(&walltime_nsecs_stats); - update_stats(&walltime_nsecs_stats, t1 - t0); + init_stats(stat_config.walltime_nsecs_stats); + update_stats(stat_config.walltime_nsecs_stats, t1 - t0); =20 evlist__copy_prev_raw_counts(evsel_list); evlist__reset_prev_raw_counts(evsel_list); evlist__reset_aggr_stats(evsel_list); } else { - update_stats(&walltime_nsecs_stats, t1 - t0); + update_stats(stat_config.walltime_nsecs_stats, t1 - t0); update_rusage_stats(&stat_config.ru_data); } =20 @@ -2167,7 +2167,7 @@ static int process_stat_round_event(const struct perf= _tool *tool __maybe_unused, process_counters(); =20 if (stat_round->type =3D=3D PERF_STAT_ROUND_TYPE__FINAL) - update_stats(&walltime_nsecs_stats, stat_round->time); + update_stats(stat_config.walltime_nsecs_stats, stat_round->time); =20 if (stat_config.interval && stat_round->time) { tsh.tv_sec =3D stat_round->time / NSEC_PER_SEC; @@ -2975,7 +2975,7 @@ int cmd_stat(int argc, const char **argv) } =20 if (!interval) { - if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL)) + if (WRITE_STAT_ROUND_EVENT(stat_config.walltime_nsecs_stats->max, FINAL= )) pr_err("failed to write stat round event\n"); } =20 diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 66a5275917e2..7ca0b0791677 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -40,8 +40,6 @@ static void load_runtime_stat(struct evlist *evlist, stru= ct value *vals) count =3D find_value(evsel->name, vals); evsel->supported =3D true; evsel->stats->aggr->counts.val =3D count; - if (evsel__name_is(evsel, "duration_time")) - update_stats(&walltime_nsecs_stats, count); } } =20 diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index f40a828c9861..a99716862168 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -872,8 +872,6 @@ static int test__parsing_callback(const struct pmu_metr= ic *pm, evlist__alloc_aggr_stats(evlist, 1); evlist__for_each_entry(evlist, evsel) { evsel->stats->aggr->counts.val =3D k; - if (evsel__name_is(evsel, "duration_time")) - update_stats(&walltime_nsecs_stats, k); k++; } evlist__for_each_entry(evlist, evsel) { diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index cc0746f494f4..e0219bc6330a 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -37,6 +37,8 @@ =20 #define METRIC_ONLY_LEN 20 =20 +static struct stats walltime_nsecs_stats; + struct perf_stat_config stat_config =3D { .aggr_mode =3D AGGR_GLOBAL, .aggr_level =3D MAX_CACHE_LVL + 1, diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index cb7c741a1ebb..69f09db0c945 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -17,13 +17,6 @@ #include "util/hashmap.h" #include "tool_pmu.h" =20 -struct stats walltime_nsecs_stats; - -void perf_stat__reset_shadow_stats(void) -{ - memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats)); -} - static bool tool_pmu__is_time_event(const struct perf_stat_config *config, const struct evsel *evsel, int *tool_aggr_idx) { diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 055b95d18106..f986911c9296 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -129,8 +129,6 @@ static inline void init_stats(struct stats *stats) struct evsel; struct evlist; =20 -extern struct stats walltime_nsecs_stats; - enum metric_threshold_classify { METRIC_THRESHOLD_UNKNOWN, METRIC_THRESHOLD_BAD, --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (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 9D6D635B142 for ; Thu, 13 Nov 2025 18:05:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057159; cv=none; b=bo1HU7Q6jrhyXvaTDBiTK3SYW0IljGk78fkjzdcLNjMMfByjkQwLLxkZdQcgqA7zKjYyLUXIIWvf5NIS2jpbbSqGJr/vGaCycXUjUIInPDQe5P7SE0NCibAGEOX/znIVSRJQjjJM4RGFsznwp7ysUOUvPVNIDtxFy8N9jT4HhGw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057159; c=relaxed/simple; bh=0f1TDzO6H6tB8Sqz0jVLsYxxLfA6IgKxvXEGC+7+pOU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=HrQGicJR85RysZIojxRWwN7FVGKN0CgwYl6lQKVf/IE6VfkNd7K0E9rK4fkbjHi/cuTisXG3uM00JexXt25yw3p5w2Ugs/yd/mXVqVjPPLutHFD4EfcJt7N1IuQmAViU/TNhKuZbgYe6dmH20tDFwaM24CUNclEloIqk5pGTJDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=2K4FzeLW; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="2K4FzeLW" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b9ceccbd7e8so2363853a12.0 for ; Thu, 13 Nov 2025 10:05:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057157; x=1763661957; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=YuP8PXUqe7Wr/8ISWkGnPVH1SBV8e8BOv5yyhohFapc=; b=2K4FzeLWkayKZCudP1am8VPGfIv1ILGf6uTpjQOG64yzus2VyHDMnAQhZBZEN+oW+j 6NR4ocLpQ8yw4TEko6zG7gLHdxyphyGyCQSeSWgiQ/TxTY7n1AbVoXpS/LbF0/mLBP1H csGoPbs0GT2RMPqdcpnKOwwM8axLTzc7O9/qxFq8rli6iLBl6oyebOIsUJgxL4/iS6EI aK73wcKuzDTNCQLXIivPuTvTOcQJblKSRiD6lUk6lDfYzzww3uDifMskz4SO61BmZ3eE NBDAPSZSTv7GS1DFKJQhtRjWQdXqvyyG6mOWnDC8VkXByZvLCOLixH+uLRKxSyMtBZpP 4yTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057157; x=1763661957; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=YuP8PXUqe7Wr/8ISWkGnPVH1SBV8e8BOv5yyhohFapc=; b=Ecp4mU5hurUJXPbbMQU3mq/h91X8xDXwUgrKl0A+A27wvJr5M7lQFPZz86qpU8kwgw TAY6TQ6ISjRtknoM7Vl/lkcpsoc5b+STKvXRft8XpDzYlsc6d23EecA/uvlYu555rtyC Q/rZS7WLAC8Jn9A97j40GIfJpMDwj1KEsYpbvUxWlD+Aa0niMCSD3HSRPOtWFeFwra+O y+kPDs/f7fDQrdO/yUdzs0GoQdf1mZRZkt8o3TfA7LU1e9BMgGszbVsVx9mHti++O6L9 wIZWJbGdwVHe5rhFfQG4YF1B1MLvLX4IQj1A8YjSnNGsSEUwRh0XEk86XvvWBerluOk9 Rsaw== X-Forwarded-Encrypted: i=1; AJvYcCXpXejE3wl2ChhSjuqkAXh5wTjyzqxwXeWkuSCbJd0YVYno3UWaPjsQjYta1rtd5CV3VPCGg4HAWTg6w8E=@vger.kernel.org X-Gm-Message-State: AOJu0YyusbQZhzhwtjWiKBUVJi+y2wrT76YWNEHI5BuUGr33j494q0TN rZ0yTpyp+68/3URUcRErxY1GsZp78l7QlIxQoDUoSWEdows9iw8c/Imebp7uYu8QpNT1o0aWGhd WyoF3GTuU+w== X-Google-Smtp-Source: AGHT+IG4tLWQG6Nhx7yV9QcYVY05Ov9bXvi/owMeYul8P75j8HZaUm6CF2k78DeEPMIywkJ59xIfi2JtS0wT X-Received: from dlbbq19.prod.google.com ([2002:a05:7022:6713:b0:11b:1a9a:d2e8]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:ef0f:b0:11b:dff:7830 with SMTP id a92af1059eb24-11b40fa3490mr182386c88.18.1763057156938; Thu, 13 Nov 2025 10:05:56 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:13 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-8-irogers@google.com> Subject: [PATCH v4 07/10] perf tool_pmu: More accurately set the cpus for tool events From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The user and system time events can record on different CPUs, but for all other events a single CPU map of just CPU 0 makes sense. In parse-events detect a tool PMU and then pass the perf_event_attr so that the tool_pmu can return CPUs specific for the event. This avoids a CPU map of all online CPUs being used for events like duration_time. Avoiding this avoids the evlist CPUs containing CPUs for which duration_time just gives 0. Minimizing the evlist CPUs can remove unnecessary sched_setaffinity syscalls that delay metric calculations. Signed-off-by: Ian Rogers --- tools/perf/util/parse-events.c | 9 +++++++-- tools/perf/util/tool_pmu.c | 19 +++++++++++++++++++ tools/perf/util/tool_pmu.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 0c0dc20b1c13..7b2422ccb554 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -30,6 +30,7 @@ #include "util/event.h" #include "util/bpf-filter.h" #include "util/stat.h" +#include "util/tool_pmu.h" #include "util/util.h" #include "tracepoint.h" #include @@ -227,8 +228,12 @@ __add_event(struct list_head *list, int *idx, if (pmu) { is_pmu_core =3D pmu->is_core; pmu_cpus =3D perf_cpu_map__get(pmu->cpus); - if (perf_cpu_map__is_empty(pmu_cpus)) - pmu_cpus =3D cpu_map__online(); + if (perf_cpu_map__is_empty(pmu_cpus)) { + if (perf_pmu__is_tool(pmu)) + pmu_cpus =3D tool_pmu__cpus(attr); + else + pmu_cpus =3D cpu_map__online(); + } } else { is_pmu_core =3D (attr->type =3D=3D PERF_TYPE_HARDWARE || attr->type =3D=3D PERF_TYPE_HW_CACHE); diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index 6a9df3dc0e07..37c4eae0bef1 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -2,6 +2,7 @@ #include "cgroup.h" #include "counts.h" #include "cputopo.h" +#include "debug.h" #include "evsel.h" #include "pmu.h" #include "print-events.h" @@ -13,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +111,23 @@ const char *evsel__tool_pmu_event_name(const struct ev= sel *evsel) return tool_pmu__event_to_str(evsel->core.attr.config); } =20 +struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr) +{ + static struct perf_cpu_map *cpu0_map; + enum tool_pmu_event event =3D (enum tool_pmu_event)attr->config; + + if (event <=3D TOOL_PMU__EVENT_NONE || event >=3D TOOL_PMU__EVENT_MAX) { + pr_err("Invalid tool PMU event config %llx\n", attr->config); + return NULL; + } + if (event =3D=3D TOOL_PMU__EVENT_USER_TIME || event =3D=3D TOOL_PMU__EVEN= T_SYSTEM_TIME) + return cpu_map__online(); + + if (!cpu0_map) + cpu0_map =3D perf_cpu_map__new_int(0); + return perf_cpu_map__get(cpu0_map); +} + static bool read_until_char(struct io *io, char e) { int c; diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h index f1714001bc1d..ea343d1983d3 100644 --- a/tools/perf/util/tool_pmu.h +++ b/tools/perf/util/tool_pmu.h @@ -46,6 +46,7 @@ bool tool_pmu__read_event(enum tool_pmu_event ev, u64 tool_pmu__cpu_slots_per_cycle(void); =20 bool perf_pmu__is_tool(const struct perf_pmu *pmu); +struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr); =20 bool evsel__is_tool(const struct evsel *evsel); enum tool_pmu_event evsel__tool_event(const struct evsel *evsel); --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (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 E422835B14F for ; Thu, 13 Nov 2025 18:05:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057162; cv=none; b=ejTDQJu1/lZmMvmlsQh9fKbVP2L1FsxuucksYVKhOJIGHJCX3AbH9hgeJuXV17B7g7+8qB1/bUAf5AdQ6gmV89jVLA+TM6PMr0QKPhXdL7JaprWC8DXcfqTaNxW41IbB7DYXq5eF2jEUm1Nt5YFJUnmIOxabnOS4uX2eWjuxQp4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057162; c=relaxed/simple; bh=tOCRp6q8cU4TvS3BW3hxq4YfZFgatWkJuBOP3VOz8ss=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=ZFv5CrG7u0a/uyf9Ami8CwHYi6yIshr3bw10j4Ogv+N8TibMPmnrPWEmQh65aIfUwzGa2Hb6U8eoYb2FpZ3UBeeyR2TDaWJbSGmJvQoGZxAourn75sH1sOh1I8lLelxcvB1uZheBoyhk+w+vwuQAG2pWr5uvccyPqYuZO5+tutE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=CZd7IqWD; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="CZd7IqWD" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-bc0de474d4eso2284674a12.0 for ; Thu, 13 Nov 2025 10:05:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057159; x=1763661959; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=F/LpTxscNWWRbaTmICukfm1cE/Qpboh07gAHjTodIzU=; b=CZd7IqWDtAk47dGGHBRcgWmqcprLVaVozudTCTul/QirWcbSX5rofJ5TAEvFAV1PYO 7C0EGhPjQT90OecaxNQ9AgNv7svHvuzmT39ERFOX9ty6Vfggo9ZAOTtcimjLrp69uZQ8 OCMdXBQKr1ga64vRpFdZ4AkiRLiULG6VjaYH54bJuTMbT2GsV68hIUZEDwad2HuuAfOl XwUtiSqiGdUb4Orv538ZENpggsiw8SZ/BJ/WT9h7rgdvd4T+X2jqPSt0fhid1fq8J4O4 iZQ+TgxSKUbnK7dcPGOR78fniX8Y0n8k0yZoow4bYQS8WSW7Ym4WeOrKvnayQ6GoNb5x Nsag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057159; x=1763661959; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=F/LpTxscNWWRbaTmICukfm1cE/Qpboh07gAHjTodIzU=; b=b766F3Xz07ikUVjIUHBbKLJEwIeYnk4jAEUMFuX7tU8VQ2PdrohshXSPcYEREw6mix Yb4wbBITf+Fr+nIR/QBQI3/QvwLkW6H93ZCiUMYIKylZadf5Kc91Sw0oP3n+h7Sd/fD0 xjpVoljZvYBwE8eLCMv9l4Qqd8WNIFzEcGuUb8DXa+Eaj4giDP2BNHHGW5WocwLD3QmU ZI4NqMbW/7qQJBOQLepupgAMVcYMk4GnCOnXXFlod+Co4kR1+D+oihEey0+9f6j0mbBK f+G05lPeYTB15Y5CkTnqKdQcT/iYzP+3D76JFmS0IiM1Laqu7kMf1j0cLAeSOwvq7DPQ J6yA== X-Forwarded-Encrypted: i=1; AJvYcCUIN/2dyrTjFp2EQ/bk1vYEHeS9EX+WLATfXax9O/kUxGmOZokCUd6mrA6yBk8mcVm2O+sxXHiGLxgImk8=@vger.kernel.org X-Gm-Message-State: AOJu0YxPth6ajkuCA7H2omwUbVV4k0/NhvGSmD6ZepUTMq4RlrGr+UCY TxW+SB6hs9Iyru943ajaklnTUYxNqQR/c+crSgJD8OAr40BPLPZaqwCGyF/dE2BafzO0ho76POD kumt3tJU/1g== X-Google-Smtp-Source: AGHT+IFbMUItGVTF42dSaK9s8x3Bi3vZ2OPTsK+hudUOLg8fchArlJqAlFXzGG/D1iZ6tcyeB6nMmOxz8k9/ X-Received: from dybma14.prod.google.com ([2002:a05:7301:168e:b0:2a4:4843:eafd]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:1288:b0:2a4:3592:cf6f with SMTP id 5a478bee46e88-2a4abb0328cmr151599eec.19.1763057159118; Thu, 13 Nov 2025 10:05:59 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:14 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-9-irogers@google.com> Subject: [PATCH v4 08/10] perf evlist: Reduce affinity use and move into iterator, fix no affinity From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The evlist__for_each_cpu iterator will call sched_setaffitinity when moving between CPUs to avoid IPIs. If only 1 IPI is saved then this may be unprofitable as the delay to get scheduled may be considerable. This may be particularly true if reading an event group in `perf stat` in interval mode. Move the affinity handling completely into the iterator so that a single evlist__use_affinity can determine whether CPU affinities will be used. For `perf record` the change is minimal as the dummy event and the real event will always make the use of affinities the thing to do. In `perf stat`, tool events are ignored and affinities only used if >1 event on the same CPU occur. Determining if affinities are useful is done by per-event in a new PMU benefits from affinity function. Fix a bug where when there are no affinities that the CPU map iterator may reference a CPU not present in the initial evsel. Fix by making the iterator and non-iterator code common. Fix a bug where closing events on an evlist wasn't closing TPEBS events. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 128 ++++++++++++++---------------- tools/perf/util/evlist.c | 160 ++++++++++++++++++++++++-------------- tools/perf/util/evlist.h | 26 +++++-- tools/perf/util/pmu.c | 12 +++ tools/perf/util/pmu.h | 1 + 5 files changed, 189 insertions(+), 138 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index ca1c80c141b6..947f11b8b106 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -366,22 +366,14 @@ static int read_counter_cpu(struct evsel *counter, in= t cpu_map_idx) return 0; } =20 -static int read_affinity_counters(void) +static int read_counters_with_affinity(void) { struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity; =20 if (all_counters_use_bpf) return 0; =20 - if (!target__has_cpu(&target) || target__has_per_thread(&target)) - affinity =3D NULL; - else if (affinity__setup(&saved_affinity) < 0) - return -1; - else - affinity =3D &saved_affinity; - - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { struct evsel *counter =3D evlist_cpu_itr.evsel; =20 if (evsel__is_bpf(counter)) @@ -390,8 +382,6 @@ static int read_affinity_counters(void) if (!counter->err) counter->err =3D read_counter_cpu(counter, evlist_cpu_itr.cpu_map_idx); } - if (affinity) - affinity__cleanup(&saved_affinity); =20 return 0; } @@ -414,12 +404,18 @@ static int read_bpf_map_counters(void) =20 static int read_counters(void) { - if (!stat_config.stop_read_counter) { - if (read_bpf_map_counters() || - read_affinity_counters()) - return -1; - } - return 0; + int ret; + + if (stat_config.stop_read_counter) + return 0; + + // Read all BPF counters first. + ret =3D read_bpf_map_counters(); + if (ret) + return ret; + + // Read non-BPF and non-tool counters next. + return read_counters_with_affinity(); } =20 static void process_counters(void) @@ -760,7 +756,6 @@ static int __run_perf_stat(int argc, const char **argv,= int run_idx) const bool forks =3D (argc > 0); bool is_pipe =3D STAT_RECORD ? perf_stat.data.is_pipe : false; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity =3D NULL; int err, open_err =3D 0; bool second_pass =3D false, has_supported_counters; =20 @@ -772,14 +767,6 @@ static int __run_perf_stat(int argc, const char **argv= , int run_idx) child_pid =3D evsel_list->workload.pid; } =20 - if (!cpu_map__is_dummy(evsel_list->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) { - err =3D -1; - goto err_out; - } - affinity =3D &saved_affinity; - } - evlist__for_each_entry(evsel_list, counter) { counter->reset_group =3D false; if (bpf_counter__load(counter, &target)) { @@ -792,49 +779,48 @@ static int __run_perf_stat(int argc, const char **arg= v, int run_idx) =20 evlist__reset_aggr_stats(evsel_list); =20 - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { - counter =3D evlist_cpu_itr.evsel; + /* + * bperf calls evsel__open_per_cpu() in bperf__load(), so + * no need to call it again here. + */ + if (!target.use_bpf) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { + counter =3D evlist_cpu_itr.evsel; =20 - /* - * bperf calls evsel__open_per_cpu() in bperf__load(), so - * no need to call it again here. - */ - if (target.use_bpf) - break; + if (counter->reset_group || !counter->supported) + continue; + if (evsel__is_bperf(counter)) + continue; =20 - if (counter->reset_group || !counter->supported) - continue; - if (evsel__is_bperf(counter)) - continue; + while (true) { + if (create_perf_stat_counter(counter, &stat_config, + evlist_cpu_itr.cpu_map_idx) =3D=3D 0) + break; =20 - while (true) { - if (create_perf_stat_counter(counter, &stat_config, - evlist_cpu_itr.cpu_map_idx) =3D=3D 0) - break; + open_err =3D errno; + /* + * Weak group failed. We cannot just undo this + * here because earlier CPUs might be in group + * mode, and the kernel doesn't support mixing + * group and non group reads. Defer it to later. + * Don't close here because we're in the wrong + * affinity. + */ + if ((open_err =3D=3D EINVAL || open_err =3D=3D EBADF) && + evsel__leader(counter) !=3D counter && + counter->weak_group) { + evlist__reset_weak_group(evsel_list, counter, false); + assert(counter->reset_group); + counter->supported =3D true; + second_pass =3D true; + break; + } =20 - open_err =3D errno; - /* - * Weak group failed. We cannot just undo this here - * because earlier CPUs might be in group mode, and the kernel - * doesn't support mixing group and non group reads. Defer - * it to later. - * Don't close here because we're in the wrong affinity. - */ - if ((open_err =3D=3D EINVAL || open_err =3D=3D EBADF) && - evsel__leader(counter) !=3D counter && - counter->weak_group) { - evlist__reset_weak_group(evsel_list, counter, false); - assert(counter->reset_group); - counter->supported =3D true; - second_pass =3D true; - break; + if (stat_handle_error(counter, open_err) !=3D COUNTER_RETRY) + break; } - - if (stat_handle_error(counter, open_err) !=3D COUNTER_RETRY) - break; } } - if (second_pass) { /* * Now redo all the weak group after closing them, @@ -842,7 +828,7 @@ static int __run_perf_stat(int argc, const char **argv,= int run_idx) */ =20 /* First close errored or weak retry */ - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { counter =3D evlist_cpu_itr.evsel; =20 if (!counter->reset_group && counter->supported) @@ -851,7 +837,7 @@ static int __run_perf_stat(int argc, const char **argv,= int run_idx) perf_evsel__close_cpu(&counter->core, evlist_cpu_itr.cpu_map_idx); } /* Now reopen weak */ - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { counter =3D evlist_cpu_itr.evsel; =20 if (!counter->reset_group) @@ -860,17 +846,18 @@ static int __run_perf_stat(int argc, const char **arg= v, int run_idx) while (true) { pr_debug2("reopening weak %s\n", evsel__name(counter)); if (create_perf_stat_counter(counter, &stat_config, - evlist_cpu_itr.cpu_map_idx) =3D=3D 0) + evlist_cpu_itr.cpu_map_idx) =3D=3D 0) { + evlist_cpu_iterator__exit(&evlist_cpu_itr); break; - + } open_err =3D errno; - if (stat_handle_error(counter, open_err) !=3D COUNTER_RETRY) + if (stat_handle_error(counter, open_err) !=3D COUNTER_RETRY) { + evlist_cpu_iterator__exit(&evlist_cpu_itr); break; + } } } } - affinity__cleanup(affinity); - affinity =3D NULL; =20 has_supported_counters =3D false; evlist__for_each_entry(evsel_list, counter) { @@ -1021,7 +1008,6 @@ static int __run_perf_stat(int argc, const char **arg= v, int run_idx) if (forks) evlist__cancel_workload(evsel_list); =20 - affinity__cleanup(affinity); return err; } =20 diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e8217efdda53..b6df81b8a236 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -358,36 +358,111 @@ int evlist__add_newtp(struct evlist *evlist, const c= har *sys, const char *name, } #endif =20 -struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct= affinity *affinity) +/* + * Should sched_setaffinity be used with evlist__for_each_cpu? Determine if + * migrating the thread will avoid possibly numerous IPIs. + */ +static bool evlist__use_affinity(struct evlist *evlist) +{ + struct evsel *pos; + struct perf_cpu_map *used_cpus =3D NULL; + bool ret =3D false; + + /* + * With perf record core.user_requested_cpus is usually NULL. + * Use the old method to handle this for now. + */ + if (!evlist->core.user_requested_cpus || + cpu_map__is_dummy(evlist->core.user_requested_cpus)) + return false; + + evlist__for_each_entry(evlist, pos) { + struct perf_cpu_map *intersect; + + if (!perf_pmu__benefits_from_affinity(pos->pmu)) + continue; + + if (evsel__is_dummy_event(pos)) { + /* + * The dummy event is opened on all CPUs so assume >1 + * event with shared CPUs. + */ + ret =3D true; + break; + } + if (evsel__is_retire_lat(pos)) { + /* + * Retirement latency events are similar to tool ones in + * their implementation, and so don't require affinity. + */ + continue; + } + if (perf_cpu_map__is_empty(used_cpus)) { + /* First benefitting event, we want >1 on a common CPU. */ + used_cpus =3D perf_cpu_map__get(pos->core.cpus); + continue; + } + if ((pos->core.attr.read_format & PERF_FORMAT_GROUP) && + evsel__leader(pos) !=3D pos) { + /* Skip members of the same sample group. */ + continue; + } + intersect =3D perf_cpu_map__intersect(used_cpus, pos->core.cpus); + if (!perf_cpu_map__is_empty(intersect)) { + /* >1 event with shared CPUs. */ + perf_cpu_map__put(intersect); + ret =3D true; + break; + } + perf_cpu_map__put(intersect); + perf_cpu_map__merge(&used_cpus, pos->core.cpus); + } + perf_cpu_map__put(used_cpus); + return ret; +} + +void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evl= ist *evlist) { - struct evlist_cpu_iterator itr =3D { + *itr =3D (struct evlist_cpu_iterator){ .container =3D evlist, .evsel =3D NULL, .cpu_map_idx =3D 0, .evlist_cpu_map_idx =3D 0, .evlist_cpu_map_nr =3D perf_cpu_map__nr(evlist->core.all_cpus), .cpu =3D (struct perf_cpu){ .cpu =3D -1}, - .affinity =3D affinity, + .affinity =3D NULL, }; =20 if (evlist__empty(evlist)) { /* Ensure the empty list doesn't iterate. */ - itr.evlist_cpu_map_idx =3D itr.evlist_cpu_map_nr; - } else { - itr.evsel =3D evlist__first(evlist); - if (itr.affinity) { - itr.cpu =3D perf_cpu_map__cpu(evlist->core.all_cpus, 0); - affinity__set(itr.affinity, itr.cpu.cpu); - itr.cpu_map_idx =3D perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu); - /* - * If this CPU isn't in the evsel's cpu map then advance - * through the list. - */ - if (itr.cpu_map_idx =3D=3D -1) - evlist_cpu_iterator__next(&itr); - } + itr->evlist_cpu_map_idx =3D itr->evlist_cpu_map_nr; + return; } - return itr; + + if (evlist__use_affinity(evlist)) { + if (affinity__setup(&itr->saved_affinity) =3D=3D 0) + itr->affinity =3D &itr->saved_affinity; + } + itr->evsel =3D evlist__first(evlist); + itr->cpu =3D perf_cpu_map__cpu(evlist->core.all_cpus, 0); + if (itr->affinity) + affinity__set(itr->affinity, itr->cpu.cpu); + itr->cpu_map_idx =3D perf_cpu_map__idx(itr->evsel->core.cpus, itr->cpu); + /* + * If this CPU isn't in the evsel's cpu map then advance + * through the list. + */ + if (itr->cpu_map_idx =3D=3D -1) + evlist_cpu_iterator__next(itr); +} + +void evlist_cpu_iterator__exit(struct evlist_cpu_iterator *itr) +{ + if (!itr->affinity) + return; + + affinity__cleanup(itr->affinity); + itr->affinity =3D NULL; } =20 void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr) @@ -417,14 +492,11 @@ void evlist_cpu_iterator__next(struct evlist_cpu_iter= ator *evlist_cpu_itr) */ if (evlist_cpu_itr->cpu_map_idx =3D=3D -1) evlist_cpu_iterator__next(evlist_cpu_itr); + } else { + evlist_cpu_iterator__exit(evlist_cpu_itr); } } =20 -bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu= _itr) -{ - return evlist_cpu_itr->evlist_cpu_map_idx >=3D evlist_cpu_itr->evlist_cpu= _map_nr; -} - static int evsel__strcmp(struct evsel *pos, char *evsel_name) { if (!evsel_name) @@ -452,19 +524,11 @@ static void __evlist__disable(struct evlist *evlist, = char *evsel_name, bool excl { struct evsel *pos; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity =3D NULL; bool has_imm =3D false; =20 - // See explanation in evlist__close() - if (!cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) - return; - affinity =3D &saved_affinity; - } - /* Disable 'immediate' events last */ for (int imm =3D 0; imm <=3D 1; imm++) { - evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { pos =3D evlist_cpu_itr.evsel; if (evsel__strcmp(pos, evsel_name)) continue; @@ -482,7 +546,6 @@ static void __evlist__disable(struct evlist *evlist, ch= ar *evsel_name, bool excl break; } =20 - affinity__cleanup(affinity); evlist__for_each_entry(evlist, pos) { if (evsel__strcmp(pos, evsel_name)) continue; @@ -522,16 +585,8 @@ static void __evlist__enable(struct evlist *evlist, ch= ar *evsel_name, bool excl_ { struct evsel *pos; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity =3D NULL; =20 - // See explanation in evlist__close() - if (!cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) - return; - affinity =3D &saved_affinity; - } - - evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { pos =3D evlist_cpu_itr.evsel; if (evsel__strcmp(pos, evsel_name)) continue; @@ -541,7 +596,6 @@ static void __evlist__enable(struct evlist *evlist, cha= r *evsel_name, bool excl_ continue; evsel__enable_cpu(pos, evlist_cpu_itr.cpu_map_idx); } - affinity__cleanup(affinity); evlist__for_each_entry(evlist, pos) { if (evsel__strcmp(pos, evsel_name)) continue; @@ -1338,28 +1392,14 @@ void evlist__close(struct evlist *evlist) { struct evsel *evsel; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity affinity; - - /* - * With perf record core.user_requested_cpus is usually NULL. - * Use the old method to handle this for now. - */ - if (!evlist->core.user_requested_cpus || - cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - evlist__for_each_entry_reverse(evlist, evsel) - evsel__close(evsel); - return; - } - - if (affinity__setup(&affinity) < 0) - return; =20 - evlist__for_each_cpu(evlist_cpu_itr, evlist, &affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { + if (evlist_cpu_itr.cpu_map_idx =3D=3D 0 && evsel__is_retire_lat(evlist_c= pu_itr.evsel)) + evsel__tpebs_close(evlist_cpu_itr.evsel); perf_evsel__close_cpu(&evlist_cpu_itr.evsel->core, evlist_cpu_itr.cpu_map_idx); } =20 - affinity__cleanup(&affinity); evlist__for_each_entry_reverse(evlist, evsel) { perf_evsel__free_fd(&evsel->core); perf_evsel__free_id(&evsel->core); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 5e71e3dc6042..b4604c3f03d6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -10,6 +10,7 @@ #include #include #include +#include "affinity.h" #include "events_stats.h" #include "evsel.h" #include "rblist.h" @@ -361,6 +362,8 @@ struct evlist_cpu_iterator { struct perf_cpu cpu; /** If present, used to set the affinity when switching between CPUs. */ struct affinity *affinity; + /** Maybe be used to hold affinity state prior to iterating. */ + struct affinity saved_affinity; }; =20 /** @@ -368,22 +371,31 @@ struct evlist_cpu_iterator { * affinity, iterate over all CPUs and then the evl= ist * for each evsel on that CPU. When switching betwe= en * CPUs the affinity is set to the CPU to avoid IPIs - * during syscalls. + * during syscalls. The affinity is set up and remo= ved + * automatically, if the loop is broken a call to + * evlist_cpu_iterator__exit is necessary. * @evlist_cpu_itr: the iterator instance. * @evlist: evlist instance to iterate. - * @affinity: NULL or used to set the affinity to the current CPU. */ -#define evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) \ - for ((evlist_cpu_itr) =3D evlist__cpu_begin(evlist, affinity); \ +#define evlist__for_each_cpu(evlist_cpu_itr, evlist) \ + for (evlist_cpu_iterator__init(&(evlist_cpu_itr), evlist); \ !evlist_cpu_iterator__end(&evlist_cpu_itr); \ evlist_cpu_iterator__next(&evlist_cpu_itr)) =20 -/** Returns an iterator set to the first CPU/evsel of evlist. */ -struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct= affinity *affinity); +/** Setup an iterator set to the first CPU/evsel of evlist. */ +void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evl= ist *evlist); +/** + * Cleans up the iterator, automatically done by evlist_cpu_iterator__next= when + * the end of the list is reached. Multiple calls are safe. + */ +void evlist_cpu_iterator__exit(struct evlist_cpu_iterator *itr); /** Move to next element in iterator, updating CPU, evsel and the affinity= . */ void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr); /** Returns true when iterator is at the end of the CPUs and evlist. */ -bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu= _itr); +static inline bool evlist_cpu_iterator__end(const struct evlist_cpu_iterat= or *evlist_cpu_itr) +{ + return evlist_cpu_itr->evlist_cpu_map_idx >=3D evlist_cpu_itr->evlist_cpu= _map_nr; +} =20 struct evsel *evlist__get_tracking_event(struct evlist *evlist); void evlist__set_tracking_event(struct evlist *evlist, struct evsel *track= ing_evsel); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f14f2a12d061..e300a3b71bd6 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -2410,6 +2410,18 @@ bool perf_pmu__is_software(const struct perf_pmu *pm= u) return false; } =20 +bool perf_pmu__benefits_from_affinity(struct perf_pmu *pmu) +{ + if (!pmu) + return true; /* Assume is core. */ + + /* + * All perf event PMUs should benefit from accessing the perf event + * contexts on the local CPU. + */ + return pmu->type <=3D PERF_PMU_TYPE_PE_END; +} + FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name) { char path[PATH_MAX]; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 1ebcf0242af8..87e12a9a0e67 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -259,6 +259,7 @@ bool perf_pmu__name_no_suffix_match(const struct perf_p= mu *pmu, const char *to_m * perf_sw_context in the kernel? */ bool perf_pmu__is_software(const struct perf_pmu *pmu); +bool perf_pmu__benefits_from_affinity(struct perf_pmu *pmu); =20 FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name); FILE *perf_pmu__open_file_at(const struct perf_pmu *pmu, int dirfd, const = char *name); --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (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 7D64835BDD7 for ; Thu, 13 Nov 2025 18:06:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057163; cv=none; b=ny9maPOQU1ac6JwMpk4XSjBdvbMMKwpszkj3MYd1zn+X8RsKxg1KgSaZRm2nP2VJFz2UlIIDYQu37mkT6y1k2vaILThj8UuNCil/mrV8aYyLPpOman5MTBBPY/+5UixurAS88Ce+VhP1m0cH/78+73I/oftqPXhUv3s6hSCoPvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057163; c=relaxed/simple; bh=VSPi5b0FYSjK9jbjwqv1ISG3u2SRPYT3qLyoAV5ofDo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=G70ZG8thum6k9p7JxGWCDRV0jprWohu9fZKN4PZeWT0PsAeII3+Od6oUF6/TFiRgXxDQGzhyLskJOhHORSdftpEKU0K0U0ml3puE0ssSTGYJs4Y50Dw5RkQSrHcF7WlUcO1v5Uviue1UQhbQy+I3LbMhyVqEXCmMLvDOqtyPfUk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=A49xG5wy; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="A49xG5wy" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b95d06db747so1745665a12.1 for ; Thu, 13 Nov 2025 10:06:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057161; x=1763661961; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=gHUlYvYVsoqcUvPe52eoqpv7ujyDyUuBEdGEz9LzsdQ=; b=A49xG5wyyAJoZ5PngxBlKud/0zta7tUNjx7qGEAKodIT7wmBEDzFuxkdx3MkcpoQkj Bg4abRtUjy7DZGvjNvdN9udPDaxv2ugJ9DSVglLCEeeCfHSHYsFGXtfeV4iH1wX0zpIR RXqfC44HG/dOByp8Z1R9zROGOboSoQ2GqXgETlPN8pi/wX4EjN23p0/MCafOAXxB9oB4 xfMsdINbfp6si0iiktSriWS4Dp5sASdgwyOlQuNoH+eU4ZubwS+HRfUHe/SbyCSOK221 qDpzbU1c4BD4+XIzsclj/Cvnjg44eHUsdouyMsZgk6QB5iiWfGFs10isiWSfIlTyeKVc Em0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057161; x=1763661961; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gHUlYvYVsoqcUvPe52eoqpv7ujyDyUuBEdGEz9LzsdQ=; b=jLePfjmPjP/Z0wQ6b2zDki7P0puFid+O7TuByPgL2WCDanjyZEkJYU9yJTVlfCirhX cT/o9YIDgOQiVNqZCrWmqwNPW9qo3kfWGJRC+PNTCDWerCW6Vobh14VRP0Ihw+H3rkjJ mJvOiraefQYMeDxXmShIKQUR4B/G6ZzWcKwTXSLEkJEAxP2L9WkUpZTrX0HTL9WTimYh 7KK6CvnLVQG1Qww3lR6DeUddmd8ebb0tnSZ+g6Is4Du1rxGHzYZNE7ufgNkSxRxDhhmj NerfCQkqPbbW31akyBCWaNzwrytRHHH5aej9Kxav7moCRQuB2AbOi8nMTsrWtChJlPot 7t+Q== X-Forwarded-Encrypted: i=1; AJvYcCWI8EEiJGIvdfGxi9WIg3WF/R19L3hhNa5iNWfREdQVmq0o6jDWirn1A+R4mBwrRlnf9LO0mTRttaYDwAg=@vger.kernel.org X-Gm-Message-State: AOJu0YzJzdDXWUDzPkDfQ9iVcePpwIkk/IMdDE7ppgIn7kA4ylSGpkHy F2Q6svlW4NHC/f5xTa+IQnANqg6Nn0wQSFXLvpPRPAtbtUS7jRbw2m+ymnTir+wk77p1n8mFviu C9eWlsPxV1Q== X-Google-Smtp-Source: AGHT+IFQJGwfEwwbqk/yBlpxj/IRuM1bsBxCbxuEgwiTito2SNi2QtdAhaXaZUrQ0UBVURt+znfpgQ3dcomE X-Received: from dlbrd6.prod.google.com ([2002:a05:7022:f106:b0:119:9f33:34aa]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:701b:2912:b0:119:e569:f86c with SMTP id a92af1059eb24-11b40fa9495mr105517c88.9.1763057160835; Thu, 13 Nov 2025 10:06:00 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:15 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-10-irogers@google.com> Subject: [PATCH v4 09/10] perf stat: Read tool events last From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When reading a metric like memory bandwidth on multiple sockets, the additional sockets will be on CPUS > 0. Because of the affinity reading, the counters are read on CPU 0 along with the time, then the later sockets are read. This can lead to the later sockets having a bandwidth larger than is possible for the period of time. To avoid this moving the reading of tool events to occur after all other events are read. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 29 ++++++++++++++++++++++++++++- tools/perf/util/evlist.c | 4 ---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 947f11b8b106..aec93b91fd11 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -379,6 +379,9 @@ static int read_counters_with_affinity(void) if (evsel__is_bpf(counter)) continue; =20 + if (evsel__is_tool(counter)) + continue; + if (!counter->err) counter->err =3D read_counter_cpu(counter, evlist_cpu_itr.cpu_map_idx); } @@ -402,6 +405,24 @@ static int read_bpf_map_counters(void) return 0; } =20 +static int read_tool_counters(void) +{ + struct evsel *counter; + + evlist__for_each_entry(evsel_list, counter) { + int idx; + + if (!evsel__is_tool(counter)) + continue; + + perf_cpu_map__for_each_idx(idx, counter->core.cpus) { + if (!counter->err) + counter->err =3D read_counter_cpu(counter, idx); + } + } + return 0; +} + static int read_counters(void) { int ret; @@ -415,7 +436,13 @@ static int read_counters(void) return ret; =20 // Read non-BPF and non-tool counters next. - return read_counters_with_affinity(); + ret =3D read_counters_with_affinity(); + if (ret) + return ret; + + // Read the tool counters last. This way the duration_time counter + // should always be greater than any other counter's enabled time. + return read_tool_counters(); } =20 static void process_counters(void) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b6df81b8a236..fc3dae7cdfca 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -368,10 +368,6 @@ static bool evlist__use_affinity(struct evlist *evlist) struct perf_cpu_map *used_cpus =3D NULL; bool ret =3D false; =20 - /* - * With perf record core.user_requested_cpus is usually NULL. - * Use the old method to handle this for now. - */ if (!evlist->core.user_requested_cpus || cpu_map__is_dummy(evlist->core.user_requested_cpus)) return false; --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sat Feb 7 23:48:22 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (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 B998B35C1AB for ; Thu, 13 Nov 2025 18:06:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057165; cv=none; b=UQBmnz7NDZhrJIuNCA4uhZNa4cKQBixhnrMiihBqye6mdsIxCqnmio8sG46pIr6vqOMDgVP/+DUzJiJbAxopJPkgYhRam9BsG1kmhlMv8X3nZBSaPHn20R6lcpFUpIoc6/2656XxrzmxFgQXl7pNEh1M7AFR4Dov3AKWe+ivQFg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763057165; c=relaxed/simple; bh=tALcLrqXxNWDiOpY9UQxmoxjIfX4GTtZdrGYQN1kydo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=EP1bAWQp3H44SKJpRl40gLivxIPh6F9Lhvo8s/b+PmPVkt47eOj15D0qi9CXv7eVPIzd5AU5W2axPzaWItHu0dawe3i6d4PqtMlqnJi21LC6aAqeJBHZIP+lZvq177d278Gt2eyUvvTrHqZGzGtX2c+oWJMIf0QcITbz2khLhh0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=f73j4WWj; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="f73j4WWj" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b62da7602a0so914788a12.2 for ; Thu, 13 Nov 2025 10:06:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1763057163; x=1763661963; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=F7BQwoR1zRfcoaLIGWF72ww+QsUvGUWtVBokWi10jMg=; b=f73j4WWjrPvEVlONYUvSWSQRw3RsgYoigEV/GkwY1Zkq6Q/zpdwV9+qeyDHeHG8D7j JimYgtUXrg0QULPfTySrhskygeoknfdE1bWLE0B+FBac5jHZbldFQ9zGjmBMqn+nXxl9 7ftqlFqHaPnhGbEHiqXSQgEe3DAaSd2A2aIexAzivMICXx34jnvjO3Jo3lZxvs09UO8d 1SmnGCrMIAO6OxGjus1xli5mZXdZOve6xtsIWX4y+1vsEbH4q1sjJKGgVtsO5bncR/MW UNsvn64p2fymXC9v6rGg0vL64gye2mdsAm3hOAu6sQVmznbh/YIkJM0aSR0QJFzhHd/J DZEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763057163; x=1763661963; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=F7BQwoR1zRfcoaLIGWF72ww+QsUvGUWtVBokWi10jMg=; b=LjxCur28bAunoQkrftVGFhgKFXmrFNDMNJg5am6oJt0regScAD8eBXIpUxUe4wZ6ai CBH6mjC8OyfU4PnsaLP1u4P5B6eOkKBVLxCxKCCJ7dErafrbDzuEJbLRBr7qKKBYyLYc neT5Uxw+KdoFGD2BqQ5gwL5gbSkSofKFwwkj8CBK0wa9IP60d8MYIgNKyaHcSIE/yL3I xp22w2Y8eIF8RWwjZZ/uYw7ZHj3+xXlKYE8TsEQTIeeDPUZsPOVIjuY8NcDonkyF2Pks 9e3MEBvHty+XpgCVJMjWu3iHwxyAAmJ0U8DF5UvcG0QaIEOiMALvXiA3bDLHWuRz38XH CPfg== X-Forwarded-Encrypted: i=1; AJvYcCXRAkTtjL1bvK4S3+ZNgrWX5FKFp4gs7x4hi8esRbvF+xX1Q2sxA+M36zSYTBCXleIqlRaMeOb4ef9doL8=@vger.kernel.org X-Gm-Message-State: AOJu0YxkuhuC+qkBYmQalwsry9uK77ExKCV+8RqK/06SNirniaYOI1AB SOWi9NSQ9WOAoZLbyA37rrNeIdh6M5dn0h0qu+t7mCyLX69NrWij5SFe3OF/XtFtonUpzLyRzlD 2XmlSyJ0iNQ== X-Google-Smtp-Source: AGHT+IE9ZNy2sDxlTj1psbp9B5u18SqT2MXKmQHk6xCZfp+KcS9kKNFdokFtVB9rtsA+pzTjYkPKn+0YDXn9 X-Received: from dlbrp11.prod.google.com ([2002:a05:7022:160b:b0:119:78ff:fe11]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:d41:b0:119:e56b:91e2 with SMTP id a92af1059eb24-11b411f0923mr82675c88.19.1763057163085; Thu, 13 Nov 2025 10:06:03 -0800 (PST) Date: Thu, 13 Nov 2025 10:05:16 -0800 In-Reply-To: <20251113180517.44096-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251113180517.44096-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog Message-ID: <20251113180517.44096-11-irogers@google.com> Subject: [PATCH v4 10/10] perf stat: Add no-affinity flag From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add flag that disables affinity behavior. Using sched_setaffinity to place a perf thread on a CPU can avoid certain interprocessor interrupts but may introduce a delay due to the scheduling, particularly on loaded machines. Add a command line option to disable the behavior. This behavior is less present in other tools like `perf record`, as it uses a ring buffer and doesn't make repeated system calls. Signed-off-by: Ian Rogers --- tools/perf/Documentation/perf-stat.txt | 4 ++++ tools/perf/builtin-stat.c | 6 ++++++ tools/perf/util/evlist.c | 2 +- tools/perf/util/evlist.h | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentat= ion/perf-stat.txt index 1a766d4a2233..1ffb510606af 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -382,6 +382,10 @@ color the metric's computed value. Don't print output, warnings or messages. This is useful with perf stat record below to only write data to the perf.data file. =20 +--no-affinity:: +Don't change scheduler affinities when iterating over CPUs. Disables +an optimization aimed at minimizing interprocessor interrupts. + STAT RECORD ----------- Stores stat data into perf data file. diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index aec93b91fd11..fa42b08bd1df 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2415,6 +2415,7 @@ static int parse_tpebs_mode(const struct option *opt,= const char *str, int cmd_stat(int argc, const char **argv) { struct opt_aggr_mode opt_mode =3D {}; + bool no_affinity =3D false; struct option stat_options[] =3D { OPT_BOOLEAN('T', "transaction", &transaction_run, "hardware transaction statistics"), @@ -2543,6 +2544,8 @@ int cmd_stat(int argc, const char **argv) "don't print 'summary' for CSV summary output"), OPT_BOOLEAN(0, "quiet", &quiet, "don't print any output, messages or warnings (useful with record)"), + OPT_BOOLEAN(0, "no-affinity", &no_affinity, + "don't allow affinity optimizations aimed at reducing IPIs"), OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type", "Only enable events on applying cpu with this type " "for hybrid platform (e.g. core or atom)", @@ -2600,6 +2603,9 @@ int cmd_stat(int argc, const char **argv) } else stat_config.csv_sep =3D DEFAULT_SEPARATOR; =20 + if (no_affinity) + evsel_list->no_affinity =3D true; + if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) { argc =3D __cmd_record(stat_options, &opt_mode, argc, argv); if (argc < 0) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index fc3dae7cdfca..53c8e974de8b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -368,7 +368,7 @@ static bool evlist__use_affinity(struct evlist *evlist) struct perf_cpu_map *used_cpus =3D NULL; bool ret =3D false; =20 - if (!evlist->core.user_requested_cpus || + if (evlist->no_affinity || !evlist->core.user_requested_cpus || cpu_map__is_dummy(evlist->core.user_requested_cpus)) return false; =20 diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index b4604c3f03d6..c7ba0e0b2219 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -59,6 +59,7 @@ struct event_enable_timer; struct evlist { struct perf_evlist core; bool enabled; + bool no_affinity; int id_pos; int is_pos; int nr_br_cntr; --=20 2.51.2.1041.gc1ab5b90ca-goog