From nobody Sun Feb 8 18:48:25 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 817E02DD60F for ; Thu, 6 Nov 2025 07:12:48 +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=1762413169; cv=none; b=p8mjOgEqJPIKBH7RcgltdtTWqlvHlLFd5I+KB0li/oNBX+GNpc0ihbmgCwJjeEB7tpJ4q0T2kHm3+VF5WBGy6A9WUwf7NO7Q0qYPfHqYtsA2a5yGA7wcFZSTgV54UXLntiWit/u3mLZRgkBx1xCJ5tzkmJptiGisC7PRrLMpOVI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413169; c=relaxed/simple; bh=0G/j/xJj1qsweoCKMUXKGFzeFo7TvQZ/7fH1qwVBjpI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=XYXvXiQQTnlaTpq7P6ELlvpATDWGLJap+RebkdzVaLDRsElDb+OkpFl7bjjkq76EjIFpZHe6b6SLv+Xqo6lj2SB51P4giMKbVu0KZXknRHOWzBxczmXd4xX4rHJL2ezwRrW8xbWzg+PkpBH57ZVJx/or/F5PIVw17oK3VvNPGik= 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=Tm1g0zS3; 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="Tm1g0zS3" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-77f610f7325so641887b3a.1 for ; Wed, 05 Nov 2025 23:12:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413168; x=1763017968; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=BwL0flbR67e6mq7ibhkhVdiS0tjPyP1QzI5zBDpL9cA=; b=Tm1g0zS3kyL9KV4nrXb9qiUakT+Exbff+YXf6KWQMCKxHDu3nzVQwt3CVW5U8ux7EQ PlQM9nfZaR7Ljrga0Dj0fC/Y6ISV5HOkjJKrvsuc+etoBT2g4g7c/SvfJKrP5/fDOnJ6 7DR69nguqOtWzF3LxLDvFBOMUX7TKFg20zt3aRVrp0hd3Ar9soP58FPVqj+urRYdnPxQ 1oszwmJzKg+KS7NCLlap4niMQZf4QM9LjRD/UUrlfW+AJKzUX0STfO1P649Z5y5WMGJm T8+MS7Dv1RpV5QRCalZjReNxNYsrD+yZnTs/72cplJG/qYdxq8oDT4AnzWW/Z3jUZ/7Z Orew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413168; x=1763017968; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=BwL0flbR67e6mq7ibhkhVdiS0tjPyP1QzI5zBDpL9cA=; b=guiMgX5ZTTCJJXC1AGDfeCAFmwRzZMx+j2A4ItUr8oHTqEE1yrqQwwm7F2GQ+8xE0K oUVlag4q64UPVXCBIuRyWdq0tbhR9PiqKzEozVsRxy5JbOmWhu6t9q0phRAWiXikYIYQ TFKLG7xIahcvHUzI2uVxGJaBq4y04cdJbJTZZ4Z5Q4Hvmi2riuPEyjL1F9gtuYp5LpmR EFHstL8q5G7+puG8ynxNjDDP2G9FIoyAqKjMPGAFtSUkbKmcH/F661hzSOMc17DY+U4w Mvt+o/+t+f4r+AhuCDlolrWfftorRdUydjXS6uOO0joZWetnUN0RIfbjCjL25oyhPFDb DAww== X-Forwarded-Encrypted: i=1; AJvYcCXVmmdwWtT6jOxrFluFKZhOBc3EoEV5RHcnWX8LaRpkYBZOP5KqK6gH8kcQ+mTx9yIdKE8AhPuR5XbmYuQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyEG9eg7oMnVUO2RQkJXm9V+tkMmx4+NyU4fP6YpcuraKPRexpo KVYb4D2UtnUyucnF1a7SNzDFhGa7+FkTV/hGJyoZGom7xt6ajpx6l629qh5T4ityOeE/NrLYIy8 6RmvVJudlog== X-Google-Smtp-Source: AGHT+IHBw9KDApkRxNKNSSYbt0DxZex8yR8CkX8/EVYPoFywpOURlzyyxkxht7ZP44EnoM+9po/KDk//aDb0 X-Received: from dlbrl28.prod.google.com ([2002:a05:7022:f51c:b0:119:78ff:fe15]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:5491:b0:340:cc06:94ee with SMTP id adf61e73a8af0-34f86e13de7mr7541851637.60.1762413167626; Wed, 05 Nov 2025 23:12:47 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:32 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-2-irogers@google.com> Subject: [PATCH v3 1/9] libperf cpumap: Reduce allocations and sorting in intersect From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On hybrid platforms the CPU maps are often disjoint. Rather than copy CPUs and trim, compute the number of common CPUs, if none early exit, otherwise copy in an sorted order. This avoids memory allocation in the disjoint case and avoids a second malloc and useless sort in the previous trim cases. Signed-off-by: Ian Rogers --- tools/lib/perf/cpumap.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index b20a5280f2b3..7e88417ba84d 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -453,21 +453,33 @@ int perf_cpu_map__merge(struct perf_cpu_map **orig, s= truct perf_cpu_map *other) struct perf_cpu_map *perf_cpu_map__intersect(struct perf_cpu_map *orig, struct perf_cpu_map *other) { - struct perf_cpu *tmp_cpus; - int tmp_len; int i, j, k; - struct perf_cpu_map *merged =3D NULL; + struct perf_cpu_map *merged; =20 if (perf_cpu_map__is_subset(other, orig)) return perf_cpu_map__get(orig); if (perf_cpu_map__is_subset(orig, other)) return perf_cpu_map__get(other); =20 - tmp_len =3D max(__perf_cpu_map__nr(orig), __perf_cpu_map__nr(other)); - tmp_cpus =3D malloc(tmp_len * sizeof(struct perf_cpu)); - if (!tmp_cpus) + i =3D j =3D k =3D 0; + while (i < __perf_cpu_map__nr(orig) && j < __perf_cpu_map__nr(other)) { + if (__perf_cpu_map__cpu(orig, i).cpu < __perf_cpu_map__cpu(other, j).cpu) + i++; + else if (__perf_cpu_map__cpu(orig, i).cpu > __perf_cpu_map__cpu(other, j= ).cpu) + j++; + else { /* CPUs match. */ + i++; + j++; + k++; + } + } + if (k =3D=3D 0) /* Maps are completely disjoint. */ return NULL; =20 + merged =3D perf_cpu_map__alloc(k); + if (!merged) + return NULL; + /* Entries are added to merged in sorted order, so no need to sort again.= */ i =3D j =3D k =3D 0; while (i < __perf_cpu_map__nr(orig) && j < __perf_cpu_map__nr(other)) { if (__perf_cpu_map__cpu(orig, i).cpu < __perf_cpu_map__cpu(other, j).cpu) @@ -476,11 +488,8 @@ struct perf_cpu_map *perf_cpu_map__intersect(struct pe= rf_cpu_map *orig, j++; else { j++; - tmp_cpus[k++] =3D __perf_cpu_map__cpu(orig, i++); + RC_CHK_ACCESS(merged)->map[k++] =3D __perf_cpu_map__cpu(orig, i++); } } - if (k) - merged =3D cpu_map__trim_new(k, tmp_cpus); - free(tmp_cpus); return merged; } --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4604D2DECA5 for ; Thu, 6 Nov 2025 07:12:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413171; cv=none; b=YkpjOkhPXZzFkuLCPYChgCeRwncGvxr1u0cnWANb9o2kI5qD7eHwgj3+glR9T9JIw3SKfs2JEPivK/nHA7kI6zfCu89cej9sEXvKv43u+sFT4MW3oPaxhIRgbBlDrOnQ1XllkInx7TH2FY9MfAaq2sTXL/2ZVT+OihGLgwBZKec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413171; c=relaxed/simple; bh=Kgo7sxJNHAVdmzHf5VuG0p/PQfK1697phqEp6Xwcyo0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=Iu2h/SoBj+OIBDM3hU+fuTpQx21fTeOEoY3wyuKlGf2VbD4MncFwkMYI9IP9UsAXQVKvcs0v12yuAle0ZSijkbWK1ogIPzwTeTDNc68XCI95V7U52EDYVSX12ALF0JfzxfRMOM5gsJImAv8Jxk9egmd4GyWvB5dYJOmjmaP3FFs= 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=ptANHQsC; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ptANHQsC" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b9d73d57328so536942a12.1 for ; Wed, 05 Nov 2025 23:12:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413170; x=1763017970; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=PLwg+2AiO3F/YfbdpvnrnBijRms/bsxixJsYS/jBPB8=; b=ptANHQsCJRj/jgug1THZeW2g5XWFMtlnRgFv1fK1HWaSA+dd5jNA4i+bmcj7R79vko J8/GsCE7Elviy/ORDu0EPeNLnd8bTFyaiBba6QdeTEcVu2zpNlLDE427ee5iRVofFz1C AJThg1qfv0RAmXRlt2E3ONZgsat02ip63ovsIrndNviZZRyAm+n4A/nWZMSXuH7vCR6S sEYBB3LC6BFpyz5hadRSIXIAkCzId0lboHYazscTUoZan1ri2USfaId1+ia0aj50JHWC Yrm0GwFL9LRYEvKyXhUIUve+/koAIsuaHLWbGgITfJOOjHcOefqeujuscK4a/aIZQlF/ Hn1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413170; x=1763017970; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PLwg+2AiO3F/YfbdpvnrnBijRms/bsxixJsYS/jBPB8=; b=q24tpYTsdt16Tq+Xw9a0eVK8flW36Y3U0R+734WsTPZUMiOOKaJfuSZ+IklgRhzbVr UcS5SGLBwTpv7A+TYhFHJq/Lo5rAqg3zTLVGGp8yn/bFJulijRM9S2n6Majksxr1kG47 ws4wMCS+yuAeU6SGoQPm9iI5nVE0l65kPJv2xDvmqVsGu4VYwB4RHs69PERpgJnWFvKI bZjTuvQSJ/DqxP5yjYB+0H+wdzvF0fvfpflENRrqi+xC/ezYC9OwpxZgfqnJNn0I+VvB DPRY/ZnxYQUammzqDFYOWG3y6VAtodi+o9hXj75Mj8fLtPJgvS9XOO4G98BuaQ5EHU4U jWcg== X-Forwarded-Encrypted: i=1; AJvYcCXtVhpkWjmUTl5W3rQ6GbrJI/WmRd8kK7FmVrjmKWlVguWSJWXVgJH7o/4+uUb3g9YZPoa3uKkBgVeRRSw=@vger.kernel.org X-Gm-Message-State: AOJu0YwrFbnAN+Uzg98b3XYbzxd6malxKJIhTNVl2nGMwk7na43VH9eI QmOzc6Y0gRY/AbpiJNNr6uebmfNvdZNVC/1BCsDFGYl+mStafEZXyQUyimfKJ1BaioTz7NVkPDa AfPaWhnhm5w== X-Google-Smtp-Source: AGHT+IE0YX5vsYPKWDEQJBgQGJdnX5svKCKT5iKNi+LiQBs+q034F7/hs6Iv6PwLztjF2Ff/O7meufnROYpz X-Received: from dlbsv11.prod.google.com ([2002:a05:7022:3a0b:b0:119:49ca:6b9f]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:12c3:b0:2fb:2e04:eeae with SMTP id adf61e73a8af0-34f83d0f7d1mr7648612637.21.1762413169496; Wed, 05 Nov 2025 23:12:49 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:33 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-3-irogers@google.com> Subject: [PATCH v3 2/9] perf pmu: perf_cpu_map__new_int to avoid parsing a string From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Prefer perf_cpu_map__new_int(0) to perf_cpu_map__new("0") as it avoids strings parsing. Signed-off-by: Ian Rogers --- tools/perf/util/drm_pmu.c | 2 +- tools/perf/util/hwmon_pmu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/drm_pmu.c b/tools/perf/util/drm_pmu.c index 98d4d2b556d4..fc864bde4cb2 100644 --- a/tools/perf/util/drm_pmu.c +++ b/tools/perf/util/drm_pmu.c @@ -119,7 +119,7 @@ static struct drm_pmu *add_drm_pmu(struct list_head *pm= us, char *line, size_t li return NULL; } =20 - drm->pmu.cpus =3D perf_cpu_map__new("0"); + drm->pmu.cpus =3D perf_cpu_map__new_int(0); if (!drm->pmu.cpus) { perf_pmu__delete(&drm->pmu); return NULL; diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c index 5c27256a220a..279d6b1a47f0 100644 --- a/tools/perf/util/hwmon_pmu.c +++ b/tools/perf/util/hwmon_pmu.c @@ -376,7 +376,7 @@ struct perf_pmu *hwmon_pmu__new(struct list_head *pmus,= const char *hwmon_dir, perf_pmu__delete(&hwm->pmu); return NULL; } - hwm->pmu.cpus =3D perf_cpu_map__new("0"); + hwm->pmu.cpus =3D perf_cpu_map__new_int(0); if (!hwm->pmu.cpus) { perf_pmu__delete(&hwm->pmu); return NULL; --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 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 D3B7D2E03E4 for ; Thu, 6 Nov 2025 07:12:51 +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=1762413173; cv=none; b=ZKuetA/mFv2JRuOpdljMdNmtQgfkphEGNM4bg0xCIx5OlDjz8vItIbfJgdXQBs/oBZKZk6FlEYPr5ujY02QQ7eqE4QEN5wFt3i812ph6CQk3m6/30C6H6fyiZAgew65v07wG+lc9RL8CZk+MYJ+9gIQBb1u/dnUvPKTPmcSatTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413173; c=relaxed/simple; bh=LNyMR/FxzeM/nBYJ1n7Go6LoKgm+Jmbzge6v2T7XY8M=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=fe24csulSmE9Vpgf4ENLki/4bT4sZxA3SniGYA7uiUqNYrbIGhuC78knxzXlPNhx0ynSsDj8lTf33veTo5lQXfl3/JjJBylGwSkGdGRHEDwtMbVIx6hILAHnDmOQ0S9NsuNuM6GrYMmOhLhgTZ3QCf877HPvHX6BZ/CUs5FVsxQ= 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=g563hXW2; 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="g563hXW2" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-782063922ceso217311b3a.0 for ; Wed, 05 Nov 2025 23:12:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413171; x=1763017971; 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=e+Pdd5axpxJgS59kogXuDTxSRBSKUwiMlRaE/rJ5GNI=; b=g563hXW2VU3eiWiSWB+PNbhQA6k4KPCd3uKyfIPgPI7mSfsWlQq1Aw9FoT6olqRMlV GhiZX45hOVC0bhuDr0sV668ATE35iwn6k7+maiTdh0dBqSPV8EBNcF0Zl7REeCtn/m0q l28bzOYNHxcXg4l/lZG8GjvKPbOj3Q5kgly5x4n2r6hOjIOz9Sdbt/eV4BGt7lKHkJP/ 20pitox59WvDHZUlYXdQ7Ah8H6WCemyi3dgutcl2hfvz2SjEY/nLPRCSIY+j59EwBPMS 1O1B57Xts3urxrztU+xusW8P/IQ0SXVQFt0/EE8+swgHH6dCmgVODLSXFB9m6csxDGls oXnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413171; x=1763017971; 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=e+Pdd5axpxJgS59kogXuDTxSRBSKUwiMlRaE/rJ5GNI=; b=iNu1IaTw272nw/gkeD6Ojh2Ps/SKFVmZOmAogzZU0BJUC38iz4BZY3Q+FWZaCBTltf 23VdFu/HPDBaJ5Ex/tOoEyXa6DkkeHPMFF6Jnbr/YyqAz5UFsFgP1CnlG92Dw/UIsbxW wo8uAe7bEDlJyT1p6F0IB3X8+8Nbg4ZsXh5KCZamz/UvIDxcvSVNGMMK/i5RYXYo49Fx rmhVTG+zdmTXH3Ie1gPrNcePdG5EBdlgetI29VcWFtvFkaZ0We0ZIVXc8XDwnKjLcEme GmLKvEj1yLlvn0Y3CC/dE/h/lffVL099XO4Mk73SbIIHEsD+kXYCcDTO5SecEILM0sqx oUTA== X-Forwarded-Encrypted: i=1; AJvYcCVqnjV4iVh3Ax3Li7dyqsFESalBxSRygMWFJv6yZ4/lViCcjydzcY7iKa3DN+f1YuGNd3qwtWsAFv+zunY=@vger.kernel.org X-Gm-Message-State: AOJu0YytQ0SUxyz+k1hHQb4s2nf741p+QgtY2pRVGL2Usxyvngl9JCnS cUy6+FouasXiUwivxnSFLIsfLOuLVQtK1gHswS985F8UMgcX7H0sEScHhFyxUgOnkrmJY2BPOlh 8mSZAsdsoBA== X-Google-Smtp-Source: AGHT+IHDBJfzNDXDcNCXyM0+krjWpqxKuX9/kAV9YiS3jz8dK8m2B7xctOqy+nX3koRLFJMTdGGi4sFyE9Pf X-Received: from dlbrs16.prod.google.com ([2002:a05:7022:f690:b0:119:49ca:6baf]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:2589:b0:34f:2341:cbc6 with SMTP id adf61e73a8af0-34f86409639mr8958653637.52.1762413171178; Wed, 05 Nov 2025 23:12:51 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:34 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-4-irogers@google.com> Subject: [PATCH v3 3/9] perf tool_pmu: Use old_count when computing count values for time events From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When running in interval mode every third count of a time event isn't showing properly: ``` $ perf stat -e duration_time -a -I 1000 1.001082862 1,002,290,425 duration_time 2.004264262 1,003,183,516 duration_time 3.007381401 duration_time 4.011160141 1,003,705,631 duration_time 5.014515385 1,003,290,110 duration_time 6.018539680 duration_time 7.022065321 1,003,591,720 duration_time ``` The regression came in with a different fix, found through bisection, commit 68cb1567439f ("perf tool_pmu: Fix aggregation on duration_time"). The issue is caused by the enabled and running time of the event matching the old_count's and creating a delta of 0, which is indicative of an error. Fixes: 68cb1567439f ("perf tool_pmu: Fix aggregation on duration_time") Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 16 +++++++++-- tools/perf/util/tool_pmu.c | 59 +++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 886727ae8529..d89fa9468f89 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -282,17 +282,27 @@ static int read_single_counter(struct evsel *counter,= int cpu_map_idx, int threa if (err && cpu_map_idx =3D=3D 0 && (evsel__tool_event(counter) =3D=3D TOOL_PMU__EVENT_USER_TIME || evsel__tool_event(counter) =3D=3D TOOL_PMU__EVENT_SYSTEM_TIME)) { - u64 val, *start_time; struct perf_counts_values *count =3D perf_counts(counter->counts, cpu_map_idx, thread); + struct perf_counts_values *old_count =3D NULL; + u64 val; + + if (counter->prev_raw_counts) + old_count =3D perf_counts(counter->prev_raw_counts, cpu_map_idx, thread= ); =20 - start_time =3D xyarray__entry(counter->start_times, cpu_map_idx, thread); if (evsel__tool_event(counter) =3D=3D TOOL_PMU__EVENT_USER_TIME) val =3D ru_stats.ru_utime_usec_stat.mean; else val =3D ru_stats.ru_stime_usec_stat.mean; - count->ena =3D count->run =3D *start_time + val; + count->val =3D val; + if (old_count) { + count->run =3D old_count->run + 1; + count->ena =3D old_count->ena + 1; + } else { + count->run++; + count->ena++; + } return 0; } return err; diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index f075098488ba..b895e88ff740 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -431,16 +431,39 @@ bool tool_pmu__read_event(enum tool_pmu_event ev, str= uct evsel *evsel, u64 *resu } } =20 +static void perf_counts__update(struct perf_counts_values *count, + const struct perf_counts_values *old_count, + bool raw, u64 val) +{ + /* + * The values of enabled and running must make a ratio of 100%. The + * exact values don't matter as long as they are non-zero to avoid + * issues with evsel__count_has_error. + */ + if (old_count) { + count->val =3D raw ? val : old_count->val + val; + count->run =3D old_count->run + 1; + count->ena =3D old_count->ena + 1; + count->lost =3D old_count->lost; + } else { + count->val =3D val; + count->run++; + count->ena++; + count->lost =3D 0; + } +} + int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread) { __u64 *start_time, cur_time, delta_start; - u64 val; - int fd, err =3D 0; + int err =3D 0; struct perf_counts_values *count, *old_count =3D NULL; bool adjust =3D false; enum tool_pmu_event ev =3D evsel__tool_event(evsel); =20 count =3D perf_counts(evsel->counts, cpu_map_idx, thread); + if (evsel->prev_raw_counts) + old_count =3D perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); =20 switch (ev) { case TOOL_PMU__EVENT_HAS_PMEM: @@ -451,26 +474,18 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu= _map_idx, int thread) case TOOL_PMU__EVENT_NUM_PACKAGES: case TOOL_PMU__EVENT_SLOTS: case TOOL_PMU__EVENT_SMT_ON: - case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: - if (evsel->prev_raw_counts) - old_count =3D perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); - val =3D 0; + case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: { + u64 val =3D 0; + if (cpu_map_idx =3D=3D 0 && thread =3D=3D 0) { if (!tool_pmu__read_event(ev, evsel, &val)) { count->lost++; val =3D 0; } } - if (old_count) { - count->val =3D old_count->val + val; - count->run =3D old_count->run + 1; - count->ena =3D old_count->ena + 1; - } else { - count->val =3D val; - count->run++; - count->ena++; - } + perf_counts__update(count, old_count, /*raw=3D*/false, val); return 0; + } case TOOL_PMU__EVENT_DURATION_TIME: /* * Pretend duration_time is only on the first CPU and thread, or @@ -486,9 +501,9 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_m= ap_idx, int thread) case TOOL_PMU__EVENT_USER_TIME: case TOOL_PMU__EVENT_SYSTEM_TIME: { bool system =3D evsel__tool_event(evsel) =3D=3D TOOL_PMU__EVENT_SYSTEM_T= IME; + int fd =3D FD(evsel, cpu_map_idx, thread); =20 start_time =3D xyarray__entry(evsel->start_times, cpu_map_idx, thread); - fd =3D FD(evsel, cpu_map_idx, thread); lseek(fd, SEEK_SET, 0); if (evsel->pid_stat) { /* The event exists solely on 1 CPU. */ @@ -522,17 +537,9 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_= map_idx, int thread) if (adjust) { __u64 ticks_per_sec =3D sysconf(_SC_CLK_TCK); =20 - delta_start *=3D 1000000000 / ticks_per_sec; + delta_start *=3D 1e9 / ticks_per_sec; } - count->val =3D delta_start; - count->lost =3D 0; - /* - * The values of enabled and running must make a ratio of 100%. The - * exact values don't matter as long as they are non-zero to avoid - * issues with evsel__count_has_error. - */ - count->ena++; - count->run++; + perf_counts__update(count, old_count, /*raw=3D*/true, delta_start); return 0; } =20 --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD0E72E543E for ; Thu, 6 Nov 2025 07:12:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413175; cv=none; b=UxQe3AwkOfEUbVQaHQhU5iEZZiGohz5cTetdE3me+Q/0dvt6EcqC2p2omonn430xde85ITh70WrjbM9g9LyqBK71mzb/8dAKzPDj5hVcb17Z/NQ1yVhSgDTy3lb3cX2C2THLwG6UdiE2RCYV3AkNo12U1Nm+SrFsuniQ8r+5G5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413175; c=relaxed/simple; bh=EC/tZ9Xdy5myRRq+PdXPCKA/bbIvt50N1agXEhWd7Rg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=i5hSDHMXTFZokm7Y3K8ep2VQoBcuOarwiBr7/YLzau5z3sCR/lbAlIuYLQAkMbEE02GnCr214mWcmG/TjVRgVL5WjgU9s1b14yHlnec8TvvGqsB5kKvlg1XWjXJDo+82I6SVt/DrK6jP3Iaqnhrt1cIGYqCewxXtNcumzSrwSWM= 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=tg5T3ARd; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="tg5T3ARd" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b6ce1b57b9cso645733a12.1 for ; Wed, 05 Nov 2025 23:12:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413173; x=1763017973; 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=A4ZNYhXXjGnRVVF3I/Hjm5vaAXPO71/s9Kf71lIm9nQ=; b=tg5T3ARdGqbsgOew2K+s222ZCz7ckEai9nG75XNpK0yYq2f4L5m9IaYJyF7kJpcG5g 9KUJodYzUCSwNNDnBKgbYyJZm8RXO8iBqEEbc7YnaKp6ab5/JkjImngcLLkKNIXguVAc u4lPMP2Yam/vUCdtIrkkLKRhF2KaBKSbmcbjYe1naSBweHlFWWTYOBmhm3/tA6ztf/9v Qi4Xf5Yz9xcvkMkIWhedHV3dEcX7kyqSuCFexChbHdLx8AbhAFxmhp5X/tVteVVn4j1d u9It7uQhZbctr3z/mAPsnCRXl5oR9FtwjjUK9mhKKon9A4UUdpSRL9xV9r7hmrnb9lmI dFBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413173; x=1763017973; 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=A4ZNYhXXjGnRVVF3I/Hjm5vaAXPO71/s9Kf71lIm9nQ=; b=eX62Dwjju6BtkW0tg8N8aNFaumfOl+bWNt07bZg9wk8AWGF8mIYX6fu+zWSOP7zdFD m1cwfyBdCxGkroeBlWU2uJL+sbFbtasXpeSSnx+bmqACPSMLtnnXjpbHI56ndY53P8Ov nSbgcUv1uwyjBEX9z1X19ku34gwcPBetdq+CcRjKh5411Rr+ClFuw5rcyFnxrlptBGff yV+QYqIB81/h3OQeB0tRg2WF6ZfSyIF/ySg3cl/2MOwMWXIxBLQwxR9fqjKrDRY67nrR BHJFyhL0eLiWfcLlkE/oNG2bDQg+cQnl2boXgLXFzu8RLjXwWjcvMwNxxggw45/R0vZv aXpA== X-Forwarded-Encrypted: i=1; AJvYcCWrV9xPEqqvB1GtCxhOBTGSq5Te7KW68vMAmFT5kPwM2LLfNyCFAFUuNG8BUIYyTA71aNVphwYm69lmjhE=@vger.kernel.org X-Gm-Message-State: AOJu0YyIk3LrKZk1NfdNKuAZOyYpQecq2/xwlX+Zgu6RQ2X8JIE6C0ZU eAFbDkY4sKLmo6dMfp4YKD51xvt98b3LVD1C8kodr6paenbFQ7hX30xt+w3dAPJGpzZ6OU0Nrzx hnnyND+z8mg== X-Google-Smtp-Source: AGHT+IHGU1zIshvyY+car8C198znETVpyz+J4B/MEF/IzHG6Vp7onwTJYM5tT/KUFm8oCtJPiJO3W6kuDROM X-Received: from dlbut3.prod.google.com ([2002:a05:7022:7e03:b0:119:49ca:6ba5]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:4305:b0:344:bf35:2bfa with SMTP id adf61e73a8af0-34f8561d759mr8426190637.33.1762413173091; Wed, 05 Nov 2025 23:12:53 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:35 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-5-irogers@google.com> Subject: [PATCH v3 4/9] perf stat-shadow: Read tool events directly From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When reading time values for metrics don't use the globals updated in builtin-stat, just read the events as regular events. The only exception is for time events where nanoseconds need converting to seconds as metrics assume time metrics are in seconds. Signed-off-by: Ian Rogers --- tools/perf/util/stat-shadow.c | 147 +++++++++++++++------------------- 1 file changed, 66 insertions(+), 81 deletions(-) diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index abaf6b579bfc..939ac3269a44 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -371,7 +371,32 @@ static void print_nsecs(struct perf_stat_config *confi= g, } } =20 -static int prepare_metric(const struct metric_expr *mexp, +static bool tool_pmu__is_time_event(const struct perf_stat_config *config, + const struct evsel *evsel, int *tool_aggr_idx) +{ + enum tool_pmu_event event =3D evsel__tool_event(evsel); + int aggr_idx; + + if (event !=3D TOOL_PMU__EVENT_DURATION_TIME && + event !=3D TOOL_PMU__EVENT_USER_TIME && + event !=3D TOOL_PMU__EVENT_SYSTEM_TIME) + return false; + + if (config) { + cpu_aggr_map__for_each_idx(aggr_idx, config->aggr_map) { + if (config->aggr_map->map[aggr_idx].cpu.cpu =3D=3D 0) { + *tool_aggr_idx =3D aggr_idx; + return true; + } + } + pr_debug("Unexpected CPU0 missing in aggregation for tool event.\n"); + } + *tool_aggr_idx =3D 0; /* Assume the first aggregation index works. */ + return true; +} + +static int prepare_metric(const struct perf_stat_config *config, + const struct metric_expr *mexp, const struct evsel *evsel, struct expr_parse_ctx *pctx, int aggr_idx) @@ -381,91 +406,51 @@ static int prepare_metric(const struct metric_expr *m= exp, int i; =20 for (i =3D 0; metric_events[i]; i++) { + int source_count =3D 0, tool_aggr_idx; + bool is_tool_time =3D + tool_pmu__is_time_event(config, metric_events[i], &tool_aggr_idx); + struct perf_stat_evsel *ps =3D metric_events[i]->stats; + struct perf_stat_aggr *aggr; char *n; double val; - int source_count =3D 0; =20 - if (evsel__is_tool(metric_events[i])) { - struct stats *stats; - double scale; - - switch (evsel__tool_event(metric_events[i])) { - case TOOL_PMU__EVENT_DURATION_TIME: - stats =3D &walltime_nsecs_stats; - scale =3D 1e-9; - break; - case TOOL_PMU__EVENT_USER_TIME: - stats =3D &ru_stats.ru_utime_usec_stat; - scale =3D 1e-6; - break; - case TOOL_PMU__EVENT_SYSTEM_TIME: - stats =3D &ru_stats.ru_stime_usec_stat; - scale =3D 1e-6; + /* + * If there are multiple uncore PMUs and we're not reading the + * leader's stats, determine the stats for the appropriate + * uncore PMU. + */ + if (evsel && evsel->metric_leader && + evsel->pmu !=3D evsel->metric_leader->pmu && + mexp->metric_events[i]->pmu =3D=3D evsel->metric_leader->pmu) { + struct evsel *pos; + + evlist__for_each_entry(evsel->evlist, pos) { + if (pos->pmu !=3D evsel->pmu) + continue; + if (pos->metric_leader !=3D mexp->metric_events[i]) + continue; + ps =3D pos->stats; + source_count =3D 1; break; - case TOOL_PMU__EVENT_NONE: - pr_err("Invalid tool event 'none'"); - abort(); - case TOOL_PMU__EVENT_MAX: - pr_err("Invalid tool event 'max'"); - abort(); - case TOOL_PMU__EVENT_HAS_PMEM: - case TOOL_PMU__EVENT_NUM_CORES: - case TOOL_PMU__EVENT_NUM_CPUS: - case TOOL_PMU__EVENT_NUM_CPUS_ONLINE: - case TOOL_PMU__EVENT_NUM_DIES: - case TOOL_PMU__EVENT_NUM_PACKAGES: - case TOOL_PMU__EVENT_SLOTS: - case TOOL_PMU__EVENT_SMT_ON: - case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: - default: - pr_err("Unexpected tool event '%s'", evsel__name(metric_events[i])); - abort(); } - val =3D avg_stats(stats) * scale; - source_count =3D 1; - } else { - struct perf_stat_evsel *ps =3D metric_events[i]->stats; - struct perf_stat_aggr *aggr; - + } + /* Time events are always on CPU0, the first aggregation index. */ + aggr =3D &ps->aggr[is_tool_time ? tool_aggr_idx : aggr_idx]; + if (!aggr || !metric_events[i]->supported) { /* - * If there are multiple uncore PMUs and we're not - * reading the leader's stats, determine the stats for - * the appropriate uncore PMU. + * Not supported events will have a count of 0, which + * can be confusing in a metric. Explicitly set the + * value to NAN. Not counted events (enable time of 0) + * are read as 0. */ - if (evsel && evsel->metric_leader && - evsel->pmu !=3D evsel->metric_leader->pmu && - mexp->metric_events[i]->pmu =3D=3D evsel->metric_leader->pmu) { - struct evsel *pos; - - evlist__for_each_entry(evsel->evlist, pos) { - if (pos->pmu !=3D evsel->pmu) - continue; - if (pos->metric_leader !=3D mexp->metric_events[i]) - continue; - ps =3D pos->stats; - source_count =3D 1; - break; - } - } - aggr =3D &ps->aggr[aggr_idx]; - if (!aggr) - break; - - if (!metric_events[i]->supported) { - /* - * Not supported events will have a count of 0, - * which can be confusing in a - * metric. Explicitly set the value to NAN. Not - * counted events (enable time of 0) are read as - * 0. - */ - val =3D NAN; - source_count =3D 0; - } else { - val =3D aggr->counts.val; - if (!source_count) - source_count =3D evsel__source_count(metric_events[i]); - } + val =3D NAN; + source_count =3D 0; + } else { + val =3D aggr->counts.val; + if (is_tool_time) + val *=3D 1e-9; /* Convert time event nanoseconds to seconds. */ + if (!source_count) + source_count =3D evsel__source_count(metric_events[i]); } n =3D strdup(evsel__metric_id(metric_events[i])); if (!n) @@ -511,7 +496,7 @@ static void generic_metric(struct perf_stat_config *con= fig, pctx->sctx.user_requested_cpu_list =3D strdup(config->user_requested_cpu= _list); pctx->sctx.runtime =3D runtime; pctx->sctx.system_wide =3D config->system_wide; - i =3D prepare_metric(mexp, evsel, pctx, aggr_idx); + i =3D prepare_metric(config, mexp, evsel, pctx, aggr_idx); if (i < 0) { expr__ctx_free(pctx); return; @@ -572,7 +557,7 @@ double test_generic_metric(struct metric_expr *mexp, in= t aggr_idx) if (!pctx) return NAN; =20 - if (prepare_metric(mexp, /*evsel=3D*/NULL, pctx, aggr_idx) < 0) + if (prepare_metric(/*config=3D*/NULL, mexp, /*evsel=3D*/NULL, pctx, aggr_= idx) < 0) goto out; =20 if (expr__parse(&ratio, pctx, mexp->metric_expr)) --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 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 99A352DE1E2 for ; Thu, 6 Nov 2025 07:12:55 +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=1762413177; cv=none; b=MO9bkn6p80qC6zDa81Jfm0FjW9MauxlhTCyD3A/tzcopLXhKF65HpfqeavpAlt+6PvhciXkNztz0/33VnWDV8VVCQsvPkU05ms8CinVOjkuCMGoqGiSHpN+DiYHPedwVLWINYmT6RTC9O1wZSPljHsJW5XLIIoqJHpEQquGZORE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413177; c=relaxed/simple; bh=PsrLYZ63S4/Yl5gUDazBRZIT23aCtdqQCezqcEzmpgg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=tQOXJ+ruXleVBXRSAYDx43zo3mb4+AWOczH5ZUiDkIZklV2BzPQowa3lx1rR2OCKicyGmMBninbsFClcdR7Iu3b4OdHmIjWlRYdOctBOESBMt/iswUgBBuDIyoy8FanbjdRzRZDCZkFhnNGK7QLuXor4o9NObbLVc+cOE8cDO9c= 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=E0R/icLo; 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="E0R/icLo" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-792722e4ebeso872909b3a.3 for ; Wed, 05 Nov 2025 23:12:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413175; x=1763017975; 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=xO1dG1dA38tu5LHgCObN6Aj03K5VCieIjvEPjfcsmMk=; b=E0R/icLo3lPx8rGqKs9fHIP0uUTIBJ7PZ4x/5/gQn/gaEhs13+49OAmO1Dl/O3fJOe QcJqR9SYepqR9DngbK4BgpSEVyLt4rfLlWyPkvUSfzuS+2WlKA1KpDLN9JWofMZjvdVu Adl5mEjx7M4qRHWkY6BAmLcy8wZw9Lo8Ak/I6VwmkgMB0GnsNMovU46nyHC0xPcdVdIL M9rf5dgEP31KJ+xZOgJfqWg0IVUg/iLtY4rGKMeFuesDuOIrXtRuQ0IQhLjc9L+uGDCL J0R+SjJlk46c6Yvmo8CYMaLMr/H1EoexOeTHhZhM4Ys7OfYl13zrnajNsAX6YmbhAe6M ZrHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413175; x=1763017975; 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=xO1dG1dA38tu5LHgCObN6Aj03K5VCieIjvEPjfcsmMk=; b=nP932iK+NLkBilRQuQ7q/WcI2ee3D/xxZ46Qd29DfdEdNk5RQaTQ3KjvGAqLGPxds/ O9345WybXQFVK3u0GD6kRA+iKqJzUhhQ9VH1UFgoXbp5rb/ti5zpeb4QmyQxiGTp+Jqc /yIyXn2HixxXWDqObB7PxOsZ9FmJSYnvwPG95wjNmxPcQ47ZXIBXWsLsFueVYtAgi03S E9DAszWt8iO7veU6hIrZ1P7RueDywdW9TFyP8rMgrXkfKJ3F4pYChNfHi1BzUd2FLxy/ ctp2dEUOaXt+g4gsRi88oL++N5lsu3Wn1u1n8T4et7F+GIsLAxaoYtjzz4z4yhf9npfA aLqA== X-Forwarded-Encrypted: i=1; AJvYcCXvKtuwRpC4hHE37b/7dHKX3gibctBNMUOX4ebWn0IgA6X6JU7F39dvs0iC6fwajLhCPbpX08smdY7ZnBA=@vger.kernel.org X-Gm-Message-State: AOJu0YwxoC7eMwfqr+JN5Qjftvz4ikyK3DIjTnfnx5+NUnr9RGzS21PF gNhJaeoOuvTmoby2z2NUOah7xTbQjN5n1eQNcu2nlZwUu2xUMgv+VvLFJXzCtSKSbZ7V1oMc40c qOOBVa+UADQ== X-Google-Smtp-Source: AGHT+IHfNtEmB2vzB5Qgk4FgJ6by0dipPevRra6zzBmqo37BLyLVuIe07shcJ43P7IrSPny8s42SfF6V60Pa X-Received: from dlad18.prod.google.com ([2002:a05:701b:2212:b0:119:9f33:34af]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:9989:b0:251:43f5:cad4 with SMTP id adf61e73a8af0-34f84008799mr8440665637.10.1762413174906; Wed, 05 Nov 2025 23:12:54 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:36 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-6-irogers@google.com> Subject: [PATCH v3 5/9] perf stat: Reduce scope of ru_stats From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The ru_stats are used to capture user and system time stats when a process exits. These are then applied to user and system time tool events if their reads fail due to the process terminating. Reduce the scope now the metric code no longer reads these values. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 14 +++++++++++++- tools/perf/util/config.c | 1 - tools/perf/util/stat-shadow.c | 2 -- tools/perf/util/stat.h | 16 ---------------- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d89fa9468f89..3cd663b3b357 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -132,6 +132,7 @@ static bool interval_count; static const char *output_name; static int output_fd; static char *metrics; +static struct rusage_stats ru_stats; =20 struct perf_stat { bool record; @@ -729,6 +730,17 @@ static int create_perf_stat_counter(struct evsel *evse= l, evsel->core.threads); } =20 +static void update_rusage_stats(const struct rusage *rusage) +{ + const u64 us_to_ns =3D 1000; + const u64 s_to_ns =3D 1000000000; + + update_stats(&ru_stats.ru_utime_usec_stat, + (rusage->ru_utime.tv_usec * us_to_ns + rusage->ru_utime.tv_sec * s_to_ns= )); + update_stats(&ru_stats.ru_stime_usec_stat, + (rusage->ru_stime.tv_usec * us_to_ns + rusage->ru_stime.tv_sec * s_to_ns= )); +} + static int __run_perf_stat(int argc, const char **argv, int run_idx) { int interval =3D stat_config.interval; @@ -978,7 +990,7 @@ static int __run_perf_stat(int argc, const char **argv,= int run_idx) evlist__reset_aggr_stats(evsel_list); } else { update_stats(&walltime_nsecs_stats, t1 - t0); - update_rusage_stats(&ru_stats, &stat_config.ru_data); + update_rusage_stats(&stat_config.ru_data); } =20 /* diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 6f914620c6ff..cc0746f494f4 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -45,7 +45,6 @@ struct perf_stat_config stat_config =3D { .run_count =3D 1, .metric_only_len =3D METRIC_ONLY_LEN, .walltime_nsecs_stats =3D &walltime_nsecs_stats, - .ru_stats =3D &ru_stats, .big_num =3D true, .ctl_fd =3D -1, .ctl_fd_ack =3D -1, diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 939ac3269a44..c59578886b4f 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -18,7 +18,6 @@ #include "tool_pmu.h" =20 struct stats walltime_nsecs_stats; -struct rusage_stats ru_stats; =20 enum { CTX_BIT_USER =3D 1 << 0, @@ -74,7 +73,6 @@ static int evsel_context(const struct evsel *evsel) void perf_stat__reset_shadow_stats(void) { memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats)); - memset(&ru_stats, 0, sizeof(ru_stats)); } =20 static enum stat_type evsel__stat_type(struct evsel *evsel) diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 34f30a295f89..5b8b4675883c 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -102,7 +102,6 @@ struct perf_stat_config { const char *csv_sep; struct stats *walltime_nsecs_stats; struct rusage ru_data; - struct rusage_stats *ru_stats; struct cpu_aggr_map *aggr_map; aggr_get_id_t aggr_get_id; struct cpu_aggr_map *cpus_aggr_map; @@ -132,25 +131,10 @@ static inline void init_stats(struct stats *stats) stats->max =3D 0; } =20 -static inline void init_rusage_stats(struct rusage_stats *ru_stats) { - init_stats(&ru_stats->ru_utime_usec_stat); - init_stats(&ru_stats->ru_stime_usec_stat); -} - -static inline void update_rusage_stats(struct rusage_stats *ru_stats, stru= ct rusage* rusage) { - const u64 us_to_ns =3D 1000; - const u64 s_to_ns =3D 1000000000; - update_stats(&ru_stats->ru_utime_usec_stat, - (rusage->ru_utime.tv_usec * us_to_ns + rusage->ru_utime.tv_s= ec * s_to_ns)); - update_stats(&ru_stats->ru_stime_usec_stat, - (rusage->ru_stime.tv_usec * us_to_ns + rusage->ru_stime.tv_s= ec * s_to_ns)); -} - struct evsel; struct evlist; =20 extern struct stats walltime_nsecs_stats; -extern struct rusage_stats ru_stats; =20 enum metric_threshold_classify { METRIC_THRESHOLD_UNKNOWN, --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 B41922E7BDE for ; Thu, 6 Nov 2025 07:12:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413179; cv=none; b=Pq324lU5183wWzaxG+y75/J5dCritmRnzWOSQg71XmGBKoNm3YCDVACmHEjGjjj/lvn1nI6gyGm2upK3sPbkoYy5h1b2PGvAIV+9G5ZICDgl00d/SWigdvuVwiDS+1QIw931s9l5PEFyp81qOozCR8SZ/HwrWGS2HrEahf83cMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413179; c=relaxed/simple; bh=Kqri/Alb+V+w7qzG+QBHkhKocG0ET4LkykOzlLyraoc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=awvEODDa9Gh9vcsoZUVhqImBrxi6MnFX4FHTKB6puCsKgIh9KmK3FKvXQhqjmU24fGJ6ThRF49DTAWMXfEXc6+u0766n9ixe7gbUnAKLrtanJlWdKCgbUb9X+rWOVlOxCjHLky2Gx+4QDgFm+56iUcSXzaRR/7wyLSG8piwW2B8= 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=Yt5EBKFL; arc=none smtp.client-ip=209.85.214.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="Yt5EBKFL" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2958c80fcabso3525225ad.0 for ; Wed, 05 Nov 2025 23:12:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413177; x=1763017977; 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=78IdArXu/o78rf9RBGlZEphptoytZiyY9nptrqq9n9I=; b=Yt5EBKFLBOAOqqgLuo7UCQCYimDu07kWwX4Rxcu0HP0j8THiSUH1cpAQA2s9pCgyiw UBBqQpZbHamQ+bhOwmIOlRdp+Y42dxsYltQ6q4XyJIzfjQaprBYvVhhjUA8w2MhOMqIY Y08l+7JqHWiKEbg+K1fZfZqSfvwkLceAYZXP4WVzdNJ9QliCq9odxjBL7NuwyfG6bq6h yhGNhvxGu0HIWaGadLnOnuMRWEVDDsjwelHoLale2ODBIuudvu0hkzHHykovuPS7zayb cSLratj6bwf2DPtYOT173y7/itXWyQfLZi1FZ6tb795fgs+2rBy1R2C0NSMDMVNYqj29 YGNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413177; x=1763017977; 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=78IdArXu/o78rf9RBGlZEphptoytZiyY9nptrqq9n9I=; b=AKhMW9eh+2awPYtp67F0wcwSv8NpjBltchNr27qLs7nIJohXKdxidgZpgIjsrOsCNF EUVFW2BehC1nHRFA6nN2Az94QHx+e4y4506jVzezTBguFO5anwNgXzdxzjEnzp6ywKe1 Fu5iH8ehiqehX3eXLWuDuEblnL4eQYMs8tYm4v6VhS+VHppw8pdVeXFYrUBxM/TP3mgR absu66Qa3LXWBECjVEMRO9Q8xiDuWPtvPZ4eofBoehbijGznSJhAOBgiBefTV5GAKyYY Cg3atA6f8pihklify7FfKOE7z1Krl+LYcZ9e0piI9SdWKBgqTFGSZp1ha/f3pid+GDU4 Zi/w== X-Forwarded-Encrypted: i=1; AJvYcCUlnOLRPSIaYiGKwpwX+4NkRiDmVysX/3pyo1kIEJuVyX3tBM+9Ya6DD1n7u1UmuXldye3VKIRzJS6SZso=@vger.kernel.org X-Gm-Message-State: AOJu0YxI6KyIH0Bky2oIhSzfxCM7Xrasl/3Km8fcx25Ym3nQMfc2PZdS vhtSpkN8B9YUTNmz0ap9fA2sZVlmMlEmedfJ7v8KSTiFocMLOnST5n8fAekwooAKzaKtBOPyIQ9 E/f9sg0VqRA== X-Google-Smtp-Source: AGHT+IHT3qB+8n6x1TMTaVVHCYrNGzGlIQq4aSpq/V8+riLbDRCRUniwFBQiQEuaxOEgRM16X/FJOKJuYGXA X-Received: from dlbuu5.prod.google.com ([2002:a05:7022:7e85:b0:119:49ca:6ba7]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:9303:b0:295:745a:8016 with SMTP id d9443c01a7336-2962ad079admr63903935ad.11.1762413177013; Wed, 05 Nov 2025 23:12:57 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:37 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-7-irogers@google.com> Subject: [PATCH v3 6/9] perf tool_pmu: More accurately set the cpus for tool events From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The user and system time events can record on different CPUs, but for all other events a single CPU map of just CPU 0 makes sense. In parse-events detect a tool PMU and then pass the perf_event_attr so that the tool_pmu can return CPUs specific for the event. This avoids a CPU map of all online CPUs being used for events like duration_time. Avoiding this avoids the evlist CPUs containing CPUs for which duration_time just gives 0. Minimizing the evlist CPUs can remove unnecessary sched_setaffinity syscalls that delay metric calculations. Signed-off-by: Ian Rogers --- tools/perf/util/parse-events.c | 9 +++++++-- tools/perf/util/tool_pmu.c | 19 +++++++++++++++++++ tools/perf/util/tool_pmu.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 0c0dc20b1c13..7b2422ccb554 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -30,6 +30,7 @@ #include "util/event.h" #include "util/bpf-filter.h" #include "util/stat.h" +#include "util/tool_pmu.h" #include "util/util.h" #include "tracepoint.h" #include @@ -227,8 +228,12 @@ __add_event(struct list_head *list, int *idx, if (pmu) { is_pmu_core =3D pmu->is_core; pmu_cpus =3D perf_cpu_map__get(pmu->cpus); - if (perf_cpu_map__is_empty(pmu_cpus)) - pmu_cpus =3D cpu_map__online(); + if (perf_cpu_map__is_empty(pmu_cpus)) { + if (perf_pmu__is_tool(pmu)) + pmu_cpus =3D tool_pmu__cpus(attr); + else + pmu_cpus =3D cpu_map__online(); + } } else { is_pmu_core =3D (attr->type =3D=3D PERF_TYPE_HARDWARE || attr->type =3D=3D PERF_TYPE_HW_CACHE); diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index b895e88ff740..03864a8f5e91 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -2,6 +2,7 @@ #include "cgroup.h" #include "counts.h" #include "cputopo.h" +#include "debug.h" #include "evsel.h" #include "pmu.h" #include "print-events.h" @@ -12,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +108,23 @@ const char *evsel__tool_pmu_event_name(const struct ev= sel *evsel) return tool_pmu__event_to_str(evsel->core.attr.config); } =20 +struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr) +{ + static struct perf_cpu_map *cpu0_map; + enum tool_pmu_event event =3D (enum tool_pmu_event)attr->config; + + if (event <=3D TOOL_PMU__EVENT_NONE || event >=3D TOOL_PMU__EVENT_MAX) { + pr_err("Invalid tool PMU event config %llx\n", attr->config); + return NULL; + } + if (event =3D=3D TOOL_PMU__EVENT_USER_TIME || event =3D=3D TOOL_PMU__EVEN= T_SYSTEM_TIME) + return cpu_map__online(); + + if (!cpu0_map) + cpu0_map =3D perf_cpu_map__new_int(0); + return perf_cpu_map__get(cpu0_map); +} + static bool read_until_char(struct io *io, char e) { int c; diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h index d642e7d73910..e95fcbd55384 100644 --- a/tools/perf/util/tool_pmu.h +++ b/tools/perf/util/tool_pmu.h @@ -39,6 +39,7 @@ bool tool_pmu__read_event(enum tool_pmu_event ev, struct = evsel *evsel, u64 *resu u64 tool_pmu__cpu_slots_per_cycle(void); =20 bool perf_pmu__is_tool(const struct perf_pmu *pmu); +struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr); =20 bool evsel__is_tool(const struct evsel *evsel); enum tool_pmu_event evsel__tool_event(const struct evsel *evsel); --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A6152E7BD3 for ; Thu, 6 Nov 2025 07:12:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413181; cv=none; b=W6XZ5KCR5nY9iHHPbtzbmvBRHF11EuCZ432tgnzhWnu1tHg54ioJC2NRSaA6/LQOyoILtphLWZPuTGDwFMozt2TzePWPXXVVlJ672PXuF+mVH+T3ovQ55gbSGmdD7Pn0s/7ASMrBmdBW8ahNm1+ymWTECTge1THwL46BnKXvLBQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413181; c=relaxed/simple; bh=JNhLGs00rNW/+7lVVO0bVZOwTnKCZ+wq/Mka8MFSn0M=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=pOZlIFZ3NKURhKTHLL0h9cMqo7GwewUsIYL2WTPxv5n5tWgBxnYMr8EMwpIHEr6g6HwlaQUuo8qLxDndW2xVh7eq5fCVv39KHfjCkz5zgy9qYyEppTi9n0bWq/l77Xvmu3iOJRduVGiqhW7YLa3CIwqNdbR1liToWdLzZqBqGQ8= 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=WrjVhIfo; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="WrjVhIfo" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b9a72a43e42so531233a12.2 for ; Wed, 05 Nov 2025 23:12:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413179; x=1763017979; 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=xJUze4+Oq5s5lqHaP7yGjZVTEId13jiEFeb/gCDInuw=; b=WrjVhIfoscw3vy3cwFe4vOM8Js9QS0AQmx294sJ8icz3nAT3jKp8hjHvwqVKtd5lAx ox1YIgkYsc/HI2LwLftg/wUM2zob0SPp4GfYqPZy7qXXu/rdDfR45Q2aCxmzyNXn0TvN 0h8R9fTe5WSLWAknliWgou9tVw9R5iiOCjDBchoc5WyIjfuvUGUE9R4WpC6kROgvKQX1 IvXM3eUOpnxtZBDpDp0GN4xsc4QaMPev2PwbgEk51GYBITJ+mLYrmKMn4bZa0tMPNO4S E6DsOvTX9QJoYgM9z+a3AEI3H5sMlyO/voOLHOtAY3kqGolhwmaihdwVKg52p1Wn+2YA rVwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413179; x=1763017979; 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=xJUze4+Oq5s5lqHaP7yGjZVTEId13jiEFeb/gCDInuw=; b=FUTi9ut3YBRKgloeYKVPHUS+4ovrSqp/HVeJdH50Lu4DHewty5ugArJxg+fOmpwy8l UE1AGepVY82WI4z9+3c3TAdjlnR0UM0e/VJE56LRWj+yZbhT2rLnIg/3S6xsuvMWBmaI r83qWzMNrZwZtB0KaQvRL4r3WC9gvqBkZKdsWsZagYKaYNfHrl+AOa2dUI1Vnp/fOMnY N9XGLn6tvTcBk5PrzUUTPWSvxYk1XmJj6RqhS8UP29HRTzcsHnEV8bPkCD5WFzG93yTF DdfJDL4w34CtrbnsiFWT95gZYBQkyNlAHHxl9FPDhwdIl63CnL7nVElaI1CocKeDsLIG U5+A== X-Forwarded-Encrypted: i=1; AJvYcCW2tSi5Pshot561hPht7sSLFyBiQ/Nv2laACIjLfL/3tkavx9tD2Eg/qPLy9M3A2Eqi1kjmmiJ17jwdLlA=@vger.kernel.org X-Gm-Message-State: AOJu0Yxm9ShRJZqQUaMlEMz5MRjXBzkbiZBQ6bpPlJctRwEL2G5PjfDl 6sqyRZoChNRnZXjiWxdpXAyneIBb+3WgjkRaWWMTJUPeDF7nDF7HLfF7Toyawx0o2IFuwIvLKA+ 5H1DEz9Zfyg== X-Google-Smtp-Source: AGHT+IH8O2GTB3pEV8v6n4UI2aM1Jz8C3CJkmJKSFmXDhhUbg0GLfjZGHASl0r5Lci/IgQReBx4r/6vM7HNl X-Received: from dlbcq12.prod.google.com ([2002:a05:7022:248c:b0:119:b185:ea71]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:4320:b0:34f:27f:1e67 with SMTP id adf61e73a8af0-34f840087ffmr8239911637.12.1762413178887; Wed, 05 Nov 2025 23:12:58 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:38 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-8-irogers@google.com> Subject: [PATCH v3 7/9] perf evlist: Reduce affinity use and move into iterator, fix no affinity From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The evlist__for_each_cpu iterator will call sched_setaffitinity when moving between CPUs to avoid IPIs. If only 1 IPI is saved then this may be unprofitable as the delay to get scheduled may be considerable. This may be particularly true if reading an event group in `perf stat` in interval mode. Move the affinity handling completely into the iterator so that a single evlist__use_affinity can determine whether CPU affinities will be used. For `perf record` the change is minimal as the dummy event and the real event will always make the use of affinities the thing to do. In `perf stat`, tool events are ignored and affinities only used if >1 event on the same CPU occur. Determining if affinities are useful is done by per-event in a new PMU benefits from affinity function. Fix a bug where when there are no affinities that the CPU map iterator may reference a CPU not present in the initial evsel. Fix by making the iterator and non-iterator code common. Fix a bug where closing events on an evlist wasn't closing TPEBS events. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 128 ++++++++++++++---------------- tools/perf/util/evlist.c | 160 ++++++++++++++++++++++++-------------- tools/perf/util/evlist.h | 26 +++++-- tools/perf/util/pmu.c | 12 +++ tools/perf/util/pmu.h | 1 + 5 files changed, 189 insertions(+), 138 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 3cd663b3b357..5f31cd5bb03b 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -360,22 +360,14 @@ static int read_counter_cpu(struct evsel *counter, in= t cpu_map_idx) return 0; } =20 -static int read_affinity_counters(void) +static int read_counters_with_affinity(void) { struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity; =20 if (all_counters_use_bpf) return 0; =20 - if (!target__has_cpu(&target) || target__has_per_thread(&target)) - affinity =3D NULL; - else if (affinity__setup(&saved_affinity) < 0) - return -1; - else - affinity =3D &saved_affinity; - - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { struct evsel *counter =3D evlist_cpu_itr.evsel; =20 if (evsel__is_bpf(counter)) @@ -384,8 +376,6 @@ static int read_affinity_counters(void) if (!counter->err) counter->err =3D read_counter_cpu(counter, evlist_cpu_itr.cpu_map_idx); } - if (affinity) - affinity__cleanup(&saved_affinity); =20 return 0; } @@ -408,12 +398,18 @@ static int read_bpf_map_counters(void) =20 static int read_counters(void) { - if (!stat_config.stop_read_counter) { - if (read_bpf_map_counters() || - read_affinity_counters()) - return -1; - } - return 0; + int ret; + + if (stat_config.stop_read_counter) + return 0; + + // Read all BPF counters first. + ret =3D read_bpf_map_counters(); + if (ret) + return ret; + + // Read non-BPF and non-tool counters next. + return read_counters_with_affinity(); } =20 static void process_counters(void) @@ -754,7 +750,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 @@ -766,14 +761,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)) { @@ -786,49 +773,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, @@ -836,7 +822,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) @@ -845,7 +831,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) @@ -854,17 +840,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) { @@ -1015,7 +1002,6 @@ static int __run_perf_stat(int argc, const char **arg= v, int run_idx) if (forks) evlist__cancel_workload(evsel_list); =20 - affinity__cleanup(affinity); return err; } =20 diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e8217efdda53..b6df81b8a236 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -358,36 +358,111 @@ int evlist__add_newtp(struct evlist *evlist, const c= har *sys, const char *name, } #endif =20 -struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct= affinity *affinity) +/* + * Should sched_setaffinity be used with evlist__for_each_cpu? Determine if + * migrating the thread will avoid possibly numerous IPIs. + */ +static bool evlist__use_affinity(struct evlist *evlist) +{ + struct evsel *pos; + struct perf_cpu_map *used_cpus =3D NULL; + bool ret =3D false; + + /* + * With perf record core.user_requested_cpus is usually NULL. + * Use the old method to handle this for now. + */ + if (!evlist->core.user_requested_cpus || + cpu_map__is_dummy(evlist->core.user_requested_cpus)) + return false; + + evlist__for_each_entry(evlist, pos) { + struct perf_cpu_map *intersect; + + if (!perf_pmu__benefits_from_affinity(pos->pmu)) + continue; + + if (evsel__is_dummy_event(pos)) { + /* + * The dummy event is opened on all CPUs so assume >1 + * event with shared CPUs. + */ + ret =3D true; + break; + } + if (evsel__is_retire_lat(pos)) { + /* + * Retirement latency events are similar to tool ones in + * their implementation, and so don't require affinity. + */ + continue; + } + if (perf_cpu_map__is_empty(used_cpus)) { + /* First benefitting event, we want >1 on a common CPU. */ + used_cpus =3D perf_cpu_map__get(pos->core.cpus); + continue; + } + if ((pos->core.attr.read_format & PERF_FORMAT_GROUP) && + evsel__leader(pos) !=3D pos) { + /* Skip members of the same sample group. */ + continue; + } + intersect =3D perf_cpu_map__intersect(used_cpus, pos->core.cpus); + if (!perf_cpu_map__is_empty(intersect)) { + /* >1 event with shared CPUs. */ + perf_cpu_map__put(intersect); + ret =3D true; + break; + } + perf_cpu_map__put(intersect); + perf_cpu_map__merge(&used_cpus, pos->core.cpus); + } + perf_cpu_map__put(used_cpus); + return ret; +} + +void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evl= ist *evlist) { - struct evlist_cpu_iterator itr =3D { + *itr =3D (struct evlist_cpu_iterator){ .container =3D evlist, .evsel =3D NULL, .cpu_map_idx =3D 0, .evlist_cpu_map_idx =3D 0, .evlist_cpu_map_nr =3D perf_cpu_map__nr(evlist->core.all_cpus), .cpu =3D (struct perf_cpu){ .cpu =3D -1}, - .affinity =3D affinity, + .affinity =3D NULL, }; =20 if (evlist__empty(evlist)) { /* Ensure the empty list doesn't iterate. */ - itr.evlist_cpu_map_idx =3D itr.evlist_cpu_map_nr; - } else { - itr.evsel =3D evlist__first(evlist); - if (itr.affinity) { - itr.cpu =3D perf_cpu_map__cpu(evlist->core.all_cpus, 0); - affinity__set(itr.affinity, itr.cpu.cpu); - itr.cpu_map_idx =3D perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu); - /* - * If this CPU isn't in the evsel's cpu map then advance - * through the list. - */ - if (itr.cpu_map_idx =3D=3D -1) - evlist_cpu_iterator__next(&itr); - } + itr->evlist_cpu_map_idx =3D itr->evlist_cpu_map_nr; + return; } - return itr; + + if (evlist__use_affinity(evlist)) { + if (affinity__setup(&itr->saved_affinity) =3D=3D 0) + itr->affinity =3D &itr->saved_affinity; + } + itr->evsel =3D evlist__first(evlist); + itr->cpu =3D perf_cpu_map__cpu(evlist->core.all_cpus, 0); + if (itr->affinity) + affinity__set(itr->affinity, itr->cpu.cpu); + itr->cpu_map_idx =3D perf_cpu_map__idx(itr->evsel->core.cpus, itr->cpu); + /* + * If this CPU isn't in the evsel's cpu map then advance + * through the list. + */ + if (itr->cpu_map_idx =3D=3D -1) + evlist_cpu_iterator__next(itr); +} + +void evlist_cpu_iterator__exit(struct evlist_cpu_iterator *itr) +{ + if (!itr->affinity) + return; + + affinity__cleanup(itr->affinity); + itr->affinity =3D NULL; } =20 void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr) @@ -417,14 +492,11 @@ void evlist_cpu_iterator__next(struct evlist_cpu_iter= ator *evlist_cpu_itr) */ if (evlist_cpu_itr->cpu_map_idx =3D=3D -1) evlist_cpu_iterator__next(evlist_cpu_itr); + } else { + evlist_cpu_iterator__exit(evlist_cpu_itr); } } =20 -bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu= _itr) -{ - return evlist_cpu_itr->evlist_cpu_map_idx >=3D evlist_cpu_itr->evlist_cpu= _map_nr; -} - static int evsel__strcmp(struct evsel *pos, char *evsel_name) { if (!evsel_name) @@ -452,19 +524,11 @@ static void __evlist__disable(struct evlist *evlist, = char *evsel_name, bool excl { struct evsel *pos; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity =3D NULL; bool has_imm =3D false; =20 - // See explanation in evlist__close() - if (!cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) - return; - affinity =3D &saved_affinity; - } - /* Disable 'immediate' events last */ for (int imm =3D 0; imm <=3D 1; imm++) { - evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { pos =3D evlist_cpu_itr.evsel; if (evsel__strcmp(pos, evsel_name)) continue; @@ -482,7 +546,6 @@ static void __evlist__disable(struct evlist *evlist, ch= ar *evsel_name, bool excl break; } =20 - affinity__cleanup(affinity); evlist__for_each_entry(evlist, pos) { if (evsel__strcmp(pos, evsel_name)) continue; @@ -522,16 +585,8 @@ static void __evlist__enable(struct evlist *evlist, ch= ar *evsel_name, bool excl_ { struct evsel *pos; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity =3D NULL; =20 - // See explanation in evlist__close() - if (!cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) - return; - affinity =3D &saved_affinity; - } - - evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { pos =3D evlist_cpu_itr.evsel; if (evsel__strcmp(pos, evsel_name)) continue; @@ -541,7 +596,6 @@ static void __evlist__enable(struct evlist *evlist, cha= r *evsel_name, bool excl_ continue; evsel__enable_cpu(pos, evlist_cpu_itr.cpu_map_idx); } - affinity__cleanup(affinity); evlist__for_each_entry(evlist, pos) { if (evsel__strcmp(pos, evsel_name)) continue; @@ -1338,28 +1392,14 @@ void evlist__close(struct evlist *evlist) { struct evsel *evsel; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity affinity; - - /* - * With perf record core.user_requested_cpus is usually NULL. - * Use the old method to handle this for now. - */ - if (!evlist->core.user_requested_cpus || - cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - evlist__for_each_entry_reverse(evlist, evsel) - evsel__close(evsel); - return; - } - - if (affinity__setup(&affinity) < 0) - return; =20 - evlist__for_each_cpu(evlist_cpu_itr, evlist, &affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { + if (evlist_cpu_itr.cpu_map_idx =3D=3D 0 && evsel__is_retire_lat(evlist_c= pu_itr.evsel)) + evsel__tpebs_close(evlist_cpu_itr.evsel); perf_evsel__close_cpu(&evlist_cpu_itr.evsel->core, evlist_cpu_itr.cpu_map_idx); } =20 - affinity__cleanup(&affinity); evlist__for_each_entry_reverse(evlist, evsel) { perf_evsel__free_fd(&evsel->core); perf_evsel__free_id(&evsel->core); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 5e71e3dc6042..b4604c3f03d6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -10,6 +10,7 @@ #include #include #include +#include "affinity.h" #include "events_stats.h" #include "evsel.h" #include "rblist.h" @@ -361,6 +362,8 @@ struct evlist_cpu_iterator { struct perf_cpu cpu; /** If present, used to set the affinity when switching between CPUs. */ struct affinity *affinity; + /** Maybe be used to hold affinity state prior to iterating. */ + struct affinity saved_affinity; }; =20 /** @@ -368,22 +371,31 @@ struct evlist_cpu_iterator { * affinity, iterate over all CPUs and then the evl= ist * for each evsel on that CPU. When switching betwe= en * CPUs the affinity is set to the CPU to avoid IPIs - * during syscalls. + * during syscalls. The affinity is set up and remo= ved + * automatically, if the loop is broken a call to + * evlist_cpu_iterator__exit is necessary. * @evlist_cpu_itr: the iterator instance. * @evlist: evlist instance to iterate. - * @affinity: NULL or used to set the affinity to the current CPU. */ -#define evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) \ - for ((evlist_cpu_itr) =3D evlist__cpu_begin(evlist, affinity); \ +#define evlist__for_each_cpu(evlist_cpu_itr, evlist) \ + for (evlist_cpu_iterator__init(&(evlist_cpu_itr), evlist); \ !evlist_cpu_iterator__end(&evlist_cpu_itr); \ evlist_cpu_iterator__next(&evlist_cpu_itr)) =20 -/** Returns an iterator set to the first CPU/evsel of evlist. */ -struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct= affinity *affinity); +/** Setup an iterator set to the first CPU/evsel of evlist. */ +void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evl= ist *evlist); +/** + * Cleans up the iterator, automatically done by evlist_cpu_iterator__next= when + * the end of the list is reached. Multiple calls are safe. + */ +void evlist_cpu_iterator__exit(struct evlist_cpu_iterator *itr); /** Move to next element in iterator, updating CPU, evsel and the affinity= . */ void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr); /** Returns true when iterator is at the end of the CPUs and evlist. */ -bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu= _itr); +static inline bool evlist_cpu_iterator__end(const struct evlist_cpu_iterat= or *evlist_cpu_itr) +{ + return evlist_cpu_itr->evlist_cpu_map_idx >=3D evlist_cpu_itr->evlist_cpu= _map_nr; +} =20 struct evsel *evlist__get_tracking_event(struct evlist *evlist); void evlist__set_tracking_event(struct evlist *evlist, struct evsel *track= ing_evsel); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d597263fab4f..caa3bd5e0956 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -2402,6 +2402,18 @@ bool perf_pmu__is_software(const struct perf_pmu *pm= u) return false; } =20 +bool perf_pmu__benefits_from_affinity(struct perf_pmu *pmu) +{ + if (!pmu) + return true; /* Assume is core. */ + + /* + * All perf event PMUs should benefit from accessing the perf event + * contexts on the local CPU. + */ + return pmu->type <=3D PERF_PMU_TYPE_PE_END; +} + FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name) { char path[PATH_MAX]; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 1ebcf0242af8..87e12a9a0e67 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -259,6 +259,7 @@ bool perf_pmu__name_no_suffix_match(const struct perf_p= mu *pmu, const char *to_m * perf_sw_context in the kernel? */ bool perf_pmu__is_software(const struct perf_pmu *pmu); +bool perf_pmu__benefits_from_affinity(struct perf_pmu *pmu); =20 FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name); FILE *perf_pmu__open_file_at(const struct perf_pmu *pmu, int dirfd, const = char *name); --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F9992EACEF for ; Thu, 6 Nov 2025 07:13:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413182; cv=none; b=Hv9wyVBF53G79AWLxOIyKFC5bOeQKtNLeTh3U+623j08XAkhF/P3A+UaZE1CA/U96GVCDg1U/VT6hu7G+tT9LPRErY5nJi2urCQ1IxmKVm+O1QEAorCxX2CFtbeetzSZ9WAnfhd6c4MGU3WqefxD/nZNI0FBpILMZQJAQoX4wvg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413182; c=relaxed/simple; bh=iP5yCD4lNJBZ54VXCnLo6TAsw5GH2qBuAbNIhmsoFCI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=HJ3gslKMLh4xjR5R4/VL/r2M1Q4liBICtmw+uo7WBnlzDzyikJESL035RrJ4dlXJdIcVnMUaZNrc6bXd8PP8JRVwQ6/DoXv2+eR5PnxXUAQKa5KY1cj7PG3fu6YHz1mS5Dv/QZ0Rc2z0QZ1LedtcNQCmC5arFmLJzmH9QK0kEOo= 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=0nQDTx10; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0nQDTx10" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b471737e673so130409a12.1 for ; Wed, 05 Nov 2025 23:13:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413180; x=1763017980; 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=s3mUC9sPFouhj1rBALiYO4Qb6Uq1xN1oWTquV7EiCFw=; b=0nQDTx103mQetrXofg38pcjMLu542t1FIGiGdwXf/ssWhgwIoEoieHlAA296Z18Yho ri8fSQpu6h3I8hCcQkorsnUj8kDuw/IAXsXqmXqB+LwHQToBQkN2NXvfNlgRaUJc9DkM xlGj3qINbxGIOVRUzYemXGtVFHh62OVJrBf0gBWe/SsgMaHnHMGsD+dPq0YsKfeq+ZL7 sDmR5WJqiC+j44Og47LxJgWrVBcTnVvBi4yN/YFJiBm1D6IWBmW/SzWFxCjhD0cWc9L9 xK995CYIBj18uweCyMOVUiCZykqRUN25kC3jHv01IycVzeXm9/vbCiZXotly1okHY63w ATKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413180; x=1763017980; 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=s3mUC9sPFouhj1rBALiYO4Qb6Uq1xN1oWTquV7EiCFw=; b=sns6cd1fLBF8HjwUITgG5fUDfsbz9xI9fI4GINCb/MPwtycTUD/7zBI/iFmnwHLW8U eVV3eScdADwIyXI4VO8mnLbS+fRzw5f+SzuUnjW+R1avBv8MV2DtBqDOF7Yv3XXNn/gV xEyrf7Qrzs8xsV8607PAKBxYpcRpSJGjq2GXosK/jf8ck/XGpZk+fzxtkECQfh1R8OSN 2G4HTiS8NeEB/+32661IaOnNQe1s1vg8X0HONSD/8HwuniHgfgHVb3xQxgZyJdYrt0RN +2sMR1XvINqoxjAwpFD+deX8P4qKKG6R1pELiguDykgLHnr3HNBcasl7aFfubZauIFSU 5lYw== X-Forwarded-Encrypted: i=1; AJvYcCXR/Bo8E3U2/Qg2iqhkTJm1OJCzYbF6jTX43J7YTlHPGEdQj7atr8s4Zwwk9x8qBYIi61bxG3tHKPo04F0=@vger.kernel.org X-Gm-Message-State: AOJu0YzFOeIDI3qBm8pEWv7erhVl572Ugf81HkFpQZyf8i9uTKQn98ZH ncCe4xDiwnCJPuTd1J4gpJuOnhMZOnCNbYlAhrWEAcxWy4fRwIwYPuvRa2G3oFfR6Qn6GeIxIyZ yTD8Tap/25Q== X-Google-Smtp-Source: AGHT+IG4sIhbJsW2cMjujNFWdXTnrQvTWPxQtMzU7mQ4Vd/UmEodRv7ANnAPYqSxmGy75vD+p+QmxdkA76f1 X-Received: from dlbdt2.prod.google.com ([2002:a05:7022:2582:b0:119:49ca:6b8d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:4306:b0:346:331:97e4 with SMTP id adf61e73a8af0-34f87301a42mr8511687637.56.1762413180476; Wed, 05 Nov 2025 23:13:00 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:39 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-9-irogers@google.com> Subject: [PATCH v3 8/9] perf stat: Read tool events last From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When reading a metric like memory bandwidth on multiple sockets, the additional sockets will be on CPUS > 0. Because of the affinity reading, the counters are read on CPU 0 along with the time, then the later sockets are read. This can lead to the later sockets having a bandwidth larger than is possible for the period of time. To avoid this moving the reading of tool events to occur after all other events are read. Signed-off-by: Ian Rogers --- tools/perf/builtin-stat.c | 29 ++++++++++++++++++++++++++++- tools/perf/util/evlist.c | 4 ---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 5f31cd5bb03b..75ff08c5f0ed 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -373,6 +373,9 @@ static int read_counters_with_affinity(void) if (evsel__is_bpf(counter)) continue; =20 + if (evsel__is_tool(counter)) + continue; + if (!counter->err) counter->err =3D read_counter_cpu(counter, evlist_cpu_itr.cpu_map_idx); } @@ -396,6 +399,24 @@ static int read_bpf_map_counters(void) return 0; } =20 +static int read_tool_counters(void) +{ + struct evsel *counter; + + evlist__for_each_entry(evsel_list, counter) { + int idx; + + if (!evsel__is_tool(counter)) + continue; + + perf_cpu_map__for_each_idx(idx, counter->core.cpus) { + if (!counter->err) + counter->err =3D read_counter_cpu(counter, idx); + } + } + return 0; +} + static int read_counters(void) { int ret; @@ -409,7 +430,13 @@ static int read_counters(void) return ret; =20 // Read non-BPF and non-tool counters next. - return read_counters_with_affinity(); + ret =3D read_counters_with_affinity(); + if (ret) + return ret; + + // Read the tool counters last. This way the duration_time counter + // should always be greater than any other counter's enabled time. + return read_tool_counters(); } =20 static void process_counters(void) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b6df81b8a236..fc3dae7cdfca 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -368,10 +368,6 @@ static bool evlist__use_affinity(struct evlist *evlist) struct perf_cpu_map *used_cpus =3D NULL; bool ret =3D false; =20 - /* - * With perf record core.user_requested_cpus is usually NULL. - * Use the old method to handle this for now. - */ if (!evlist->core.user_requested_cpus || cpu_map__is_dummy(evlist->core.user_requested_cpus)) return false; --=20 2.51.2.1041.gc1ab5b90ca-goog From nobody Sun Feb 8 18:48:25 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3C512EE5FE for ; Thu, 6 Nov 2025 07:13:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413184; cv=none; b=ZSkRzbkg6MPmsyvIPyz1s9ktMzJ/IrH0GgWRL1YlIcGndvy2W0ki+NW0We41fq/7a2Lt3PaIRFZDeJCl4r63qBSgo+Gbcp1FM+pMmNOW8SxVjfu6l9lNtrWFfnE2QTu6aj2l9u9W6thc2r7tbjCZQH3ddNSFLX1NGSWe+iBuKDo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762413184; c=relaxed/simple; bh=baW/PP9vuOXOepoc3ZzKNVeVqn+YVFSWu3Wdb3YH+qI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=efTF55ycswGTox0sdvigmbvuGTW3GsQJynKFvsTYgf+lFPdG7jkp5KIDHI/f6S0rDSr+DO+fEqZ8g2RiTJ15IdYtHP8aZu3egJTt23Qvxkwg5/rHHXiOQh6TQtlaW4BGjKa+C/Qm/IYQLt28W6m715KbPjNeCQkDm3RmbgDaaw4= 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=jp41COIl; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="jp41COIl" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b9ceccbd7e8so118656a12.0 for ; Wed, 05 Nov 2025 23:13:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1762413182; x=1763017982; 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=w9ZhWJR/a4jUzE3S599HAQn9Ex0tBJc68Cyk87AziX0=; b=jp41COIl3kshd8F54ki0AIAlhzfrPWu+a82JLFbTtanQYzf3w2GwDWbmgw58zdtO+c lVp2ALCQv0qEPuydZ9UU9wr6eO2sbiB8SUzfhs9ZDpDr8eYBpyQcwCxDqqQrsJ9rJI6x S8sRlawflEhk0hBXpGNsYUUGLq098Mz8WTYdojD6bLzLphz3DPFaiE/7qOm10AtWIPEj 08SKLuEQDJBuj/CyGHLSwzHMISqb8KaqTvj9Xvde88d3Jnt+aXRKTDoShNY3+lsZqzTw L4uuAiAVItluCXHzSC/o3XzWNWLzOG0w3nnZOrv/9gtsvR30CdgW8fDXMO8//f9VSHyU yHZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762413182; x=1763017982; 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=w9ZhWJR/a4jUzE3S599HAQn9Ex0tBJc68Cyk87AziX0=; b=V/OClUPMqnlmsXSrBvLGkCvbWvgXgOlemtqqTqD9cBCiUibfAKNOorctr6WRBb4zzy Rv+SsrK470WqlpujLHLpnU+iH2WlksnLsBybBSRcOW5FmZS3o248JWQGjMlpwkV4y9gA e8lBq8NdRC90Kbq566SObyCeyF723lr70lYeu3qUu72rFmrOBPK8LwLNMBkGDx8/mlbi +BSW3Z+7Hsbl9+IkxcW00TY8lmGpUYqwJr+5G+0UzSZZpyB6M1jD8wuhzoIg4QhKjHYh W4V2fndkIk8D8eGCYC7Kc9MZKW16ODQdw/QoDaujvkwDrrYCXGsao3AODCclk3z3Upt1 YIQQ== X-Forwarded-Encrypted: i=1; AJvYcCXilgLAeKycRjBuap0xYngx56uKcmAPY6Dq3BakpCRTo/T+l+6PT7vFMtHB8LRqywjHyghl6HdQsNDzBfg=@vger.kernel.org X-Gm-Message-State: AOJu0YymR5Rk8+z8tk/oc9CXIdPGPClxrmisPbOtycv6dTVBwdtmHwqc HrtVObK0zbafRU4yLVcNmUgkW+fSDJHYAEkNAx6tPbpTUpBZp8RH+S58GoMb6wqMuYcur0cFCrY J/Tk1W6A7hA== X-Google-Smtp-Source: AGHT+IE226Se0eAuwakSfAwq7yVrK/hma19wGPnIC5iTTdwVG+sTf6vfeyZ6rqw5EP3YtKPbdGB+kq+zuvoc X-Received: from dlbrs16.prod.google.com ([2002:a05:7022:f690:b0:119:49ca:6b95]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:12c3:b0:341:6d44:dfd5 with SMTP id adf61e73a8af0-34f8580ad59mr8097329637.33.1762413182363; Wed, 05 Nov 2025 23:13:02 -0800 (PST) Date: Wed, 5 Nov 2025 23:12:40 -0800 In-Reply-To: <20251106071241.141234-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: <20251106071241.141234-1-irogers@google.com> X-Mailer: git-send-email 2.51.2.1041.gc1ab5b90ca-goog Message-ID: <20251106071241.141234-10-irogers@google.com> Subject: [PATCH v3 9/9] perf stat: Add no-affinity flag From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Dr. David Alan Gilbert" , Yang Li , James Clark , Thomas Falcon , Thomas Richter , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Andi Kleen , Dapeng Mi Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add flag that disables affinity behavior. Using sched_setaffinity to place a perf thread on a CPU can avoid certain interprocessor interrupts but may introduce a delay due to the scheduling, particularly on loaded machines. Add a command line option to disable the behavior. This behavior is less present in other tools like `perf record`, as it uses a ring buffer and doesn't make repeated system calls. Signed-off-by: Ian Rogers --- tools/perf/Documentation/perf-stat.txt | 4 ++++ tools/perf/builtin-stat.c | 6 ++++++ tools/perf/util/evlist.c | 2 +- tools/perf/util/evlist.h | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentat= ion/perf-stat.txt index 1a766d4a2233..1ffb510606af 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -382,6 +382,10 @@ color the metric's computed value. Don't print output, warnings or messages. This is useful with perf stat record below to only write data to the perf.data file. =20 +--no-affinity:: +Don't change scheduler affinities when iterating over CPUs. Disables +an optimization aimed at minimizing interprocessor interrupts. + STAT RECORD ----------- Stores stat data into perf data file. diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 75ff08c5f0ed..f2f149f0c2cf 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2479,6 +2479,7 @@ static int parse_tpebs_mode(const struct option *opt,= const char *str, int cmd_stat(int argc, const char **argv) { struct opt_aggr_mode opt_mode =3D {}; + bool no_affinity =3D false; struct option stat_options[] =3D { OPT_BOOLEAN('T', "transaction", &transaction_run, "hardware transaction statistics"), @@ -2607,6 +2608,8 @@ int cmd_stat(int argc, const char **argv) "don't print 'summary' for CSV summary output"), OPT_BOOLEAN(0, "quiet", &quiet, "don't print any output, messages or warnings (useful with record)"), + OPT_BOOLEAN(0, "no-affinity", &no_affinity, + "don't allow affinity optimizations aimed at reducing IPIs"), OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type", "Only enable events on applying cpu with this type " "for hybrid platform (e.g. core or atom)", @@ -2664,6 +2667,9 @@ int cmd_stat(int argc, const char **argv) } else stat_config.csv_sep =3D DEFAULT_SEPARATOR; =20 + if (no_affinity) + evsel_list->no_affinity =3D true; + if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) { argc =3D __cmd_record(stat_options, &opt_mode, argc, argv); if (argc < 0) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index fc3dae7cdfca..53c8e974de8b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -368,7 +368,7 @@ static bool evlist__use_affinity(struct evlist *evlist) struct perf_cpu_map *used_cpus =3D NULL; bool ret =3D false; =20 - if (!evlist->core.user_requested_cpus || + if (evlist->no_affinity || !evlist->core.user_requested_cpus || cpu_map__is_dummy(evlist->core.user_requested_cpus)) return false; =20 diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index b4604c3f03d6..c7ba0e0b2219 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -59,6 +59,7 @@ struct event_enable_timer; struct evlist { struct perf_evlist core; bool enabled; + bool no_affinity; int id_pos; int is_pos; int nr_br_cntr; --=20 2.51.2.1041.gc1ab5b90ca-goog