From nobody Sun Feb 8 07:07:27 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 68B0637880E for ; Tue, 3 Feb 2026 22:51:43 +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=1770159104; cv=none; b=Q65MRJK0MemDTBynyYO7tFO0FltHXIsByA3O9o1j0gZxJlyoZ8PTykp/XqWsG5wfwSBlzBS+9YjKIDJf2KVtjVuxueB8kngYbs530SEd/hPVxSdliHXVFdJAB3bjvHBolWFT3sli8W56HEyComXoqAo+eGS9M9Dx2Fcmm8yqDNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159104; c=relaxed/simple; bh=Lszd0UdRB8GQidhdx5Z+Lj/C2pK9X74pxC+as6fOUOI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=MZbT0eUduxlKlTQEt17k0RPZQHnDXZ9OjQ50QrnCCqhWrTg2Epsxof4dZPlqoDJHNQD/4c31NIhs4q9Lb7IMewh0RQSrR/8HBOvTl7XRhrdrx4wAPAP3kozxa0+//s8dIbqJvGaaYLk7t2shYu3H4xgbihtjxncm/Z2Jx5Fve44= 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=UMTVSE8O; 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="UMTVSE8O" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2b82974bd26so979118eec.1 for ; Tue, 03 Feb 2026 14:51:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770159102; x=1770763902; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=trHHoM5lxs3R3c1XXOrfjjzTr20GXbuQCFUGYGyaPS8=; b=UMTVSE8Opdysybw1ciMXZ2wQe9F62QqECocfQ81UuYxdFiyUJ0PmFwNrjHSufpKzjW XRHxdN/SedmLi0HYPMVx4ScqL6I8Ng6aybjJV1H8tmwksoVMIrZisEDoBGHh86Z7qW8U XC3Y1h3H6sHFJC+lUU01vxNCS5Q5/SJ16HxFlwNP8R0vTpB9+7+izqlHy76QSvVvM+rw ZAtXk5LLAuM/2sTlnSZN/mzYAsVW13+737qa3XjIuf7HiYawUoLZSqaBizdUgGfoxVVi UAyLMlnCIUsUu1MdOOqfTA4864qiTZMWcWENk63C0cSj4bLkzwbuDCZtQ4KpX97VSq2W wYNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770159102; x=1770763902; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=trHHoM5lxs3R3c1XXOrfjjzTr20GXbuQCFUGYGyaPS8=; b=FfFtNEGxgwkVByxiIvG/uYLiXCMySOV1H6Kup9HwpfViUNFFMz8xQbyCmee6S1ygFQ OHz+dXztp7lrM+NzAkQd1clxIFfSoE4vm3LU/gi/1Iqb9Iyyu3+B5pvqDByxY8557UNr 4Lo/IzGS5bPQgl5a+DfnlhRSiYU0xyfC87Hmf4+f/JAPNEsfr7+VHz0L7yhkBmV+ZXny oeou9UfqCj83N0gM1cHoHfrWekACPqPmPRD0aMy08Bw8S4I1jr6DnekX4HnrcGxMkCgw 7yBPrywIrx3kX9PrnqGtnj5OFBsiWinPPLVeZFUA/mZjc8bsgcCUz7E2XWoxKrZ33O+F 84dg== X-Forwarded-Encrypted: i=1; AJvYcCUHexMkTU2ZJSf8rTnL78KFrge60ccqIlwRbErPU9UlxW3urFiR3IBfnDbTLSDt+TceQbiXkz3eMCJqqaA=@vger.kernel.org X-Gm-Message-State: AOJu0Yyh+HIXYg5APgICwx88Xx3xoe+UBAEp0lOS+qCwkv4oJoNXmRAM j3g9/Lt5yCBW+eyiBtirgbnitQmddR29QKxCoNUKypibmfx+Bkk5Pybf0strQvgmIXxAv19nkfR WAtam8c0uqw== X-Received: from dlbbt22.prod.google.com ([2002:a05:7022:996:b0:11b:d8a1:4048]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:4a1:b0:11b:1c6d:98bd with SMTP id a92af1059eb24-126f47822a3mr457703c88.9.1770159102548; Tue, 03 Feb 2026 14:51:42 -0800 (PST) Date: Tue, 3 Feb 2026 14:51:24 -0800 In-Reply-To: <20260203225129.4077140-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: <20260203225129.4077140-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203225129.4077140-2-irogers@google.com> Subject: [PATCH v7 1/6] Revert "perf tool_pmu: More accurately set the cpus for tool events" From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi , Andres Freund 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 Sun Feb 8 07:07:27 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 DA3ED378D9F for ; Tue, 3 Feb 2026 22:51:45 +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=1770159107; cv=none; b=Rwe3ZpHONeqNAX7ksLeVbSybyXyVM6HFXR8a45GkH/ECJf9nPpo/uWKkO9VpTYjQY6pY0glQVR7z1oT8nPl9Bp43EnFrqN4Nys4ucQj0/v1F2QL7FZ2DVpJ1oTqZK5oNz0Ad6c3qH5Kw7AcdNW9BW34Qn2n42a7jLCWv+9jNAuw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159107; c=relaxed/simple; bh=y3Mk9sAgkuN3mOITzM5MtblmDiqpA0EdmXDSE+EyzZQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=K5LvYUVM0P0UxBboRTlUKgmGYznNbYvYjdroSWGLsxXKQK+EuitsDxkeJqUS6zNwR9NZiH0W3VZSbUZr2nQ8HSF8EDYZy4tcFQ7J/ll3GEXdybLksEFH+6XbVBCQc8nM59LUWrZU0j/FlJXDoXmjpHO28dZKL3UPpsUe6iCazSU= 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=ayvevPY+; 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="ayvevPY+" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-1233b91de6bso10752227c88.1 for ; Tue, 03 Feb 2026 14:51:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770159105; x=1770763905; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=zzsKRSqRCFvt6FoeMViytQ7VfwZPfcB23PzvAjYa0/g=; b=ayvevPY+tMIRfl/1yZkq+4CslQjsNa9mK2TDULJfMqhvyyIv98GnTVr84nNE6iHD4S lzjcvBMgK0cdV1+1rkhjX9GMTYKDisaTnW8V+jYZv283imyJS5i6sePRQhRtEBjBFpmI rDtkH1JyWPCJ3rLDHVNVawn9O7PX66FU1iQqWhpMN2Qfb/Xu3PhwrzHfzzMNpuawnKqP 8b3R0oR16uuHbGGKop6YoUXiiyzKAMyslSgYIzXET1qxE8quliE6TO9KYVNnXiql8M66 Q+S/F8TvXxsB4ZMcfo+Rq1G2Kp2MyNRt3hmbJv5FIYKLfsUG8jJl+gEfsRDTl4lGBpRk JvUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770159105; x=1770763905; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=zzsKRSqRCFvt6FoeMViytQ7VfwZPfcB23PzvAjYa0/g=; b=Rpyg3zwtsq62m25l4Cuup+1nTSfJZnsS5wzGF8WIz+qibN1j8/QSfahayDhm84NMkT eLQS5roF29HaWn6WktCXHTNUnPEtRPPeCYLvVonVl1KUhjdIEKH3yxiBSN/O26ty7h9H IJRPmWOJa25XfdNkVsjq/sIe9gA2RhujylDbjkjWdF/tsQTNGsAzIeXao4MME4s/JZGc Qf0ox/TUllqH9Mn1ZjtkwDxVF2YweeDko1jug6gxOLpEjDmGugv6KOjIdWDtd6i7XJjX iiyus1ImA3ovZUNaG6mJB3YrtYwFc2slIMlPzQNlLj+B1JE9ZbMcBn65o3Rm3dbkYj1P 8djA== X-Forwarded-Encrypted: i=1; AJvYcCWT+MNy6gGxEGGjD5qqNjIJTNYXIx301Tut9C3UT5qDGnEbtWr8FQReVXlAnn2LopcI5No8o1qFqZhfNUY=@vger.kernel.org X-Gm-Message-State: AOJu0YwOg1GkxzWamx1xAiqqWI9krsIx1DxHmPzThjUBSjXzZtzAoeXN 295kc9Za6IsQzRw/Udww68a+LaIT7cQePVqDgKj0q/iWCDDHWwFgKaQm6Oe9wrriKNzWqTJTRJC 1cVLJH2lxHw== X-Received: from dlbsn10.prod.google.com ([2002:a05:7022:b90a:b0:126:d3ab:7af6]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6892:b0:11b:c1fb:89a with SMTP id a92af1059eb24-126f47cbf2dmr456724c88.32.1770159104993; Tue, 03 Feb 2026 14:51:44 -0800 (PST) Date: Tue, 3 Feb 2026 14:51:25 -0800 In-Reply-To: <20260203225129.4077140-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: <20260203225129.4077140-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203225129.4077140-3-irogers@google.com> Subject: [PATCH v7 2/6] perf stat-shadow: In prepare_metric fix guard on reading NULL perf_stat_evsel From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi , Andres Freund 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 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 9c83f7d96caa..7a481b2960a5 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) { + 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,6 +91,9 @@ static int prepare_metric(struct perf_stat_config *config, val =3D NAN; source_count =3D 0; } else { + struct perf_stat_aggr *aggr =3D + &ps->aggr[is_tool_time ? tool_aggr_idx : aggr_idx]; + val =3D aggr->counts.val; if (is_tool_time) val *=3D 1e-9; /* Convert time event nanoseconds to seconds. */ --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 07:07:27 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 E12F237AA80 for ; Tue, 3 Feb 2026 22:51:47 +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=1770159109; cv=none; b=JG1wBUWa55+Cni2vYeguSUwkxqUMmq8fyhSBqLRo/GRvNVNUFmGJR2XzyEmlv5rITjKeUYrecW1Bc/LmgapIM50yGtu9/yu/2JOddtLke4T/dAhDoEvXdUKObCenxldCQgq+7/qXJncrRXnWWGk6eVJa4+yvqcY7j9S2Su5UKqw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159109; c=relaxed/simple; bh=m6NLJ4Vb0UEPbPzi83NUsogmV6qs5B+5r17ynjkDPV0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=WyIwqpI373BMAmws6Z4j4kmO9tEX4VpKrVPy9RPLb8xlX4ZoIc8h3wqNyFvTv9XMytR5sZmiAg+nHynDkpl4MSBeJ0arYskFCwfWIykBKoazIR9S/e91qLsyuL7+/uBm+FLFhjIZtVOz0Yfp1R9cA8Gfp5RwIx17eOw7fj9TOOg= 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=ZnnFYfTj; 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="ZnnFYfTj" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-124a95b6f61so22233474c88.0 for ; Tue, 03 Feb 2026 14:51:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770159107; x=1770763907; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=sOJSg9cHyId65pfgpXUFicdk0Bjz5b4dGSwLC1Zzl3E=; b=ZnnFYfTjFdoj+dp1bJY+evxkwFcrd4/s/L4C5uJRhwxirPkVg/qrBkeGURHbpm25j7 nCyDTZDjgYwAND9Db+/cR7liGdJAFJ9jib0ey+8EE0GTC6yhS4CVC1K+ksttfzCGc0ML VEG2hKm1kb2geHVPwkg3CgPTHOUyArGFl3K8+qwl6qEwQnrSI1hfkop531FNFHlnEntP 4zJ7MVgP1umffQ/li5fFEXEBHdu93SAm/ytLHj5pGeCO9d9NpIVb4PvkmDgNbk9eI4lK uUS/u/fnkXP+wnj9TnQ+KRea7M8foGQPAbpe/2K1vCB8Iv5kvFY0liQzAc1VUa1HCOas l+uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770159107; x=1770763907; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=sOJSg9cHyId65pfgpXUFicdk0Bjz5b4dGSwLC1Zzl3E=; b=vWAJ1WAPArVaVhrTtFRLtsenjhkFj0ONIcbjzR6vx+Vz7MaEKl/Y5aJ2mxe0svkJKn kHW8gt/E2F0cS0aTnU+0PxI2fJE5p/Kn+g+/NKnASnefcGTv78Q/aTTQDhJ0qbZ6eqQZ VImlX4Ud36S6Irt2czvMUZN4RomG8d/aK+9DwCvrs64wc53S/BcZMYuec/QIjbYwI/CI cMUrPLb1oQuEvIsg7YHZhDCJ3JGg8uqesC8BeS1ulQurcB9/Vo8ylNWH2M7qPIwyQn5C z2MZRv6X2lElRUdTcyEFPw5jTajdmlh2bBorPaogKFFffxPitwW7oeLI6VhZ14Wdvtgn Z7kQ== X-Forwarded-Encrypted: i=1; AJvYcCXSXgqbe89NwjrOfwqfYj+qjlWkikvRCdg0HFUyt89uPIguQT9OyuVyqsX4KhqYUVXv+S67wRXQog/kePc=@vger.kernel.org X-Gm-Message-State: AOJu0YynlD87gyvFOjzE57qdRPCvvUl1ceHhenkHDGt3bnLyUJg1m6XK TgITJXloJ//b1L3nZBhISldWxzeQk5XnpGbN9M5NWp/w1VfYaoBi1/Xyn8neNZseCsFWoM8B+ar eG0+euPfF/w== X-Received: from dlbrx15.prod.google.com ([2002:a05:7022:170f:b0:123:350a:ef0b]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:4592:b0:11d:f462:78ac with SMTP id a92af1059eb24-126f47bd24bmr377925c88.28.1770159107031; Tue, 03 Feb 2026 14:51:47 -0800 (PST) Date: Tue, 3 Feb 2026 14:51:26 -0800 In-Reply-To: <20260203225129.4077140-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: <20260203225129.4077140-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203225129.4077140-4-irogers@google.com> Subject: [PATCH v7 3/6] perf evlist: Special map propagation for tool events that read on 1 CPU From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi , Andres Freund 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 Sun Feb 8 07:07:27 2026 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.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 8962137BE92 for ; Tue, 3 Feb 2026 22:51:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159110; cv=none; b=aocuJZ73yjuXLj8QZNm2VVJR264XsgssMTpw3OpH8xC/b0BAiPueyzBIUTDToSAW9Fot6KtV4fujTblfEXP2wVucozrXfReJoTk2Ul4cH9EvGnfpDUuWT4j6nb5AmBtuuSe+prl/ElS5dJnywCAl9A8T4Gsl0xdD3YrTI56zfwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159110; c=relaxed/simple; bh=s5HhmH++c0S6/4eaW7RJwAr9NrI5mDPAqNzC53KKvuA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=QmugAFcqugK4M/dVc7vBjt+mmv9bsArbnsM+AEjbPmyuxrFu7jTfJMUq8Ejl23RKhQa3VuQxdsiIKT5LL4vhBtbEqIbLm1aWNDkqlxolu1Ku6smrgdPkmG7G7Is24AxslchjR5zCw69Gxg1HB/MIv6grKaQKWPeT+Qz6FaDaXAY= 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=w8k92nB0; arc=none smtp.client-ip=209.85.210.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="w8k92nB0" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-81fdfafe6e9so2700598b3a.2 for ; Tue, 03 Feb 2026 14:51:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770159109; x=1770763909; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=grVQSNoKkwDwm/7kB0bTBCG79LQ7uooFEeHk2Xib8y8=; b=w8k92nB0s0+se+Jp7/IveA9ik0+TxcfwI0nCBamCWUQXiSwP+OqC3zDSGo+rhus/Y7 yqf2QrgY2xa2jIxTxb6IOgZxwxJdC4gpZlLt46LpWmY5KnYeRoK/7TXH4f8jsWrxuCNc 6JSAREjrOkmp9JnxBcxS0TD1nQIPRRFSxE8ksHHqSUevy0bK5RCJlCg4Jv6al9LI9KEC 7uAVtFhfbuWGfd3xtEXX9Q1eegZxxX7COnTSS6afCpzD6skuZGrkEAR36k2bB/BjqkOC p/0GFtIpMjNV0JTzjgNJbmTHgqrvxQh0SXpSFhLCwwa4LFu2Oq4Gow88UIb+mOimcTnM 2gmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770159109; x=1770763909; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=grVQSNoKkwDwm/7kB0bTBCG79LQ7uooFEeHk2Xib8y8=; b=KzGZKodD+Lop5I8a570fFv8GodfgpOqSDnCLTHXDX7AVHb9IIdE/aliJyDjJI5KeYo A0I/fATToM083lhSGQNAsgd5oS7QXJN5AgXqRVnFR185Fwl0JYYPSHMWa09ZpwUNJ/a9 nNe5+5pXUesOV+671uY9DEPZFsqL9c2QuDUVYK5vSUdnGoKJTxjIvTw4J1bk3gq/cmPP xJsdWiqHLqxA/SQDDVXTcvmqh/eU9PbDc4irKmkrtCGeqrbAS0caryitftKLqt4b/K3L e1REvmNMgwYq6MQrRbG2VWTWItszifSUzgRyUZb4DkWdPfBqlosBIB9N3EbBLIFxIyj4 qlUQ== X-Forwarded-Encrypted: i=1; AJvYcCUVaQ1BiijVP4JwrJwoIoKqr9SNrVUFeGueQaV4N9D0/avSlf8rqkd5dVvmUfsUydDyofRHM1ZT2pIkzVk=@vger.kernel.org X-Gm-Message-State: AOJu0Yw65Np/2RlXbJdAr+bUsMdVYWGsdgwEQJ44KHXqSpakY+N49W3G XLhpRf8CTavNgNNG2fGqzqpa7sB/U2djPvbYFvAqUeu5Zu5oxhAvrt8lK4cO0sHh6OLxuSIyuQe lmVupVC+KLg== X-Received: from pfhu26.prod.google.com ([2002:a62:ed1a:0:b0:77f:1f29:5399]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:138e:b0:823:1c83:e4cb with SMTP id d2e1a72fcca58-8241c694308mr956635b3a.62.1770159108788; Tue, 03 Feb 2026 14:51:48 -0800 (PST) Date: Tue, 3 Feb 2026 14:51:27 -0800 In-Reply-To: <20260203225129.4077140-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: <20260203225129.4077140-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203225129.4077140-5-irogers@google.com> Subject: [PATCH v7 4/6] perf evlist: Missing TPEBS close in evlist__close From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi , Andres Freund 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 Sun Feb 8 07:07:27 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 9AB6537D104 for ; Tue, 3 Feb 2026 22:51:51 +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=1770159113; cv=none; b=khaUPv0eAtmf7qyvj6knkzIj3TCvmuXMUvvvsLLFqZTYhq3uOVZfUtOF5PAiULyE1KnXtyjHErMkRLFKrpnFzdTfo70L+fwbuQgQ0TR7cuC1VuwXtoxyE6PGsBxc1wBTnoTqPqIqPl7g6EXUWgZ/SekR6WakSAJJP96BUGxxLU4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159113; c=relaxed/simple; bh=nMCvD9FhHWv6QXJohgSpbLwo660AjijJtxk2b8JgbNs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=F3g7kMh+WWFYI7gtdM8rCYZR3CsnoTgt5SgDAyYnVdETdyxoPl2mVgbu2JW0597ko9AOt/kqBeQH7PYP8FoV3TFu8HGejRGRE00f1/Zflz+sUxbS/Nk8C86UCL8TU6tqQk3Z7rgu4l+WWnrmjfEGqctjqnQ4XOr9K+us/dg0nNA= 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=Z/BEwuDT; 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="Z/BEwuDT" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-124ac76ea5bso1653951c88.0 for ; Tue, 03 Feb 2026 14:51:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770159111; x=1770763911; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=LBr6QtiTmPDnDtdThT9x1EHn8qfDN4a5mvSafr0ZxaM=; b=Z/BEwuDTBHurfLXQQL8lkHFoPTVyHkK/ksWU+BHWDxbOL2Z0sa1sVG4GVwnuufw8DN 9KNFyeZiE4MerUm0iRdXIAHgQeIIPwSR5G5759KFkGy7EezmGT+aXKjBLdQ6EkEMCfzM layXprS7p/5plsvzFFQajzR47pnZt/XbpcuM/6BwXTdzVnQ0SXwuaM1x/C2hHErXf/Ma +z9Ogl0aEu8MX2IoWBC5Lk5Z289cXnnjZUv2pYbq/qAJoTbXL9FAnOUQN8otGi659LDM S8ZWo3vAfvd+k4sqAuMWW5Jy59I5hRdCx56Nc/4nZ0hDtuCRI8USxItNFIhSHaB0p00l 8TSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770159111; x=1770763911; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LBr6QtiTmPDnDtdThT9x1EHn8qfDN4a5mvSafr0ZxaM=; b=FWME6UyTGtfV+fD/AoVKphI5oQBYosvNKcKndYRsjfFTU4/93iU8mnf8nmJq54VNxZ Fyp1rCUivEyzSHzJ7Ukk55zL9RTIsX/7K5dRn6a8OFBASE8hhv+VoZdVjgD1DhmXgG15 F6IanT4xChpzNtAd/2qcuistinTJITNq1LWPHkgR7EWsbaZH+lLdIanLLzCAPlP7OUWr 5OSSiHcEs/00OeVK+iDtvXN5/LgKR+qCVU4qBBK6nnZVRWA+J7m+fDjKeJDQQURQLP9X EuRXfz4k/CRQWlnH0Dj2AUhJKb2jouoiKOO0k68ZOkgjtnirqDNPFU6LI7VUSlBjlmkT zlmg== X-Forwarded-Encrypted: i=1; AJvYcCW7FYnnENsWmdsFyUXgJ/nv/s/HDsyGVek2d35z/dZhmIW0gYA5gkRiA6nLVitVhjACEqvmm2HlEFPwf2I=@vger.kernel.org X-Gm-Message-State: AOJu0YzQLjHE9hVSj4RcrY/v1co8T6DX0OL2d6Tqu1pLuLOGG+GLjOad GfCF3S11Zdz30I1MY/EoxgRwPvh/p1/1MVnndDLIeU01N/VYISxjVnWWWWiT85ntWEVhgCStrYR 1bLptPctmVg== X-Received: from dlzz28.prod.google.com ([2002:a05:7022:49c:b0:124:9694:5535]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:10d:b0:11b:88a7:e1b0 with SMTP id a92af1059eb24-126f47bd1e8mr462228c88.26.1770159110756; Tue, 03 Feb 2026 14:51:50 -0800 (PST) Date: Tue, 3 Feb 2026 14:51:28 -0800 In-Reply-To: <20260203225129.4077140-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: <20260203225129.4077140-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203225129.4077140-6-irogers@google.com> Subject: [PATCH v7 5/6] perf evlist: Reduce affinity use and move into iterator, fix no affinity From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi , Andres Freund 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 Sun Feb 8 07:07:27 2026 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.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 A3B0037F75C for ; Tue, 3 Feb 2026 22:51:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159115; cv=none; b=VI44ivggZ9D6Ibf+OgwthqZ+upJWwL5xzeAp3OGKgyY0tZ+ZIjEZD9P9eW8dusm1xT9aJe80dmdAJRrPjb8b9mA5Bave3qyhknx/1C25INZO/8eHIkfwaikDpwh0QhlzQqCiZdjrNnzjm09LeDZBYn8qDdDmK+g7SwgNNO+mT3I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770159115; c=relaxed/simple; bh=4dzqlAY6Jwfn5UZRMxqibkJ/WzReutE/CulfgusKL0g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=nrl27Eiz3Hboq5j9Lt+iOsrWCR1EkqKR2IDXUbG+EOjwxifsXmnnYtOgx9XX4ranIgnv3HvC6QIxK7Ky/Ir5xNU6Hut/6A2o7eHqplCmp47jpldHuD08LpJdMksw/+7MUKk/8p27wi65BiBFONfMTNx5YotkVXlIwW9+JOI+mT4= 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=sj8H1v7R; arc=none smtp.client-ip=209.85.210.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="sj8H1v7R" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-81f53036ac9so118169b3a.3 for ; Tue, 03 Feb 2026 14:51:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770159113; x=1770763913; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=wNGV+9W9psENt274mz6PMhj6c8c5MewbEM3NGZmHhlM=; b=sj8H1v7RTkZ2CjP69ZBd+bKMeopp7+up9Fz+sQELAW4vZIjYMEB92bgCSfe9q3+HLW 2iis+PSQe3jhdpPkz09dm91gJW8PFEW/aa/o0va1vv9I/wiyr2HATuhtdH1P8Xe+EAHG nqn5p+PDmC1QNzidWeQjfjc6JBGkt6AXVRkVsMIUFyn8Gnv9JNhJCzSF9W2yErpOQYLk 3S8zgJSLPo2Q5TeHheg2mPAtn10D1Xm+vqFfnGqOm5qSIH+DvAh1tZWkkjJv2MUd1rTr yAcSvLA3KTE3CD3qUqaTdbfBtN4783iwcx4XSzlJ9pcXMhQubKN/2dnQC6nOZnCxQn51 5ZLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770159113; x=1770763913; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wNGV+9W9psENt274mz6PMhj6c8c5MewbEM3NGZmHhlM=; b=dY1WU+AIfcxnV6H/Q2w4fcRZWXZkTmRWY0/ieR9+BcYK/j0sTHplDIhApr6EfRLigK R5/d+47UEzLy4+O4HX0rldS0qz4/xxOPrECbMkwPWWjVZ+6qQ4mS80WcS5axz0tvkDjG MkqYgf3WMaNeS7laDDVd/Jr4Jbcsy+jMhsqLAnxlYbGJGS1s30tBSKGWGzPn84NPe+0+ hm3UZh1ehUV9B6Op3RHDPTOCVY8WJ99/7PyB+KkHRBHDs1Ld/5IbiCnHE1Rxq6noDIMk pBubAd8HsH3UbqKoOzVrJfwbD6XUA2yullhUIU4UyPcL2B1zv7Uh0k1qDPT3Jxt+y3iG hjEA== X-Forwarded-Encrypted: i=1; AJvYcCVtILMqQGhcnbj7YbMr6zrG8at3+h68MpgRKP1zQeTjTUa41cLEQKRndkc505yVhk33IjnWdKBltrPHW1M=@vger.kernel.org X-Gm-Message-State: AOJu0YzvGAdVLAgKOcDtS5G+kvfye9S708Cv4fFE8NrAxpR/dlEu3Yl0 Q/LJp8DvinPCk4A4BkVnzHgsn4St2CEaxs70BLgfgGxqZXpZ8oR1YNCUt5BEpFm/+h8fSWEi8L8 Zt9lYmdJxnA== X-Received: from pfjg11.prod.google.com ([2002:a05:6a00:b8b:b0:81f:7db9:83d5]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1709:b0:81c:5694:c544 with SMTP id d2e1a72fcca58-8241c637192mr908753b3a.56.1770159112816; Tue, 03 Feb 2026 14:51:52 -0800 (PST) Date: Tue, 3 Feb 2026 14:51:29 -0800 In-Reply-To: <20260203225129.4077140-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: <20260203225129.4077140-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203225129.4077140-7-irogers@google.com> Subject: [PATCH v7 6/6] perf stat: Add no-affinity flag From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi , Andres Freund 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