From nobody Sat Feb 7 11:05:02 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 A02712FE592 for ; Fri, 6 Feb 2026 22:25:16 +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=1770416716; cv=none; b=NXLpmb6fkJHjNwjSV2BfdopGLklRfRHosT378dbgZQYu+G7gRNVVb5RPL6Si8GFv0msyUdlZC8unvE38WwSz47swOvnfIK+4XNcWj9kNzTjm4wFLr3eIIp7hV/QyDOY/9mHGzidclLQyHfstKMykIRTIt59VE3ulg2E5jYzyECI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770416716; 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=j+alVJXDI6J7zeSGmYnqWPiRFGFNWMWCEe/7suf4dWFxfjURiuvnM4BJmKInLHJjFmdoCaq1IPKN6ZiTZLx2pbk1/1fdSEVoNujM1XjKNgbMhh5EyvLbO6gajEngLENlANCXMABDw/Wms0bmnk0aLKRiz9nIH8L+G1+wnbl3y98= 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=vn+jGuor; 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="vn+jGuor" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-1270e3704d6so2046124c88.0 for ; Fri, 06 Feb 2026 14:25:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770416716; x=1771021516; 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=vn+jGuordLEz5m/xRJC+r4wB1k9fTsiXaW+BGr/X8+FU6ks5SHLg9I60/GDCduF2Bq 7nTvn/aA1FYGParjRgIc1n7KB4qVSlXlzE3GPt69MwNlI1w1de/+VAGOX9wF+jqVE6Gy vXy9Qp7yVLoZtWDRd0FLOM53HNxRSiTH+1uZviqypKYNU3RKLBoMy1qGTRzP3u6srztW JJmdCkZdpW+8PCg81u+aMJF//yD/jAfgJDXHCmHk3qor+pdKamsWfNPm7Z8wdkqYjVwz bKhVi2/rPpprFQJrSjRNS8i6sq8mEjKGuCWtGCx1loLCuP9MPHhkCwTlQHxiIfkrXoyy DL4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770416716; x=1771021516; 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=jklq0YQWN4UPC7I3zPaV6QoSWYuvTF8XmKQZaQz7rPF5W2VX8c8dbxnS3Q0QNmNkB2 d1Umvr6QNlClFCbte/uYOnerwMJEBFuo4UzmNNPwkuyPAiBhN6Je/KvdAOXQDagMClUn 0cr7sbP7IbdP/sr8z5Zsz0JJYsoPUrMPPdIpRrtocG/p9WSXOwHFijOAsntiCq+Sxgd+ ljQ2JGOwwJF6wk8fpi2qhFpM7i9unvNvK0X6C2mlmqovdYEYd6+l8ZHl+2ex7WLn5V0S G4HSLRN4z+AV7pLj5zPO4o+2YJSC8OllPCl1omwuJ0Isv6NaS8i+jpnYIEawTJSyvfv9 nujA== X-Forwarded-Encrypted: i=1; AJvYcCXsSTM5KYo6oYIHoANG81ziPtQQTo/VxdU9Z6Zji9nZZHMtNEMw8FCeatjvoCna+xxGGFF3IEBfOYXq8IM=@vger.kernel.org X-Gm-Message-State: AOJu0YxO2zODvecg6M4nxsUXrEtoAz49URlg+3NXxWd/OHX79VKAh13d dRMh6OaqFjlQq1pQjmhJh5pJg59Q6/WXoNKbYXpgtDwtTd6B/H2Ms8TD25RfeJfcG3opXdISEcb 7a5J1obd35Q== X-Received: from dlbrb7.prod.google.com ([2002:a05:7022:f007:b0:123:12b9:c4e5]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6186:b0:124:8d84:1d8f with SMTP id a92af1059eb24-127041695a8mr1587889c88.23.1770416715668; Fri, 06 Feb 2026 14:25:15 -0800 (PST) Date: Fri, 6 Feb 2026 14:25:04 -0800 In-Reply-To: <20260206222509.982489-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: <20260206222509.982489-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260206222509.982489-2-irogers@google.com> Subject: [PATCH v8 1/6] Revert "perf tool_pmu: More accurately set the cpus for tool events" From: Ian Rogers To: 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, namhyung@kernel.org, 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 Sat Feb 7 11:05:02 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 4D5E430EF7A for ; Fri, 6 Feb 2026 22:25:18 +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=1770416718; cv=none; b=Kx7x1egA4JL3o+mSQIjqHGqIfPP1wHaqLbxIQnJgY95SgQzlc1Hu7AMrueXrhQ+HL0VNgxJQBLkNK/UXdCvLkyfDFRDtXFHh1oeSNI1ewTwaZJvn6oFcOPuwAv+/r6xc+7mNcicGJuUmvsAQG4LRb5MDriDbVl2KyTRW9ebL4Mw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770416718; c=relaxed/simple; bh=oCJM+Rr7JVsz+oeqiW3eAWsUmuqxZlKgbkrzgaB0YjU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EKyUvThelqAJxPbyMi/h7U0VAGCJUuT+fVh1kOdk/L72OFM3LHu7B+1ngKQwwRia3L0SlBPvNBdEn0Q/HaGrfljQQspeQ2ZyA5Pi2ni6cVJo1lKI3tqYkyEAhMldTVxfqiersXlutZqwh4KJNsXhTqcdscXwHg2ao3XBSHQnHb8= 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=VNjsd9M7; 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="VNjsd9M7" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-1270878c3fdso1661954c88.1 for ; Fri, 06 Feb 2026 14:25:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770416718; x=1771021518; 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=hPCduTIdh2srDUZiYkVasbXP897FIHgjqU6XNx2eU5s=; b=VNjsd9M7c09GlIVKMoP0JgpTQenGWfDMx4P/LBqFx5QEGI/kgzQJ7qtAQtF3FVHB9H b8xr3JRIv6z3Ejqxn/aYiN8ZUl0NXLBd27YVRkLiXtvYLQO479d9KWrBHV3kHUouVkD9 nG5mHevo0LBBeHd2TDpg9efsBWr4U5hNVkHRgnvw8SA0rC0w9iNWWWY1oboIcASsEle4 ACgcoNM7UI30DeD5TH+eiIk4Q/kIntV8GMIQ4YtgJR14HLOvuONEf2eLyMLsFDlJ3GER 0OlTzpCDNIOWxxut6OEx6yiv5/OAN0xQtMtHzplL5FSYZGi0QdDOCMlJW4E6OhSekwoH u+3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770416718; x=1771021518; 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=hPCduTIdh2srDUZiYkVasbXP897FIHgjqU6XNx2eU5s=; b=J3g3P/YhcnBOTwxiNDblXsZDer3jiWCycjrwxVnSm5i5tSQZHPSM5XCzGy7tJdrE/7 Iy/H5qtqZ1zsjCNN/coZt1/EATTVMDFxk5jq7KOA6U8ozB4lZQgad1PlhxowqvpyUtBF KRme4nqyQu4GmuLA30xIO+0oQtylX9kXntMxHKHVxsxyYk+skt5RtvKeCJMk82beawVX 2j/xj99qIiFXtVjBoE0xUDDsQ2GcARM/hSrbjP/pKU7PSGJe4rh2ya67O9MPc2jFKaKK ZymzbC1Kp2fvZBBeIWgoYZjEaJWIK0pgW6n9QdX00H4BuWf+Jyelwx0OOlZ/Xs4xnA0h vonw== X-Forwarded-Encrypted: i=1; AJvYcCXIfHymgIwYzsxpR5Ly6M4zrwlNg/s9ylHniuKSFw+WNYWNpNfZjGUd5EIZJ8rCwaI2F5+vIsaCyqur0aM=@vger.kernel.org X-Gm-Message-State: AOJu0YwmpRBheHrAKWqiKhlZCz98b5Ujzvt/M4c1Kfd4SBDahR2MMRHx ePwUtA4ckAODKfSfVC3MXTk0OAxaOmcbxkFz0nxxb3nDBMN/K7Ka4mpX2AcPJBEf3/A/vPvdm56 HFHZiZZ8T+w== X-Received: from dlbay9.prod.google.com ([2002:a05:7022:6609:b0:119:78ff:fe1c]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:62aa:b0:119:e569:f60d with SMTP id a92af1059eb24-12703f3c734mr1809216c88.6.1770416717548; Fri, 06 Feb 2026 14:25:17 -0800 (PST) Date: Fri, 6 Feb 2026 14:25:05 -0800 In-Reply-To: <20260206222509.982489-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: <20260206222509.982489-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260206222509.982489-3-irogers@google.com> Subject: [PATCH v8 2/6] perf stat-shadow: In prepare_metric fix guard on reading NULL perf_stat_evsel From: Ian Rogers To: 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, namhyung@kernel.org, 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 Closes: https://lore.kernel.org/linux-perf-users/cgja46br2smmznxs7kbeabs6zg= v3b4olfqgh2fdp5mxk2yom4v@w6jjgov6hdi6/ 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 Sat Feb 7 11:05:02 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.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 2FA2730E831 for ; Fri, 6 Feb 2026 22:25:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770416720; cv=none; b=JaUXmDVGNb3jVtzEde9XA4dGi+pcwzFXIqsIINfYHT/kSZy/N1m26C6ZcWguLnLabTy7jbBuVUecCRiTKGCMWJYX8urKta6rqKP/oMi83R4f56/YTj4RIhbSvXEhih6Xk7EEmdD0ubqplGNCLUA7mfrczS+TvHOahs0PcEPGf4c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770416720; c=relaxed/simple; bh=m6NLJ4Vb0UEPbPzi83NUsogmV6qs5B+5r17ynjkDPV0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Sff1S3Rcg2h/vMs5TY1ZagpNOSG7NJDG/KgDfK8kkzSWA6z7T03qR7KAf1/hCjWs1fH44mZ9vnh1uvbETQ9XwYPso6/AcXP8VQKt3DMsBrLVFVY7E9rmF1JAUqXo124/SO1aOEQVgX0893hFUiEgB9BlcSHr+JrOAGSX6A12ziA= 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=u8bD5HVm; arc=none smtp.client-ip=74.125.82.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="u8bD5HVm" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2b7ef896edcso18164989eec.0 for ; Fri, 06 Feb 2026 14:25:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770416719; x=1771021519; 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=u8bD5HVmhQajjE3oyND73AFehXriXgPhGRIHDQc4ZTTodZmI//XbaibrhPgrEp3AU/ 6g1lYrczlz8yHu5Hyzck/fQGOD8Jum4rXana1qqhUUCpOdq6iDFR/QKIMtQ+DJZfiTQa l3/Tqg376wTkuVzcvKCpjicOua5I1Llo/hP8GT7sRxqBw9bz+nN0A5Li1bUfZrHEjLU3 PKI4xSvdA+jLyaxwgXicbqF8I3C8ZAi40XBkPBT+yUPf8awrF0F3HjHX+i+7cMkwFOvm Tp10YCUAXnbphPV3ZZCg3gPTFWFiAaEMqFniFwJj96KJy3b4hqpv21kOoqAYFzMOQicu Hysw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770416719; x=1771021519; 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=LRKuFkotlhGqgAIK77UWUE9gZ6W6sppZd4SQDT2hTVxsFkJqH42zyFIOjkInFFxTJw 5wknmMytfbpgCBdQaXcaywdSSy+1xFZ3tYn0hklos1C3x6i215+rz53gNpz2gbQTtdQ2 Ij/BdRNaL53qTQeGZ9+7L7KvfjdwlCSHLzAgBjQff6SCtI92MW8cnCwE3Flic/8Y9Hp1 ofL+ZCRXg/ngRIFg6f46kiCc/ypc/LAAkyHUEu8e1Qq/qkzYmPusjy28mNdBW0JeMj1w 81vbjRsjjU51M0zdtsiV5nsoyLD5JmS93bgBt/DkzmTXFv/A79bOZsj7lDy367jYpWkE 8qsA== X-Forwarded-Encrypted: i=1; AJvYcCUZBsRql9iVudX1BR9RwdX0AZICpU9V+qUJxBKuYpXDyBiu4we3d2LiugbOqfdjsJyg5n1Gbez0eNbrK28=@vger.kernel.org X-Gm-Message-State: AOJu0YxeOOHPP80OcCA8xkfbFaVbc4H/vTE+0u0bo40wI1HmY2elgsGD tQq9Hp0sih7WhUS2+b1j2XrlfRNdEWSZDY7yIxMKcNFW8VIUaLf/axoguPRXoOTwxucjTgcKSMV c5CUqfcEOkw== X-Received: from dlbcq14.prod.google.com ([2002:a05:7022:248e:b0:121:7afb:490]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6b88:b0:11e:f6ef:4988 with SMTP id a92af1059eb24-127041789f4mr1887886c88.36.1770416719225; Fri, 06 Feb 2026 14:25:19 -0800 (PST) Date: Fri, 6 Feb 2026 14:25:06 -0800 In-Reply-To: <20260206222509.982489-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: <20260206222509.982489-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260206222509.982489-4-irogers@google.com> Subject: [PATCH v8 3/6] perf evlist: Special map propagation for tool events that read on 1 CPU From: Ian Rogers To: 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, namhyung@kernel.org, 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 Sat Feb 7 11:05:02 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 0F16F3112D2 for ; Fri, 6 Feb 2026 22:25:21 +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=1770416722; cv=none; b=sK3p1CUowfmxIYn2kdRgmgOvrkqf3yhrsTKBPPnRQ6do60woukWrNif3HMrblijKia7vmtrAtKyRuEz5KnAJ92JF+TAvYyAFuB1OqYA/fXGAiXMtmgHThUYrRjXaLGjemt1Q6TpkRerr8OGR6o90hni6WCGUirbP1SdppbZDAlk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770416722; c=relaxed/simple; bh=s5HhmH++c0S6/4eaW7RJwAr9NrI5mDPAqNzC53KKvuA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ayKrXm1Yu6eXKEoyCdYJZTJN6d6nDINw7PNacHfWkxPWd2LW+N36CnjGYRm3p/OzGy2wS312TsH5BHFP+JV9qJhreW/WaYMAnzG2LaXora2JRzf/+anVHfIC3tjCrzDkhW8lfAgO3IV4YzNfUlUH7Bon/JvQ57zHP1Ti7KY9gWw= 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=DabrC/ZC; 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="DabrC/ZC" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2b71c5826fbso2696597eec.1 for ; Fri, 06 Feb 2026 14:25:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770416721; x=1771021521; 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=DabrC/ZCdDzkR28el37cy/dZ1pU9uzENnqJHzjU2A4WRf5Q7SGbdbHJWU3rCCzqtzG U4WNX3Lx0e+0rlu0RSvASod6urJ4V6H8azG41SjnM93oaDKO1LGhkU3UdYwpDMzsujRJ WbswQ37o1xdq4+bELACiBTp+obXiyTAW5KBwance+IcTRvhQliTxYPMkaj+Bn3Num/sj uw2QmthMjNr8wOb89eFjfldcD2flerzdSRW3lWF3K4qkkGcD9OXF/hHulXYqqRg6ajOs IzQAvWPo0gWUqf2wsWpJ2jRooFk5hzEurzk4izL9J7DCdUNpGdD+XAK3C8fOhB6fw+W+ FjQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770416721; x=1771021521; 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=JLV/FxPoNBk+W8zOEOV0idz+7ZFC/CnxnB1OJcltt0vtc2U6C7+x3B3nR6dzipSBbt I4xMswTUd/hFZRNcg9Ym4SxoPBeNVtSkTdt42tzmhw2Ve5MwD4/GtSL/N+wLFgL0YadW pkxuRSpgTyduUo0yCP4gb4lLF0YKjUGWbvbPBFM3u/6nGp8AnVNGfO4mxav6otGdJocj kVOs9KFnfmJJgP0onnQJazc7lwCDv9dV3EI9grHzIuiXqB+HlhAeIo69WAPez+T+aljN /ykvReBoM2E1cBWxdmVkQuP7sMv4hsuwcoZigEAAhmcPVG9DLm44NSil/EI6CyAHfcWy V7IA== X-Forwarded-Encrypted: i=1; AJvYcCWIwZHBeb5zZB23WFDButaWkfB8z2O5S4ADrpghN4NCBUFFHkE/zYRCFIz8uk6vUu4TCVdglBYxSjG3Kes=@vger.kernel.org X-Gm-Message-State: AOJu0YwMATIjS8J2K8nXewN51dhF5m2yYkaEQvTw05Rw7H/VzRiCqi+C 8gz4NWe5LwlDkwumryYnLJIny+58pLovasLLIWEB70E0QCTw6+mM72S5eRuFr6jTJAjSPz/9Bw0 s0OJ+sqBAPA== X-Received: from dybpt13.prod.google.com ([2002:a05:7301:408d:b0:2ab:9468:d9cf]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:693c:3117:b0:2b7:2d5e:914d with SMTP id 5a478bee46e88-2b8563d8ba2mr2179061eec.9.1770416721194; Fri, 06 Feb 2026 14:25:21 -0800 (PST) Date: Fri, 6 Feb 2026 14:25:07 -0800 In-Reply-To: <20260206222509.982489-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: <20260206222509.982489-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260206222509.982489-5-irogers@google.com> Subject: [PATCH v8 4/6] perf evlist: Missing TPEBS close in evlist__close From: Ian Rogers To: 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, namhyung@kernel.org, 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 Sat Feb 7 11:05:02 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 64EE230E831 for ; Fri, 6 Feb 2026 22:25:24 +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=1770416724; cv=none; b=NcepDzaurNQZI/K/QIl5FZ2gJ0bKD0ZzxIVN9AcpDuBGAq/b13pU2As5ZYQQQSzfMnVdnxN5AaTjKgD1H7CZ4kxSR1yK8WwYLGsl74KAZIGZBjbBcAwkUdCTpFFkBmBcSm6uxq8kuUh4mADpQDxZzKG5lTXQlqFcoWU0kqNnx1Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770416724; c=relaxed/simple; bh=nMCvD9FhHWv6QXJohgSpbLwo660AjijJtxk2b8JgbNs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=OM6XBMBSPkKYLfCbYJQJq/kO+ETtNVKRmxe49Hjd0gcP/DfgGi9aqupw+TjrbmKmaxkmxJMSwjChBVSfNApBSCLPGgeqYzUEGoeu63fLtfp1E6gG53ySwFaY1MJD9FmV0gQsSBDWU/WLNHFnPYTM+X+s9kJHoFGyQ9hOLEAu/vE= 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=1LBbKBj9; 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="1LBbKBj9" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2b866e72c00so213832eec.1 for ; Fri, 06 Feb 2026 14:25:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770416724; x=1771021524; 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=1LBbKBj9KMYsZLeLqUKWYB6nQtZlsrBYLUOleYiKCtoUamFj0wyNfkI0AsUa5Ge6eM fXliPKID2FS7w1SyaxKy/nqRvL2cPoeC24fJ5azB/ekfx6vVabSbvZlhN9dpxjBfs8Ad HNtcq7A2THz4N4Q3vH2PrZrMZukmncsJEvFM7dD3xnKS42ztaxAbgx+ggkHbXjpss0Pz /IQr/G+33hxutGGLjrbR3PvDm2ogK6tawLEGvR7R5vspTEpF9/y2o57rKq9wfqcjli/i R4paiHNPn5kpkO/NGTAoJfaP6PY/ceh2JDMAEqxikUvC0iLjDolRMmmY8pC6CMAVlJKh yXPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770416724; x=1771021524; 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=VSbpzXwvtg9UhbNJb8FnQepkGnnS6vdoPo+D8kuQpEJJT2FIWJ/U3CrfIJvpT6zLCT E7cWVqAgUN0JUGtYW2/eaZJir6Jh+vdcvJQQkGse6PwgcH9y2UdsU4egW3ANwQgsHj9c gy3WEVc/Xd7nnhgeSFRgxtx1aBaI1idwhf8iJEtoV3g3NuBxnivRcsQwF4qXp+7zYZjq gEpNxEQVjxLb90Nux0S1LOf7f/cIiMWAOUGBjXmo5sLd+MF/71/XhhLMfAy0GR9dG8T8 voA9Vky8sqviRCYaELvtfUVd+dKOKu7L1nxtwaNQRtclUhULB/5iOZAE/2qC0gnFuvaB GjwQ== X-Forwarded-Encrypted: i=1; AJvYcCWjYG1+YdsNxQSu0S6DeW2sB8n7zLIwuDARCfl1LBhPvHpEyMdaMCcfOzgn0hLdHUWirN0W1b5IG9oEQB8=@vger.kernel.org X-Gm-Message-State: AOJu0Yz1gUDIIjzZPcuveQkYGD3RKivX3uGFExGQPaCuF1HEdNdVdn5e Yief+KO72sON4EUK5+rPupHY4l0GCfQRjEVjca32wwiuGLU+fBNtLozCrU/TDduEFlCX1pY4e/7 KMaZI++lDuw== X-Received: from dll7.prod.google.com ([2002:a05:7022:207:b0:126:f8d3:3aea]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:49a:b0:119:e56b:98b9 with SMTP id a92af1059eb24-12704048c3bmr2429877c88.32.1770416723640; Fri, 06 Feb 2026 14:25:23 -0800 (PST) Date: Fri, 6 Feb 2026 14:25:08 -0800 In-Reply-To: <20260206222509.982489-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: <20260206222509.982489-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260206222509.982489-6-irogers@google.com> Subject: [PATCH v8 5/6] perf evlist: Reduce affinity use and move into iterator, fix no affinity From: Ian Rogers To: 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, namhyung@kernel.org, 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 Sat Feb 7 11:05:02 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 7F1EF3093D7 for ; Fri, 6 Feb 2026 22:25:26 +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=1770416726; cv=none; b=WzTSX1oEouFI1OVIuyxDtRwpbe5jGC+f3RPCJQYEx9CDh+sK8eBI8ek3nfak4uEy0EiMMRzLu114DR9lpACCg5rdsyvXl9zJT2x4TjngWv3ZQNZw3AG6M9FaEHU+GsVDUDeLIhoJ9/FC3EBwu6g8Xl1ELfxaYKNkcMHgpSSW1ek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770416726; c=relaxed/simple; bh=4dzqlAY6Jwfn5UZRMxqibkJ/WzReutE/CulfgusKL0g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=XqlQY/CVItPLLdP5eeALJV2cX6bQmvIQRUEW0BbR0QwHxp7Xizod1hPczhHj2g20+sYc+RwtIAOp5ym/yxYRAgOADVteiZPEGgCNR7kn3oWzkb6qv5uXsnoQOP5qIIhWI0IB+kXzz/nsfpEYY6GMqDg3uNQx7tp9icS4isNnCE8= 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=jKyI1YMZ; 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="jKyI1YMZ" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-124a95d580cso19959535c88.1 for ; Fri, 06 Feb 2026 14:25:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770416726; x=1771021526; 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=wNGV+9W9psENt274mz6PMhj6c8c5MewbEM3NGZmHhlM=; b=jKyI1YMZU8KbTKscOXZfdYZu4iM6Y+wucv0aNSVZL2q667YcK6+dF92c3RMhRV9W2m qOmtvaD0ur+uLDDJN7xT9sNbS6Lz305e8BrSOCGvIBsj0hjgI0kSnuiPD7ofOnyruFDL RDf6U+eX54DrEdc8Yiz10Ou80TQTSxNoN6q6z3DV5nxhELEGbe3HApZNgHIPO/eHWOnJ pmNXCv2DUqa00yeJWgecuN2uRHV6ThHRXOhzomMbNQGI2cYPVbQNhsgY3TQ2Kf/wQwXY wC7c9W5oGUIPFJCc/tcICBsyPJfrpZQaRUyhaBcpxTpth3LSKysbWip+4SWbBYW9W1BV xpEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770416726; x=1771021526; 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=wNGV+9W9psENt274mz6PMhj6c8c5MewbEM3NGZmHhlM=; b=BoX4xzhJWZU24mhipPBp8u2DHYjWmu6Cu03rR9FenFdXMudUVDJM6pYBb7+Kki5dnX g7qVUQ24RLDWdO2brMpUL7dcHPjP34hjcYO2XafzhrQeWIffXA1aoyClv7f9gX3xsL5H 3kLmzlVDaWMhztrvLD0lAWJTIcTE89i0THSf0WdRAs9JhZCutSwKaQ9iO+XU6CcGehj8 f/TbI4Pkcz+bC9643zpQPGvqI+YQ3NOcks7fQUGO1+P4WDfJwKVgvBLgC6JfwJzhZivl CbGGu6A+IzVu6HVfLncnlviSHuO37wRo60dGXP1JK6Ek9RCfzGopL7inc3VoxHDngG5d 6TMg== X-Forwarded-Encrypted: i=1; AJvYcCWhANnEuKXW9S1lEpQcoZkMWLU/IzI0XgOi8WJfyLZRsFWM1UpMJs2r8fBe6bCt5yRWQ2I2a4Q0KE5OnUk=@vger.kernel.org X-Gm-Message-State: AOJu0YwWdG9S5jPAYt0a053urv5iDbibP4sLW7FKsWMkMq9/LZjOASEY Jeu6k07SgKn3xuqNr9BcfWyv0sH7t5ZfDHlg6ETc4g4XVHrjTyLh5gtFSJd9t3Q9r/0incYCELy txzDq2NUi9Q== X-Received: from dlbur6-n2.prod.google.com ([2002:a05:7022:ea46:20b0:127:c76:21ec]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:618f:b0:11b:9386:a3cc with SMTP id a92af1059eb24-1270419f22amr1886234c88.45.1770416725561; Fri, 06 Feb 2026 14:25:25 -0800 (PST) Date: Fri, 6 Feb 2026 14:25:09 -0800 In-Reply-To: <20260206222509.982489-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: <20260206222509.982489-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260206222509.982489-7-irogers@google.com> Subject: [PATCH v8 6/6] perf stat: Add no-affinity flag From: Ian Rogers To: 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, namhyung@kernel.org, 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 | 4 ++++ tools/perf/builtin-stat.c | 6 ++++++ tools/perf/util/evlist.c | 6 +----- tools/perf/util/evlist.h | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) 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 c1bb40b99176..8bbdea44c3ba 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, + "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)", @@ -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