From nobody Fri Feb 13 12:36:54 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (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 A97EA3019D6 for ; Tue, 10 Feb 2026 06:04:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703448; cv=none; b=jho3H0UoiPLL3ldJvEfrzU7m8tqqic/EnFaOo9T9hKo1PN84rZtJ+yIS/MxvcZE2TxajVIjv1BPLyi8kOrEDcjp/H4ASgKMHTXTnLDPHLMnRnknrIRlvrrP/CIzujob3MOE6g5Ca7tOZIC8R5niP6oAJ6mPE0lfJcGwRU7r7lHc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703448; c=relaxed/simple; bh=Lszd0UdRB8GQidhdx5Z+Lj/C2pK9X74pxC+as6fOUOI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=UvZpB9/KWf9KNDYbepuLC6S9ekIV+yBAe9xlB9mUBHtqTJbzjp/Jrd/PVo9K0w53lkB4qFjdiPGdpEcPnnXW1stBtES4+REKgPMNn9E61xf+iD2WfBjLx2tGAARuLixgEQ5gT87SiIdnk4T3T5rJ0rWNVNJdkHU6V3RWa59rnJY= 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=KXY3/PT5; arc=none smtp.client-ip=74.125.82.73 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="KXY3/PT5" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-1247bb4db53so440082c88.1 for ; Mon, 09 Feb 2026 22:04:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770703447; x=1771308247; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=trHHoM5lxs3R3c1XXOrfjjzTr20GXbuQCFUGYGyaPS8=; b=KXY3/PT5r7h0+AMXAo41op15xBxpWRPat2LMnkAuZpYPGOG+xjV9I0JPvH6v+Ff8Um LbwICjcLw2MIwIPBOobihM9sh8BrLnxHPsmuR0ssxBpkLh1K7m0i4NWO3MDOmWQt/0yK 6iRHm2T9sySDtpF1krwYPdk+6RecFuQ3nEjfX26SfPAkFruopy9GT32UInaU2j+P9qkN Ng7oZO4IWh8c6zN5JNUDACkEdIgoAjvVkpNuoMaarZEFy0a5bjboql3uFukXwrxkUFzQ gkbQrdPkuGJu0/hDUcsXl2WZkRkohabyEmLOCx9rsISJHe+B6oND0pX+O6ygQ2ZchZxE zc5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770703447; x=1771308247; h=cc: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=trHHoM5lxs3R3c1XXOrfjjzTr20GXbuQCFUGYGyaPS8=; b=YdId9PuXd3obRSM6wtA3f5mEkasXmICZv/w7Mq+KAyKH6kCabAl3jNp3LhXPZT5OOx 4bgwtvy1famaAcdkZFF9VHpcEYMVEoFpDzPKpgB8rAqKcqlOe9qDizUbupl9O+DZ5LPZ juVNumJ1q+nlZtxuzkPCYG+n4vqgzQ/Wv/EH1vvdm9b88aSp7ktlL1ZBRd6WUQXdsmp9 GT9dZalGkH+0I1W1Liczcx/z+RUqAzvNltc7/F3mmobYxpMOjYgJimWbGED5ysFTafyb 56O2HMokczhmkiFxD9sm/W2AV8m2YaHZnboWWzHvrXI26TI1ndsnMgtbZAfWzNh3D2U6 qj7w== X-Forwarded-Encrypted: i=1; AJvYcCV8L9HyQUzasWzUKMfQcGcs2WuHzmntyG1Pc0LyDh0IRhg36c9UXtn0M404Z28sea9V8kbrGDpEkgWvctA=@vger.kernel.org X-Gm-Message-State: AOJu0YyMjl5J2hsKT/rzuv6zHF+O0SdFQUENWV1XWlc5jF03RxfAI6fR ITAnSgCGsUd8hNBWEKbN3tmTGHqBxWtPhQam3ZgpL5L1OMSjf01ENZGcT+j8/YVt4NZ3bWoOeTt +XiZq1QJybw== X-Received: from dlbqq7.prod.google.com ([2002:a05:7022:ed07:b0:127:177b:bd24]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:404:b0:11b:9e5e:1a40 with SMTP id a92af1059eb24-127040196f5mr4582022c88.15.1770703446829; Mon, 09 Feb 2026 22:04:06 -0800 (PST) Date: Mon, 9 Feb 2026 22:03:54 -0800 In-Reply-To: <20260210060359.2233425-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: <20260210060359.2233425-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260210060359.2233425-2-irogers@google.com> Subject: [PATCH v9 1/6] Revert "perf tool_pmu: More accurately set the cpus for tool events" From: Ian Rogers To: namhyung@kernel.org, acme@kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, alexander.shishkin@linux.intel.com, andres@anarazel.de, dapeng1.mi@linux.intel.com, irogers@google.com, james.clark@linaro.org, jolsa@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux@treblig.org, mingo@redhat.com, peterz@infradead.org, thomas.falcon@intel.com, tmricht@linux.ibm.com, yang.lee@linux.alibaba.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This reverts commit d8d8a0b3603a9a8fa207cf9e4f292e81dc5d1008. The setting of a user CPU map can cause an empty intersection when combined with CPU 0 and the event removed. This later triggers a segv in the stat-shadow logic. Let's put back a full online CPU map for now by reverting this patch. Reported-by: Andres Freund Closes: https://lore.kernel.org/linux-perf-users/cgja46br2smmznxs7kbeabs6zg= v3b4olfqgh2fdp5mxk2yom4v@w6jjgov6hdi6/ 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, 2 insertions(+), 27 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d4647ded340f..f631bf7a919f 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -30,7 +30,6 @@ #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 @@ -230,12 +229,8 @@ __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)) { - if (perf_pmu__is_tool(pmu)) - pmu_cpus =3D tool_pmu__cpus(attr); - else - pmu_cpus =3D cpu_map__online(); - } + if (perf_cpu_map__is_empty(pmu_cpus)) + 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 37c4eae0bef1..6a9df3dc0e07 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -2,7 +2,6 @@ #include "cgroup.h" #include "counts.h" #include "cputopo.h" -#include "debug.h" #include "evsel.h" #include "pmu.h" #include "print-events.h" @@ -14,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -111,23 +109,6 @@ 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 ea343d1983d3..f1714001bc1d 100644 --- a/tools/perf/util/tool_pmu.h +++ b/tools/perf/util/tool_pmu.h @@ -46,7 +46,6 @@ 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.53.0.rc2.204.g2597b5adb4-goog From nobody Fri Feb 13 12:36:54 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.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 7E4D62E7637 for ; Tue, 10 Feb 2026 06:04:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703450; cv=none; b=o4Kn+TcBZomI4w3Dp/p33u1LLBXV63OafKHYAsQTNHx1w14Kay4EPOdiNxW8TdpemXGNf6xadx0Odu2HQHqdI7gM8mG6VMNFAatWX8gWhGxKZ8B9WAMgRXTwIVmhD26VhvxLZfgmjh1dkni4Ny8GwMkG5cAVRb+4nU5kirM/IHc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703450; c=relaxed/simple; bh=TzweULhbFyvVOxzKvm6ziGllewjhlCuvpRxGmN/BS4Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cxsUjy2kyWUXbVlKKboHTQ/3tOjZW3PdEtY2sMLIw2s6L49+VI99pX03lpTN7JWLQNYMi+VGpzb2j+PJKxZrgL1WXWwjPPbuc2HEtNGToYarV3Z06Spot8LNBALiFsquQkv+dsHwn/4OgaBwoyMEnYD3kMHEkw9oLddNKgeTy90= 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=KVCX5bhK; arc=none smtp.client-ip=74.125.82.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="KVCX5bhK" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2b6b9c1249fso4256428eec.1 for ; Mon, 09 Feb 2026 22:04:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770703449; x=1771308249; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=yDLKVG3tEtlD42Ak1LCzl04+zbbwATgaIYJmxnnK6Qc=; b=KVCX5bhKlAY40YdEPKionSJwytrqQFJUktQclUSB/IF2GIMtewnB0/wGDl5/lP3XZd i0EqfoRjhjO2RxziLfkMW5M30pB+HaOqAsFRKd7Vz7jinxSHCrzzcYUTF5r/mYL2DX+Y Hl2c4GraXtB6kUByf1KUoQtlyYtsJ+QYcjVvnFlqvdTLVBvyuPkhQqew1ReoxtIhmQnR u7O529VK4giirpD0gS6QKn5greFveBI/W3c0iSpM4UfKBErnkdwF5dbYODxncYrfy8dN 2PkqBZrF7WxJdhnSxoXbDZ0TDaBklCrevZmLmUn4jfsaepB4eEyGbiOuvo8bvjBOWvUu f2tA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770703449; x=1771308249; h=cc: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=yDLKVG3tEtlD42Ak1LCzl04+zbbwATgaIYJmxnnK6Qc=; b=CHnP/2KKyYjjy820ZTDFul7k94H2NPJavUBiPwujyntE3GCnxGhnbqTU4wuZRF2C5j RmXQrE+1nHn36+Ido47wx1o2At5iZop5Q91rPRwju9GPDpFGj+7BO3laA09ulWQwaaj2 VN311MbroOAKPVjg4EPdLinQd/HyET48g0ftfyRyqAVPat4ygwLj57ylGRvT2T2g2zCn X6uQPCRMAEOQd4TBtuQB3KT1VQKzuOuWSIiBmLbLD64qMS3dkqO2RCFHMHY2VvioTEZY xvk05k9Cdc4ibY6cTpi9u5d0OMxuSz6XXwXuQsusAeeqeBq8VXf2PN75y8tCbaQJYMTz dc0w== X-Forwarded-Encrypted: i=1; AJvYcCXwQaZPpj1DkJFEzSt0nEyChVKRbfcnfraSD8JigR8gmfevIy6wpHjxdqTIQ1grFjW7AXdMfUniY8ZqAH8=@vger.kernel.org X-Gm-Message-State: AOJu0YwwFtEh9x+fPEfUQwG8dISltf9wpeXKOpjzWAMH9f+/dfJ8ORKG fifBmQ9Wyl6RcNQlBiP+/aiMNBX30JawV9ussPj8pCbmxjeR31abNcv0b1SL00iAyTje7ZzJWGQ mFqPtjtDGag== X-Received: from dlbdd35.prod.google.com ([2002:a05:7022:aa3:b0:127:1887:64c9]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:a86:b0:123:330b:398 with SMTP id a92af1059eb24-12703f51b55mr5734557c88.19.1770703448533; Mon, 09 Feb 2026 22:04:08 -0800 (PST) Date: Mon, 9 Feb 2026 22:03:55 -0800 In-Reply-To: <20260210060359.2233425-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: <20260210060359.2233425-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260210060359.2233425-3-irogers@google.com> Subject: [PATCH v9 2/6] perf stat-shadow: In prepare_metric fix guard on reading NULL perf_stat_evsel From: Ian Rogers To: namhyung@kernel.org, acme@kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, alexander.shishkin@linux.intel.com, andres@anarazel.de, dapeng1.mi@linux.intel.com, irogers@google.com, james.clark@linaro.org, jolsa@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux@treblig.org, mingo@redhat.com, peterz@infradead.org, thomas.falcon@intel.com, tmricht@linux.ibm.com, yang.lee@linux.alibaba.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The aggr value is setup to always be non-null creating a redundant guard for reading from it. Switch to using the perf_stat_evsel (ps) and narrow the scope of aggr so that it is known valid when used. Reported-by: Andres Freund Fixes: 3d65f6445fd9 ("perf stat-shadow: Read tool events directly") Signed-off-by: Ian Rogers --- tools/perf/util/stat-shadow.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 5d8d09e0e6ae..59d2cd4f2188 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -57,7 +57,6 @@ static int prepare_metric(struct perf_stat_config *config, 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; =20 @@ -82,8 +81,7 @@ static int prepare_metric(struct perf_stat_config *config, } } /* 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 || aggr->counts.run =3D=3D 0) { + if (!ps || !metric_events[i]->supported) { /* * Not supported events will have a count of 0, which * can be confusing in a metric. Explicitly set the @@ -93,11 +91,21 @@ static int prepare_metric(struct perf_stat_config *conf= ig, 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]); + struct perf_stat_aggr *aggr =3D + &ps->aggr[is_tool_time ? tool_aggr_idx : aggr_idx]; + + if (aggr->counts.run =3D=3D 0) { + val =3D NAN; + source_count =3D 0; + } else { + val =3D aggr->counts.val; + if (is_tool_time) { + /* Convert time event nanoseconds to seconds. */ + val *=3D 1e-9; + } + if (!source_count) + source_count =3D evsel__source_count(metric_events[i]); + } } n =3D strdup(evsel__metric_id(metric_events[i])); if (!n) --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Fri Feb 13 12:36:54 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (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 3EBC132D0EF for ; Tue, 10 Feb 2026 06:04:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703452; cv=none; b=dzLhDJCTVPVJyqPI7hl8RRLlLdRZSuFvb7yqUU/NUt0vpObJeqYe8Ia4v3kl2SQ9lSbKbGWwSQ1r65UGoAZRK+wG59w0EiG9fzRLWWDqOYY8Kb0D/20NEx5Ury8kput8HvEDWaAOpFJnJiPkS7ezGOLl0BfQH2zh6Cdvz8R/iAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703452; c=relaxed/simple; bh=m6NLJ4Vb0UEPbPzi83NUsogmV6qs5B+5r17ynjkDPV0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PPUBmfH0psyDYoR411xJps6e5wb+lR14w2AcGli7qqMcFrwHaRMWvRPGuYh4CiFyEfdH9OnlanWP+DOJHPJlU4DCglh/RvnoOKUcROOd3mvrZw3CJr6ZtxLN/tfQBvGkp/YnDNylOwLPwK2vpBEeX+w+ZxNiAT3jxEF76R7nyEc= 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=FqrcSOFd; arc=none smtp.client-ip=74.125.82.74 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="FqrcSOFd" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-124a95b6f61so3017727c88.0 for ; Mon, 09 Feb 2026 22:04:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770703450; x=1771308250; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=sOJSg9cHyId65pfgpXUFicdk0Bjz5b4dGSwLC1Zzl3E=; b=FqrcSOFdByniHRDVVhL6jzIYgr2ExYpJeLe5tZvpOpG8+pR1/XATNV/3R7YaTloiPn zyzzGSU71422ZevKn17i8y0wAUrYa2oBHfgoBsdllgoeOXT8lZkA10m2EwVVBiWSmfR7 Amd94gZjO/0wbg/FpsK/fVp6gG2sj3ggPUkRDBAdBL2H8499GDfqWr/zK0riuX77YQhM W2CUd6DfKnQOikn/98YyAfs+7r5Y33mTEAruJeyTuRTAeGyKhsimXik2KXfeMA7M6SPy XWGW68RszIuhaux51lI/XTaaDhipZzif1Ha6l1J+rKsenhya/SHOj5hC2SzkIebvEA/s hEig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770703450; x=1771308250; h=cc: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=sOJSg9cHyId65pfgpXUFicdk0Bjz5b4dGSwLC1Zzl3E=; b=X9sSIXeAV6cdjgy9W5BrnJAflJKTalNfqKo6/bFtT34aAzT8RXIWJzqDp/UKfsXyJ7 v5iBp8292wvdTKLWFJl5x1GyrYcwroOzViMRtVtFX6VsmI9YphtxaVebTReO1CegSs53 et+ngicrVvfomjDHtWhJIoVV4tBl8zvNIgHxuy03ZDl2CyjQR3v8U69o5E/I2xRYIjw4 na2Zpr4RHj5D8JpzZVtwZHnu/olNf361ARtjQccuZah+TBUJwzvfclQXvGXJ1k34DId1 TviG9PSyFB8pc4InKdowDgDaN5iTSsT4yS53+8vKtOBTJwQoL0PjigD4C+YtxkxqD0Ox ovXg== X-Forwarded-Encrypted: i=1; AJvYcCXm5RsgyHvQGTPX5MU8G6Eova8v4A62mGz0+IWAokRJhzrv6utvrxfVZHEhkIzdxHqQ7a5h1fNBtfSWu+w=@vger.kernel.org X-Gm-Message-State: AOJu0YzGjKekjf8WB2GRy4+iPPE1kNVZt6xHvABpYxQaBUf3ztlaZpSB Ba2Vwsf70DmuSaR4eL6Lx6tPkBZqJGw3kiy9At8DDfJr8Y2245wYIJpLNzwrd7hXLkDSFHGQbQt jMtYpVjtFQQ== X-Received: from dlb29.prod.google.com ([2002:a05:7022:61d:b0:127:1508:19ae]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:419c:b0:124:9dea:188d with SMTP id a92af1059eb24-1270405a026mr5730471c88.30.1770703450210; Mon, 09 Feb 2026 22:04:10 -0800 (PST) Date: Mon, 9 Feb 2026 22:03:56 -0800 In-Reply-To: <20260210060359.2233425-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: <20260210060359.2233425-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260210060359.2233425-4-irogers@google.com> Subject: [PATCH v9 3/6] perf evlist: Special map propagation for tool events that read on 1 CPU From: Ian Rogers To: namhyung@kernel.org, acme@kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, alexander.shishkin@linux.intel.com, andres@anarazel.de, dapeng1.mi@linux.intel.com, irogers@google.com, james.clark@linaro.org, jolsa@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux@treblig.org, mingo@redhat.com, peterz@infradead.org, thomas.falcon@intel.com, tmricht@linux.ibm.com, yang.lee@linux.alibaba.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Tool events like duration_time don't need a perf_cpu_map that contains all online CPUs. Having such a perf_cpu_map causes overheads when iterating between events for CPU affinity. During parsing mark events that just read on a single CPU map index as such, then during map propagation set up the evsel's CPUs and thereby the evlists accordingly. The setting cannot be done early in parsing as user CPUs are only fully known when evlist__create_maps is called. Signed-off-by: Ian Rogers --- tools/lib/perf/evlist.c | 36 ++++++++++++++++++++++--- tools/lib/perf/include/internal/evsel.h | 2 ++ tools/perf/util/parse-events.c | 1 + tools/perf/util/pmu.c | 11 ++++++++ tools/perf/util/pmu.h | 2 ++ 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index 3ed023f4b190..1f210dadd666 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -101,6 +101,28 @@ static void __perf_evlist__propagate_maps(struct perf_= evlist *evlist, evsel->cpus =3D perf_cpu_map__get(evlist->user_requested_cpus); } =20 + /* + * Tool events may only read on the first CPU index to avoid double + * counting things like duration_time. Make the evsel->cpus contain just + * that single entry otherwise we may spend time changing affinity to + * CPUs that just have tool events, etc. + */ + if (evsel->reads_only_on_cpu_idx0 && perf_cpu_map__nr(evsel->cpus) > 0) { + struct perf_cpu_map *srcs[3] =3D { + evlist->all_cpus, + evlist->user_requested_cpus, + evsel->pmu_cpus, + }; + for (size_t i =3D 0; i < ARRAY_SIZE(srcs); i++) { + if (!srcs[i]) + continue; + + perf_cpu_map__put(evsel->cpus); + evsel->cpus =3D perf_cpu_map__new_int(perf_cpu_map__cpu(srcs[i], 0).cpu= ); + break; + } + } + /* Sanity check assert before the evsel is potentially removed. */ assert(!evsel->requires_cpu || !perf_cpu_map__has_any_cpu(evsel->cpus)); =20 @@ -133,16 +155,22 @@ static void __perf_evlist__propagate_maps(struct perf= _evlist *evlist, =20 static void perf_evlist__propagate_maps(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *n; - evlist->needs_map_propagation =3D true; =20 /* Clear the all_cpus set which will be merged into during propagation. */ perf_cpu_map__put(evlist->all_cpus); evlist->all_cpus =3D NULL; =20 - list_for_each_entry_safe(evsel, n, &evlist->entries, node) - __perf_evlist__propagate_maps(evlist, evsel); + /* 2 rounds so that reads_only_on_cpu_idx0 benefit from knowing the other= CPU maps. */ + for (int round =3D 0; round < 2; round++) { + struct perf_evsel *evsel, *n; + + list_for_each_entry_safe(evsel, n, &evlist->entries, node) { + if ((!evsel->reads_only_on_cpu_idx0 && round =3D=3D 0) || + (evsel->reads_only_on_cpu_idx0 && round =3D=3D 1)) + __perf_evlist__propagate_maps(evlist, evsel); + } + } } =20 void perf_evlist__add(struct perf_evlist *evlist, diff --git a/tools/lib/perf/include/internal/evsel.h b/tools/lib/perf/inclu= de/internal/evsel.h index fefe64ba5e26..b988034f1371 100644 --- a/tools/lib/perf/include/internal/evsel.h +++ b/tools/lib/perf/include/internal/evsel.h @@ -128,6 +128,8 @@ struct perf_evsel { bool requires_cpu; /** Is the PMU for the event a core one? Effects the handling of own_cpus= . */ bool is_pmu_core; + /** Does the evsel on read on the first CPU index such as tool time event= s? */ + bool reads_only_on_cpu_idx0; int idx; }; =20 diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index f631bf7a919f..b9efb296bba5 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -269,6 +269,7 @@ __add_event(struct list_head *list, int *idx, evsel->core.pmu_cpus =3D pmu_cpus; evsel->core.requires_cpu =3D pmu ? pmu->is_uncore : false; evsel->core.is_pmu_core =3D is_pmu_core; + evsel->core.reads_only_on_cpu_idx0 =3D perf_pmu__reads_only_on_cpu_idx0(a= ttr); evsel->pmu =3D pmu; evsel->alternate_hw_config =3D alternate_hw_config; evsel->first_wildcard_match =3D first_wildcard_match; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index bb399a47d2b4..81ab74681c9b 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -2718,3 +2718,14 @@ const char *perf_pmu__name_from_config(struct perf_p= mu *pmu, u64 config) } return NULL; } + +bool perf_pmu__reads_only_on_cpu_idx0(const struct perf_event_attr *attr) +{ + enum tool_pmu_event event; + + if (attr->type !=3D PERF_PMU_TYPE_TOOL) + return false; + + event =3D (enum tool_pmu_event)attr->config; + return event !=3D TOOL_PMU__EVENT_USER_TIME && event !=3D TOOL_PMU__EVENT= _SYSTEM_TIME; +} diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 7ef90b54a149..41c21389f393 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -350,6 +350,8 @@ void perf_pmu__delete(struct perf_pmu *pmu); const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config); bool perf_pmu__is_fake(const struct perf_pmu *pmu); =20 +bool perf_pmu__reads_only_on_cpu_idx0(const struct perf_event_attr *attr); + static inline enum pmu_kind perf_pmu__kind(const struct perf_pmu *pmu) { __u32 type; --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Fri Feb 13 12:36:54 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (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 B677732D45E for ; Tue, 10 Feb 2026 06:04:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703453; cv=none; b=acHUoXVp9c+bkdAAzkiOdixsydfn8uNgkMtUq7hK37oZmF1/ddaRaf+j/pKLE1S5A0k7/Y0AApitEVTTgoClRt4fqbc0oHLSmsNhpbXBqLPAQu4SCWChr4DT3G7V4kucBxlZ4l9jfWbbwkdHeuOPcuIohExQpcfilBYHtAS8Cv4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703453; c=relaxed/simple; bh=s5HhmH++c0S6/4eaW7RJwAr9NrI5mDPAqNzC53KKvuA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=r2xBfftDKDgOHzEOPLdGjNUo+MeVvM8lZlc+tBJE956c+e+GDG36JssaZ8i7YrIrXYf59DvnZ7DlUKsZGxpK7QWgPOd17S74jMv5d44l62YuoR7iEhJ1EYhjDqlLwy8j+dZNOnV3oTEtjgXWqOaLeQY4CiRa5qB9JnQ2qul3bRU= 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=gFBxoVym; arc=none smtp.client-ip=74.125.82.74 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="gFBxoVym" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-1233b91de6bso4205758c88.1 for ; Mon, 09 Feb 2026 22:04:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770703452; x=1771308252; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=grVQSNoKkwDwm/7kB0bTBCG79LQ7uooFEeHk2Xib8y8=; b=gFBxoVymYUFP6MTggINmDFqhr7Dxmb0Cyc89UUK0jKZN4u6WBZ5T+UBlGxJRlzLgQ5 Q037GTUaiecvSekhF1KRU4F7kaOIrNWr1zsX1CiBVuF6MwVTTrJ5706Y5zhhn6chcj2M PpXWqYnrmOB6UxPQtmswpAh9YtuQpjsWt0UqMO5luuwsfUWQ8BM1NMTwqzNXPLK+9CJT 7XF//sNuZ35hSNuD1QANDTBBr25PWUlgnSefO6Qv84InZlNyA71kmVCsOUhFe8coZ+Q3 yH4wdXETK1TE6SgfuNC+o6g/Wzja4+UlkMTMivkOER2Qve20VwX/8nBM+fdGETk33rKI hgQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770703452; x=1771308252; h=cc: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=grVQSNoKkwDwm/7kB0bTBCG79LQ7uooFEeHk2Xib8y8=; b=HPNlp7cBCwD9EHGyvy//3RWpYVQKkwDcEDdYU821yGk4xxxI+iOrxCO0nwkSvLn4d5 Vv8GwxKwLgRmhYxokzSS4RmfTvVnN/Ob2yZtmiCWQGODBFY5jgX3nV8kBsWIfiWseQw2 mgwFF0BsNczpBA/+qNrU4C5OCWRgfJEdNH+kFmsd8Vk0xXVEO/KqrTy/JErQBubHGe3k xaEYrrl7gO7vQB7nB5kAZBmVLCFbJHIiuo/72WUdfQhothbghChp2VcSZ7CmTE25fSaW rTfy9BmTsQtdZn5x7I99g2d+z0t+eXk2Bl7cgUcRhsw4BxfM45pOVqusHVHVZUspEFGw cbrQ== X-Forwarded-Encrypted: i=1; AJvYcCUvN7FkJAaWn4ttSCyXXZ2CImxrocSSkyQ8rArmqPL2o2IIoHewAQkThDyLOnkJr2rfxb/GQhxpgUpROB4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw5dzYeSL3ayKsW33/7/UuFZmGp1A9SOgzBkBMdqywF6BAWxhLw EuUbRFnIs1QKsRxH47x/sgclGEBWhliltjWn+6uK7q/RW/fAEgbVPSUHleBpJr3gOkOIMYZKWfD XzcfoW5e5zA== X-Received: from dlnn14.prod.google.com ([2002:a05:7022:618e:b0:123:291f:3e5b]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:418a:b0:11b:d6f2:a6d6 with SMTP id a92af1059eb24-1270400c96cmr6603757c88.34.1770703451966; Mon, 09 Feb 2026 22:04:11 -0800 (PST) Date: Mon, 9 Feb 2026 22:03:57 -0800 In-Reply-To: <20260210060359.2233425-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: <20260210060359.2233425-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260210060359.2233425-5-irogers@google.com> Subject: [PATCH v9 4/6] perf evlist: Missing TPEBS close in evlist__close From: Ian Rogers To: namhyung@kernel.org, acme@kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, alexander.shishkin@linux.intel.com, andres@anarazel.de, dapeng1.mi@linux.intel.com, irogers@google.com, james.clark@linaro.org, jolsa@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux@treblig.org, mingo@redhat.com, peterz@infradead.org, thomas.falcon@intel.com, tmricht@linux.ibm.com, yang.lee@linux.alibaba.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The libperf evsel close won't close TPEBS events properly. Add a test to do this. The libperf close routine is used in evlist__close for affinity reasons. Signed-off-by: Ian Rogers --- tools/perf/util/evlist.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3b0d837e3046..3abc2215e790 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1356,6 +1356,8 @@ void evlist__close(struct evlist *evlist) return; =20 evlist__for_each_cpu(evlist_cpu_itr, evlist, &affinity) { + 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 2.53.0.rc2.204.g2597b5adb4-goog From nobody Fri Feb 13 12:36:54 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (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 DCE8D32A3FF for ; Tue, 10 Feb 2026 06:04:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703456; cv=none; b=e8sGacKxM9sIr6N3HXAjRPkkrNBqeAO+XfluQYE8f3WmwANFFOrxkp2F10Ijshdfs8FGqXQbzA5pCPy2LjxG4TdlufFapfUdCeK6vMCN0Wp70uC4BDvJlzW2N4xF2JvEb79i3lBjKqce/yhuSjXHwk8+OSql0yxiVrgHJMQMN6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703456; c=relaxed/simple; bh=nMCvD9FhHWv6QXJohgSpbLwo660AjijJtxk2b8JgbNs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=f4E9oLaRPouBKRBruq1T9marOkgP11RQYR0b1DRo1PWUlDUfZDaicU5Z27gfIfsX3mEHAA2oR/bNW9XP+jonT1PT33AYO4YzELs1q8bvrYGTr0tvHHMoCcm5k4Z7R648Tc4nWc9CK6VT2Imk6va6pYxbkgEqqc0qo4tOkXWIhwg= 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=G57jSAFU; arc=none smtp.client-ip=74.125.82.73 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="G57jSAFU" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-126e8ee6227so469591c88.0 for ; Mon, 09 Feb 2026 22:04:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770703454; x=1771308254; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=LBr6QtiTmPDnDtdThT9x1EHn8qfDN4a5mvSafr0ZxaM=; b=G57jSAFUdXmuRsQiegfukjXBNejRQ1NicNzmHH5j/2QSSvLkgnqXRO1BsxxvqG90/3 wlfNNU7EhpYVDfPeutZbv71QAXY3y3ivtFRW9AHnZuW4qSiRGeJ+IgTV+kTUyHpHZgyx Zth/p+KFkFH/L522NuyjxJQz9ITr0IqEAbTfVYD5bg+y2bUUvXp2BUZ1qpUJ5swLFx9N SLrKG1vmauB9akTnqzf6AO6sv3mVRF/fw/p8TVzLlrxWrL7rl/4+mx5cCMikPD27mk2A TtIryuYVqoLbQMDiGYw2MrnhvgIk+j4HFIkNMqCDyA0r0VPklOora/HXjRkd3+VLR95f gjkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770703454; x=1771308254; h=cc: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=LBr6QtiTmPDnDtdThT9x1EHn8qfDN4a5mvSafr0ZxaM=; b=IeNmH0AUo8PZIqVQYGit6Tat61nywuSLA1+f60XeerB73H+BiDH9hSHFYvuZ2IPZI5 Lt4C3a7FUhWSbn7WkwYep6ebvSjAoTMSeetu3XQ7/0MMxH4WLqp14WcYFvFkd4h4SMb+ RNRAX3wCoaKhfn69d8BI1RdY8AxK1HolS3F1QBNHhoZdTjWs45IG9fnjgBEHGqeMDyQI EjgUxQH01h6/KP6BPrcggDzngsv9kUTvmkwsazplKGt7A+CU+URap0Nig6Ke4dkzHEHB 7bDKg+XK6NCCHgNHhHRV6UpyJ+vTEevUoRaZjcQAJzpWXEpQqCXa4Drgo7Phpk6F108R eHeg== X-Forwarded-Encrypted: i=1; AJvYcCW7EoDFCK9N6WV+QEYnaLP3wscXmpUkC3OUJqYujQJ5V59PzOr4iZt4TeDGwZzMIfCT1G3DJTyOPvHpy58=@vger.kernel.org X-Gm-Message-State: AOJu0Yyy3KgOgE60DR6rWe+7rqC6HbY9x3W4p9LOYCVO+GdRYv1yWX46 Oa6ElbtrDOfgvIfPogFVRMzR06CJU8BFiQnzhtx6Wnd0jYpuCq5U5aNvjnn64syaXXK5IeaLtGN M8bm5/A+nVQ== X-Received: from dll36.prod.google.com ([2002:a05:7022:224:b0:123:2a18:7134]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:627:b0:11b:9e5e:1a66 with SMTP id a92af1059eb24-12704014bf0mr5713389c88.14.1770703453931; Mon, 09 Feb 2026 22:04:13 -0800 (PST) Date: Mon, 9 Feb 2026 22:03:58 -0800 In-Reply-To: <20260210060359.2233425-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: <20260210060359.2233425-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260210060359.2233425-6-irogers@google.com> Subject: [PATCH v9 5/6] perf evlist: Reduce affinity use and move into iterator, fix no affinity From: Ian Rogers To: namhyung@kernel.org, acme@kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, alexander.shishkin@linux.intel.com, andres@anarazel.de, dapeng1.mi@linux.intel.com, irogers@google.com, james.clark@linaro.org, jolsa@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux@treblig.org, mingo@redhat.com, peterz@infradead.org, thomas.falcon@intel.com, tmricht@linux.ibm.com, yang.lee@linux.alibaba.com 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 evlist__use_affinity which tests per-event whether the event's PMU benefits from affinity use - it is assumed only perf event using PMUs do. 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. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 108 +++++++++++--------------- tools/perf/util/evlist.c | 158 +++++++++++++++++++++++--------------- tools/perf/util/evlist.h | 26 +++++-- tools/perf/util/pmu.c | 12 +++ tools/perf/util/pmu.h | 1 + 5 files changed, 174 insertions(+), 131 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2895b809607f..c1bb40b99176 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -369,19 +369,11 @@ static int read_counter_cpu(struct evsel *counter, in= t cpu_map_idx) 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)) @@ -393,8 +385,6 @@ static int read_counters_with_affinity(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; } @@ -793,7 +783,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 @@ -805,14 +794,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)) { @@ -825,49 +806,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, @@ -875,7 +855,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) @@ -884,7 +864,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) @@ -893,17 +873,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) { @@ -1065,7 +1046,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 3abc2215e790..45833244daf3 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -359,36 +359,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) @@ -418,14 +493,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) @@ -453,19 +525,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; @@ -483,7 +547,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; @@ -523,16 +586,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; @@ -542,7 +597,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; @@ -1339,30 +1393,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 911834ae7c2a..30dff7484d3c 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" @@ -363,6 +364,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 /** @@ -370,22 +373,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 81ab74681c9b..5cdd350e8885 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -2375,6 +2375,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 41c21389f393..0d9f3c57e8e8 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -303,6 +303,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.53.0.rc2.204.g2597b5adb4-goog From nobody Fri Feb 13 12:36:54 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (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 A8B9332C92A for ; Tue, 10 Feb 2026 06:04:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703457; cv=none; b=pZoaRZPFjxr7kOu/BZiwZyv8ZwIaAyQI715O/t/aF0ub+sHAysb9zH71+06euLaLKqMl68s1F0aUBxMFcPWD0dd6ZKDLGtehhoPnM1FermmnVAcqKfLIN0a+yqxFXzEPTcsJ5A0VeaDzLQBuHVUhBGG8PFG6x0WYFwvwiHlTPME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770703457; c=relaxed/simple; bh=4h/e/AxUpfmxdWh/2XIxCaVxSOIKGoSbfQOiKef+stc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KnF1NXTwkQNY0L076MXczLqx9d9mDv0ay/BALbWhJTNdjpJluSI08yv0PVjQa4ULfVvg4WmBqrxUEKyh9KEyodqf+soiNa0Jy7cYVw2UxRcP0/x305M23pj6mCghDKyZ166HQET6hX1yFYVnKgJ1qfOyt/CVYIV1M6zatIVxMck= 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=sQt81+q6; arc=none smtp.client-ip=74.125.82.74 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="sQt81+q6" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-124aa710af7so17832090c88.1 for ; Mon, 09 Feb 2026 22:04:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770703456; x=1771308256; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=MVDZXgJUA2hSu3vjasZfPoaK7yNybs3HQAJ9WY8Xr4c=; b=sQt81+q6+nK7JQX/j4wLqHQDno5WpWp3R5k9NAz2IntaJ+b2JdKWn+UhxAu9g0QuTb s1i1WeG7ZpLQyzFmimpMVP1zxUbckD2doghen4CnpbaQD6Shub04whvGIOJlkV/vPs0O Z7RfvA9RujxGk0yAEh8buuD2OSsCajND/kkahEqeYrDNxkr84Vmi+0EOohGcAwK+j0G4 +CHRiVo4+WlaCFnIV+zo9SlAfppg9l2CcB0v+ebTG18M+140htKc74gUJB8TT2NgE6P3 IckyMTXjcWUiXW3h6JxRsyRgqScuHVT/2fd3808/g87SmN0tTFIlC7KUzgN6EjvOmxqI uCPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770703456; x=1771308256; h=cc: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=MVDZXgJUA2hSu3vjasZfPoaK7yNybs3HQAJ9WY8Xr4c=; b=spPLwSwv7lcq9AzRY2dowZxqaEb0b9z0ua/XaF/4e6G3oQNrNnp96FIkctw7QdMd4X 5DP+SC9whfWvmaDWBmGPkd2CjfdaDK3e+SnnCFFNHQeaubbrgmO725653DTmPmwYQ4ek T8DvpJkJ/YcpBeD3azs4e6Xb5LizNP6xBZ+XpK+O/Bf9PQ63fpL/o7QZ8aElpGxA+zq9 jCm+30WgMCAzKNoznwo1hRWhJ/t6E6U6uHjUBGkyKo473U2tHZAB/ruHrn5wNCKGVWMF JhD6k2g0OMysaGKvtKHdwbSo1ZQ09iMJ3x0LOXBMigIhMUabVvrKFlF3Z7hjyYWEV7Gy XGww== X-Forwarded-Encrypted: i=1; AJvYcCVt4m4azHgldJ1Ce3Ual0Zbp5slIW5tXdmALQo1NmlslFJ84/jpeYiC8ee6mbNtTFQ82uSsFa4q/l3wbVE=@vger.kernel.org X-Gm-Message-State: AOJu0Ywne3E9Fu2pwiY9PGY/ois/Ixine53Zbm+WNDGZ1WVNeTWWpjb2 /biED/7D3nygUUlbXYUMtfG/75YLvt1JRirk4ZXn3yOh9/m+qwZFxCq67jqCBIkVA7li87auVzS jMvWqO+XbYQ== X-Received: from dlbou24.prod.google.com ([2002:a05:7022:1118:b0:11d:cde5:d78e]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:521:b0:11b:f056:a1b3 with SMTP id a92af1059eb24-1272431e1bcmr595153c88.11.1770703455859; Mon, 09 Feb 2026 22:04:15 -0800 (PST) Date: Mon, 9 Feb 2026 22:03:59 -0800 In-Reply-To: <20260210060359.2233425-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: <20260210060359.2233425-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260210060359.2233425-7-irogers@google.com> Subject: [PATCH v9 6/6] perf stat: Add no-affinity flag From: Ian Rogers To: namhyung@kernel.org, acme@kernel.org Cc: adrian.hunter@intel.com, ak@linux.intel.com, alexander.shishkin@linux.intel.com, andres@anarazel.de, dapeng1.mi@linux.intel.com, irogers@google.com, james.clark@linaro.org, jolsa@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux@treblig.org, mingo@redhat.com, peterz@infradead.org, thomas.falcon@intel.com, tmricht@linux.ibm.com, yang.lee@linux.alibaba.com 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 | 5 +++++ tools/perf/builtin-stat.c | 6 ++++++ tools/perf/util/evlist.c | 6 +----- tools/perf/util/evlist.h | 1 + 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentat= ion/perf-stat.txt index 1a766d4a2233..7cccc3a847d1 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -382,6 +382,11 @@ 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 CPU 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 c1bb40b99176..73c2ba7e3076 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2426,6 +2426,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 affinity =3D true, affinity_set =3D false; struct option stat_options[] =3D { OPT_BOOLEAN('T', "transaction", &transaction_run, "hardware transaction statistics"), @@ -2554,6 +2555,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_SET(0, "affinity", &affinity, &affinity_set, + "enable (default) or disable affinity optimizations to reduce 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)", @@ -2611,6 +2614,9 @@ int cmd_stat(int argc, const char **argv) } else stat_config.csv_sep =3D DEFAULT_SEPARATOR; =20 + if (affinity_set) + evsel_list->no_affinity =3D !affinity; + 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 45833244daf3..591bdf0b3e2a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -369,11 +369,7 @@ 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 || + 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 30dff7484d3c..d17c3b57a409 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.53.0.rc2.204.g2597b5adb4-goog