From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94FD53E40F9; Fri, 16 Oct 2026 21:21:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185674; cv=none; b=L3HFFIy5C1/LT29pO5RusoSXyfYg6PuuWD/Te3fp4hXjyS30oHrXMz0O59M0JOeDY9PIiVq+k5RIEpTpGZyw6Himekxpv9Iia6/78dRcAHAol/yln0ja5q7rKUT/LWdN3v7IGhn2nPIfUI3Z386k0a4vL/RXX8kG41LcqIP+eHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185674; c=relaxed/simple; bh=SmxGbot7TR9HDni/Elet4vrkv/9q2gIcEau2siebyHQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SFYOBQRqVCx7zZwxm2MID8PMs3AmSOyGK0+xO0O6GBoFLMzGg/1hqNhhutJ+jrgdqgpseolB2ib0aqaA+l3kygp9xhUf4A/1YwTUXrJmZUYnWTz+5BECUcAKQ/GmEMu3AldR9dVe2KYZxszAO2PvTmrS+5Kh/NWFULY2K8Y0pjA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CXU5NJ7e; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CXU5NJ7e" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 895801F000C5; Fri, 16 Oct 2026 21:21:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185673; bh=w5/BfkC1OceS3dX0jV7eo4MrwK7mpfm5mPAWRCk6F7M=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=CXU5NJ7e2UpLW+4H0A3CdXDroG4byDNrd3d0cbXhkx5GswNFYwf+G+NpvRA9W6eCA CvPR1SjKb6dbnRjFGbvd5HWqostjuJ0/1S3zF/jJACKssuBRV5TQ0+ZNcae3Z+M1iT TYtSDiGgdLych+DxrCXIVKopVQB8gbUbLuB2mwGtcKFvh6ASmhvdgHZfsgqwv3fm6w ffCTJS/PsuQGjI1JU7u0lAIJZZEOwWbA6OOw3/80jugay6yaSoJood4IPAlg2itfDL 8lAhxHXDqiUgo9EDFNthi9P6lyFW6x62ndtZCe1naE4DH96YGD95KuT8SRknuDAjGX lffmUSxqf0v7A== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 01/21] perf test attr: Fix record dwarf sample_type expectation Date: Fri, 16 Oct 2026 18:20:42 -0300 Message-ID: <20261016212102.76550-2-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Since commit bdd051e24914 ("perf record: Split --data-mmap option"), record_opts__parse_callchain() sets record_data_mmap instead of record->sample_address for the DWARF unwind mode, so -d/--data and its implied PERF_SAMPLE_DATA_SRC are not enabled implicitly anymore. As a result, --call-graph dwarf no longer sets PERF_SAMPLE_ADDR and PERF_SAMPLE_DATA_SRC, making the test fail: expected sample_type=3D45359, got 12583 where 45359 (0xb12f) is: IP|TID|TIME|ADDR|CALLCHAIN|PERIOD|REGS_USER|STACK_USER|DATA_SRC and 12583 (0x3127) is: IP|TID|TIME|CALLCHAIN|PERIOD|REGS_USER|STACK_USER i.e. the values differ exactly by PERF_SAMPLE_ADDR (0x8) and PERF_SAMPLE_DATA_SRC (0x8000). The mmap_data=3D1 expectation is still correct as DWARF now enables record_data_mmap. This went unnoticed until tests/attr.sh stopped ignoring attr.py's return value. Fixes: bdd051e249141c79 ("perf record: Split --data-mmap option") Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/attr/test-record-graph-dwarf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/tests/shell/attr/test-record-graph-dwarf b/tools/pe= rf/tests/shell/attr/test-record-graph-dwarf index ae92061d611ded68..fbe0faa8cdb6a8f4 100644 --- a/tools/perf/tests/shell/attr/test-record-graph-dwarf +++ b/tools/perf/tests/shell/attr/test-record-graph-dwarf @@ -4,7 +4,7 @@ args =3D --no-bpf-event --call-graph dwarf -- kill >/dev= /null 2>&1 ret =3D 1 =20 [event:base-record] -sample_type=3D45359 +sample_type=3D12583 exclude_callchain_user=3D1 sample_stack_user=3D8192 # TODO different for each arch, no support for that now --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1FF273AB47A; Fri, 16 Oct 2026 21:21:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185678; cv=none; b=hh47gkBuPrjRsMG4+vnTYcBDBerd6IRA2qMcGUzjOYDrwasefTLxF8al5HzOHcTMKafis9TJVhBBaEFVd0VcmlWE9gii8sS5v2lxL2b+mQg0Wwq8hCaEIYrQV3f+zO5Aqcot6VbsuIhM4J5L3P+mvS+0ge9Hac0fK4ydBVY0Wbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185678; c=relaxed/simple; bh=VNFzsQucjROEmM8sqMJSi0+AW8nsSQAFbUVvfqMTBo0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eVHAVc73/jnHsX7cEYDv111uCaId1n/6M+ZVsMbZtR+OUfqdN4uuzFn+5Xzlnf5pLqEYzvI0KXCXFmH1zaxvVqWTc93e6KuBf20j7/Bs97Jy8JgeGVbupquQaO2T9qqMauA9NeJxIJvj8jUi6DD9JVXHUEZDRom8XLg+DBzoEqM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c3v8LD3H; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="c3v8LD3H" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B30A81F000C4; Fri, 16 Oct 2026 21:21:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185676; bh=83UvaJHWn9SgCKKxEJYI+y3uxE9NOIxoNSGE/sao7Zw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=c3v8LD3HrjHVw4DPbCBNUS2VBaCgz1aEIh/HfyQZHnGKFADzmOsSZwi1tGWW6i8dL rkpoTdQs95kQIuT4iAc2TxL0115A/iCUFkfoqCd2G+j6ZiYt6l6zQ4ED21xCBrK+xY oXl0SM2f3p+JHCyiLXPyNRz3PzNt2V1XIoFsNs6aN1qLTvZEGdKIrS1RF0qAf5SWon GBM/64aKaAMWCZ6l0aGWXMMoyVoCVyY/4SXnD1RDem8Q0GUOtDhEA3A/8Gdlw4uG6W 9S2O/o0bVIYEPBU0Ri1OEa9XUcWpVnqHickvxJMIhlJsi+l/BE7417LjelD7+tT5Xn jzMGHc0Ftbm8w== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo , Sashiko , stable@vger.kernel.org Subject: [PATCH v4 02/21] perf python: Free the parse error entries when parsing fails Date: Fri, 16 Oct 2026 18:20:43 -0300 Message-ID: <20261016212102.76550-3-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo pyrf__parse_events() prints the entries parse_events_error__print() receives with the details of a failed parse, but returns without freeing them, leaking whatever parse_events_error__handle() allocated, so call parse_events_error__exit() on both paths, as the other parse_events() callers do. The perf test attr core PMU probe takes this failure path on machines without a core PMU, where the leak then happens on every test run. Fixes: f081defccd93 ("perf python: Add parse_events function") Reported-by: Sashiko Closes: https://lore.kernel.org/r/sashiko-outbox-173525@kernel.org Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/util/python.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 4eb17bdc5fd1231a..60dbe2dad5eb8073 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -3824,10 +3824,12 @@ static PyObject *pyrf__parse_events(PyObject *self,= PyObject *args) perf_evlist__set_maps(evlist__core(evlist), cpus, threads); if (parse_events(evlist, input, &err)) { parse_events_error__print(&err, input); + parse_events_error__exit(&err); PyErr_SetFromErrno(PyExc_OSError); evlist__put(evlist); return NULL; } + parse_events_error__exit(&err); result =3D pyrf_evlist__from_evlist(evlist); evlist__put(evlist); return result; --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D14B3E7179; Fri, 16 Oct 2026 21:21:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185681; cv=none; b=NWcozZENXjNh8z9S2CBeafZ6gcVXFOS7tTpiGoAy3FBJmbRz0CRcBiw6RVGX/+xBApe2LK+gan+nrqozsONK7PZ9kDQv698am01fSfd+yzdkSo3mraJ+ooNnmHxIt9kcLdwlyPMM8RjkR0qV3ut5gDLSsY8Yr3OaRJog7scY4BQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185681; c=relaxed/simple; bh=xGB/n90vHnG+ioo5rQMlD23mUdaCxIjk2IyxBgfYqpM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=frYCHw/Xcudm4gKuabzcsN734/OS1KN7i2yEZFEaRDZPbEBq+HYpM3PFHMD0j+4xkGnMyJ3P4pFW57Isg4qysLSmqqw7ppIExtFuln+RyuX+PI9MpbY0MN3boPvjWGAyBrW7mWegjEB82SFNEibNKPTRb4I9zB6v5Zu3/fAX9iY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fAsW+MwF; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fAsW+MwF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 476491F000C7; Fri, 16 Oct 2026 21:21:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185680; bh=vu2dxBhtjOX32mukUGPMQr+WNAc4H6EvEK2F/8Ip1nM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=fAsW+MwFPSFuk0lAqI1uVfbUdVu5Nk5RAN50wl0HXN3RpYAJ86ZDQsMOhUbOeIKpy xNYNoK0agvfvrvawgVZWwmMdc7Ql5z1cSwgMYlI+S7gBx52iB8k+y32/c1EgxDIsEp YruvI2C5sQYI9vfaJA2mrXwQMa9UaPbBJTfxzM+NWSZF7okGz834B4JuFRruu/dr/t MDjRUlL6Wx3JGRjPLdYG4ecPYoQKNfGfit0i2mjskR52g3frPg9bVbwaCNFZmUDGq/ MIefhknPx/3eBIkVfjYnXaKNqIqDvbRc6P9pKpOxgM/4OgQ1diZ4vc8KcJTHgg7sDK PgwF8f5n+DJ0w== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 03/21] perf test attr: Allow tests to require a core PMU Date: Fri, 16 Oct 2026 18:20:44 -0300 Message-ID: <20261016212102.76550-4-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo On machines without a usable core PMU, like an aarch64 box with no DT node for the ARM PMU, the expectations that pin the legacy hardware encoding can't be checked: without a core PMU at all 'cycles' doesn't even resolve, and with one that can't be opened 'perf record' takes the software fallback and records attributes they can never match: expected type=3D0, got 1 expected config=3D0, got 1 FAILED '.../attr/test-record-group-sampling1' - match failure And since attr.py stops at the first failure, every expectation that would come after that one ends up not being run at all. Add a 'requires' limitation, modelled after the existing 'arch', 'auxv' and 'kernel_since/until' ones, with 'core-pmu' as its first value, that is checked by asking perf itself to open 'cycles' via its python binding: a parse failure or an ENOENT means there is no PMU that can count it, hence nothing to check and the test gets skipped, while any other error means we can't tell, so the test keeps running as it does today, where there is no binding to ask either. When there is no core PMU, asking the binding fails and prints a parse error, once for every test that asks, so the answer is kept: it is asked once per run. A value other than 'core-pmu' is warned about, not silently ignored, so a typo can't turn the skip into a no-op. An old distro python package may have a 'perf' module without parse_events(), i.e. there is nothing to ask with, so that AttributeError gets the same treatment as the ImportError: let the expectations speak. The expectations that have a strict 'type=3D0', plus the group tests, where the fallback drops a member and leaves nothing to compare the group leader attributes with, now state that they require a core PMU. They are marked here, before the commit that has the group tests ask for the legacy encodings, so the requisite comes with that dependency. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- .../shell/attr/test-record-group-sampling | 1 + .../shell/attr/test-record-group-sampling1 | 1 + .../shell/attr/test-record-group-sampling2 | 1 + .../perf/tests/shell/attr/test-record-group1 | 1 + .../perf/tests/shell/attr/test-record-group2 | 1 + .../perf/tests/shell/attr/test-record-group3 | 1 + tools/perf/tests/shell/attr/test-stat-C0 | 1 + tools/perf/tests/shell/attr/test-stat-basic | 1 + tools/perf/tests/shell/attr/test-stat-default | 1 + .../tests/shell/attr/test-stat-detailed-1 | 1 + .../tests/shell/attr/test-stat-detailed-2 | 1 + .../tests/shell/attr/test-stat-detailed-3 | 1 + tools/perf/tests/shell/attr/test-stat-group1 | 1 + .../tests/shell/attr/test-stat-no-inherit | 1 + tools/perf/tests/shell/lib/attr.py | 63 +++++++++++++++++++ 15 files changed, 77 insertions(+) diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling b/tools= /perf/tests/shell/attr/test-record-group-sampling index 86a940d7895d7404..b43d9fe3af75c096 100644 --- a/tools/perf/tests/shell/attr/test-record-group-sampling +++ b/tools/perf/tests/shell/attr/test-record-group-sampling @@ -3,6 +3,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>= &1 ret =3D 1 kernel_until =3D 6.12 +requires =3D core-pmu =20 [event-1:base-record] fd=3D1 diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling1 b/tool= s/perf/tests/shell/attr/test-record-group-sampling1 index 4748ab7bf68437c7..3def72161820dca3 100644 --- a/tools/perf/tests/shell/attr/test-record-group-sampling1 +++ b/tools/perf/tests/shell/attr/test-record-group-sampling1 @@ -3,6 +3,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>= &1 ret =3D 1 kernel_since =3D 6.12 +requires =3D core-pmu =20 [event-1:base-record] fd=3D1 diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling2 b/tool= s/perf/tests/shell/attr/test-record-group-sampling2 index e0432244a0eb7f6c..227c18bb221c4b2f 100644 --- a/tools/perf/tests/shell/attr/test-record-group-sampling2 +++ b/tools/perf/tests/shell/attr/test-record-group-sampling2 @@ -3,6 +3,7 @@ command =3D record args =3D --no-bpf-event -c 10000 -e '{cycles,cache-misses}:S' kill >/de= v/null 2>&1 ret =3D 1 kernel_since =3D 6.12 +requires =3D core-pmu =20 [event-1:base-record] fd=3D1 diff --git a/tools/perf/tests/shell/attr/test-record-group1 b/tools/perf/te= sts/shell/attr/test-record-group1 index eeb1db392bc9ceac..a57c7ee8aaa4f9c9 100644 --- a/tools/perf/tests/shell/attr/test-record-group1 +++ b/tools/perf/tests/shell/attr/test-record-group1 @@ -2,6 +2,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles,instructions}' kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 [event-1:base-record] fd=3D1 diff --git a/tools/perf/tests/shell/attr/test-record-group2 b/tools/perf/te= sts/shell/attr/test-record-group2 index 891d41a7bddf785a..fb6e664eeacc10ef 100644 --- a/tools/perf/tests/shell/attr/test-record-group2 +++ b/tools/perf/tests/shell/attr/test-record-group2 @@ -3,6 +3,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles/period=3D1234000/,instructions/peri= od=3D6789000/}:S' kill >/dev/null 2>&1 ret =3D 1 kernel_until =3D 6.12 +requires =3D core-pmu =20 [event-1:base-record] fd=3D1 diff --git a/tools/perf/tests/shell/attr/test-record-group3 b/tools/perf/te= sts/shell/attr/test-record-group3 index 249be884959eaaba..7b90b4411d8f4b90 100644 --- a/tools/perf/tests/shell/attr/test-record-group3 +++ b/tools/perf/tests/shell/attr/test-record-group3 @@ -3,6 +3,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles/period=3D1234000/,instructions/peri= od=3D6789000/}:S' kill >/dev/null 2>&1 ret =3D 1 kernel_since =3D 6.12 +requires =3D core-pmu =20 [event-1:base-record] fd=3D1 diff --git a/tools/perf/tests/shell/attr/test-stat-C0 b/tools/perf/tests/sh= ell/attr/test-stat-C0 index a2c76d10b2bb2a15..9d242e93e3a92009 100644 --- a/tools/perf/tests/shell/attr/test-stat-C0 +++ b/tools/perf/tests/shell/attr/test-stat-C0 @@ -2,6 +2,7 @@ command =3D stat args =3D -e cycles -C 0 kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 [event:base-stat] # events are disabled by default when attached to cpu diff --git a/tools/perf/tests/shell/attr/test-stat-basic b/tools/perf/tests= /shell/attr/test-stat-basic index 69867d049fda926f..277897bd2626a41f 100644 --- a/tools/perf/tests/shell/attr/test-stat-basic +++ b/tools/perf/tests/shell/attr/test-stat-basic @@ -2,6 +2,7 @@ command =3D stat args =3D -e cycles kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 [event:base-stat] optional=3D1 diff --git a/tools/perf/tests/shell/attr/test-stat-default b/tools/perf/tes= ts/shell/attr/test-stat-default index 8dd27c1fb661fb77..74691188e859a169 100644 --- a/tools/perf/tests/shell/attr/test-stat-default +++ b/tools/perf/tests/shell/attr/test-stat-default @@ -2,6 +2,7 @@ command =3D stat args =3D kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK [event1:base-stat] diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-1 b/tools/perf/= tests/shell/attr/test-stat-detailed-1 index 12a2ebf4e64a0077..d9a6236054f2dfb1 100644 --- a/tools/perf/tests/shell/attr/test-stat-detailed-1 +++ b/tools/perf/tests/shell/attr/test-stat-detailed-1 @@ -2,6 +2,7 @@ command =3D stat args =3D -d kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-2 b/tools/perf/= tests/shell/attr/test-stat-detailed-2 index 66ea25b7d38f8d59..582a30289ccfa6df 100644 --- a/tools/perf/tests/shell/attr/test-stat-detailed-2 +++ b/tools/perf/tests/shell/attr/test-stat-detailed-2 @@ -2,6 +2,7 @@ command =3D stat args =3D -dd kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-3 b/tools/perf/= tests/shell/attr/test-stat-detailed-3 index 4a27bbfb9f87a538..2d0fca8b5020f504 100644 --- a/tools/perf/tests/shell/attr/test-stat-detailed-3 +++ b/tools/perf/tests/shell/attr/test-stat-detailed-3 @@ -2,6 +2,7 @@ command =3D stat args =3D -ddd kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK diff --git a/tools/perf/tests/shell/attr/test-stat-group1 b/tools/perf/test= s/shell/attr/test-stat-group1 index 1746751123dcb2c4..3d8b44ba42d6ae19 100644 --- a/tools/perf/tests/shell/attr/test-stat-group1 +++ b/tools/perf/tests/shell/attr/test-stat-group1 @@ -2,6 +2,7 @@ command =3D stat args =3D -e '{cycles,instructions}' kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 [event-1:base-stat] fd=3D1 diff --git a/tools/perf/tests/shell/attr/test-stat-no-inherit b/tools/perf/= tests/shell/attr/test-stat-no-inherit index 924fbb9300d16259..38f746855b1b3e11 100644 --- a/tools/perf/tests/shell/attr/test-stat-no-inherit +++ b/tools/perf/tests/shell/attr/test-stat-no-inherit @@ -2,6 +2,7 @@ command =3D stat args =3D -i -e cycles kill >/dev/null 2>&1 ret =3D 1 +requires =3D core-pmu =20 [event:base-stat] inherit=3D0 diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index 68f06df9565a0811..2d7dd26a5737777c 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 =20 import configparser +import errno import os import sys import glob @@ -28,6 +29,50 @@ def data_equal(a, b): =20 return False =20 +CORE_PMU_AVAILABLE =3D None + +def core_pmu_available(): + """ + Is there a core PMU on this machine? Without one hardware events aren't + supported and get replaced by the software fallback, so there's no way= to + check the expectations that pin their legacy encodings. The answer ca= n't + change while the tests run, so probe the binding only once. + """ + global CORE_PMU_AVAILABLE + + if CORE_PMU_AVAILABLE is None: + CORE_PMU_AVAILABLE =3D core_pmu_probe() + + return CORE_PMU_AVAILABLE + +def core_pmu_probe(): + """ + Ask perf itself, through its python binding, to parse and open 'cycles= ': + a parse failure or an ENOENT means no PMU can count it, any other error + means we can't tell whether there is one. + """ + try: + import perf + parse_events =3D perf.parse_events + except (ImportError, AttributeError): + # Nothing to ask about it, let the expectations speak. + return True + + try: + evlist =3D parse_events('cycles') + except OSError: + # No PMU that can count it, the same as the ENOENT below. + return False + + try: + evlist.open() + except OSError as err: + # Anything else is a permission problem or alike, not our business= here. + return err.errno !=3D errno.ENOENT + evlist.close() + + return True + class Fail(Exception): def __init__(self, test, msg): self.msg =3D msg @@ -138,6 +183,9 @@ def parse_version(version): # 'arch' - architecture specific test (optional) # comma separated list, ! at the beginning # negates it. +# 'requires' - Comma separated list of things the test needs, it is +# skipped when any of them isn't there, currently: +# core-pmu - the machine can count hardware events. # 'auxv' - Truthy statement that is evaled in the scope of the auxv= map. When false, # the test is skipped. For example 'auxv["AT_HWCAP"] =3D= =3D 10'. (optional) # 'kernel_since' - Inclusive kernel version from which the test will s= tart running. Only the @@ -173,6 +221,7 @@ class Test(object): self.arch =3D '' =20 self.auxv =3D parser.get('config', 'auxv', fallback=3DNone) + self.requires =3D parser.get('config', 'requires', fallback=3D'') self.kernel_since =3D parse_version(parser.get('config', 'kernel_s= ince', fallback=3DNone)) self.kernel_until =3D parse_version(parser.get('config', 'kernel_u= ntil', fallback=3DNone)) self.expect =3D {} @@ -242,6 +291,17 @@ class Test(object): return False return True =20 + def skip_test_requires(self): + for requirement in filter(None, map(str.strip, self.requires.split= (','))): + if requirement =3D=3D 'core-pmu': + if not core_pmu_available(): + log.warning("test limitation 'requires %s'", requireme= nt) + return True + else: + log.warning("unknown requirement '%s', ignored", requireme= nt) + + return False + def restore_sample_rate(self, value=3D10000): try: # Check value of sample_rate @@ -296,6 +356,9 @@ class Test(object): if self.skip_test_kernel_until(): raise Notest(self, "new kernel skip") =20 + if self.skip_test_requires(): + raise Notest(self, "requirements skip") + self.restore_sample_rate() cmd =3D "PERF_TEST_ATTR=3D%s %s %s -o %s/perf.data %s" % (tempdir, self.perf, self.command, tempdir, self.args) --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7C40447240; Fri, 16 Oct 2026 21:21:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185685; cv=none; b=UAvskv4lDD4LflrulIJR7t0+5vbX7EYlIgMWKMsfv3Yeb24wymepf5pXgUV9fUF7gFNWORMLGLXm96lk+UoFuGIL8nAaQwM7trUdAPRMJ1aH4OshDsW+PpqrehB+F54MJX1/drKVotZ8H0m+7wuDwZtYc8PfM0U+eB4mafRaPTE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185685; c=relaxed/simple; bh=c0Wc6C+H0sLY5GZTZ0RUO+0ZzwlvinqvM5m6XvDNFrY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=G2RmbP+YNkGFFDTLLlTKaHDxMU7lYia0YHJ8DOB2DiKpZ5CVLZAihwpFrZZ9GhtEXI/ZLezZ1EWfV5r9XejflX0OfP4z4z9E86PF7Ng49bHNf8qfUx9XBaAvjbPRy7xTseIh1lH1nw9tbDAaqa/pjaqNqrGX/CB0xM4a8RsvN5E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=okyuR7ad; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="okyuR7ad" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 714741F000C4; Fri, 16 Oct 2026 21:21:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185683; bh=vMYYLi56bfKOjPdfh16BHCEItjVED7x3a04Vd3ap6kc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=okyuR7adqbYZfJSW7URr5PAOAI5FS1TSVdcAHQJIutPxDvQJhClQPmWkgp6vjGAgi LJo4X165QEQ2ocyOHp/UDQm3DvCjkLjYlJehlmKGHkoxboQShejZuav7C8/r1Bj7MU kYASUmN5vFFf5wBr8z0SCfwAJmFyBwMaTouB3Ti0D3N2BFx3FpjmLMVKc91IaOL+M+ Dl9oR7x6rSE+V3pKxFzkje7eERrHewjDpBffJ5/qRqaNUN3lBaHIVYDvSQhrmgCSfX ZJ/2NPMQqSmA7Mj62dyGy2ANNGhtIAAsCadgQpR4tryUF3jo3cSpXV17aF0fPxFv1b y9/H2ZcRv5eBQ== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 04/21] perf test attr: Fix legacy event encodings in group tests Date: Fri, 16 Oct 2026 18:20:45 -0300 Message-ID: <20261016212102.76550-5-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Since commit b1c5efbfd92e ("perf parse-events: Remove hard coded legacy hardware and cache parsing"), event names are resolved with sysfs/JSON priority over the legacy encodings, so bare cache-misses and instructions now become the core PMU sysfs/JSON events (on x86 type 4, configs 0x412e and 0xc0) rather than the legacy PERF_TYPE_HARDWARE/config=3D3 and config=3D1 events the tests expect, e.g.: expected config=3D3, got 0 expected disabled=3D0, got 1 expected mmap=3D0, got 1 expected comm=3D0, got 1 expected freq=3D0, got 1 expected enable_on_exec=3D0, got 1 expected task=3D0, got 1 FAILED '.../test-record-group-sampling1' - match failure The shown diff is against the cycles group leader, as no result event matches the expected cache-misses member anymore. Request the legacy encodings explicitly with the legacy-hardware-config term, added in commit 0012e0fa221bf9cc ("perf jevents: Add legacy-hardware and legacy-cache json"), keeping the original attribute expectations unchanged, in: test-record-group1 test-record-group2 test-record-group3 test-record-group-sampling test-record-group-sampling1 test-record-group-sampling2 test-stat-group1 This went unnoticed until tests/attr.sh stopped ignoring attr.py's return value. Fixes: b1c5efbfd92eb84d ("perf parse-events: Remove hard coded legacy hardw= are and cache parsing") Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/attr/README | 10 +++++----- tools/perf/tests/shell/attr/test-record-group-sampling | 4 ++-- .../perf/tests/shell/attr/test-record-group-sampling1 | 4 ++-- .../perf/tests/shell/attr/test-record-group-sampling2 | 4 ++-- tools/perf/tests/shell/attr/test-record-group1 | 2 +- tools/perf/tests/shell/attr/test-record-group2 | 2 +- tools/perf/tests/shell/attr/test-record-group3 | 2 +- tools/perf/tests/shell/attr/test-stat-group1 | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/perf/tests/shell/attr/README b/tools/perf/tests/shell/at= tr/README index 67c4ca76b85d5611..c7b49cdf87297177 100644 --- a/tools/perf/tests/shell/attr/README +++ b/tools/perf/tests/shell/attr/README @@ -49,10 +49,10 @@ Following tests are defined (with perf commands): perf record --call-graph dwarf kill (test-record-graph-dwarf) perf record --call-graph fp kill (test-record-graph-fp) perf record --call-graph fp kill (test-record-graph-fp-aarc= h64) - perf record -e '{cycles,instructions}' kill (test-record-group1) - perf record -e '{cycles/period=3D1/,instructions/period=3D2/}:S' kill (t= est-record-group2) - perf record -e '{cycles,cache-misses}:S' kill (test-record-group-samplin= g1) - perf record -c 10000 -e '{cycles,cache-misses}:S' kill (test-record-grou= p-sampling2) + perf record -e '{cycles,default_core/legacy-hardware-config=3D1/}' kill = (test-record-group1) + perf record -e '{cycles/period=3D1234000/,default_core/legacy-hardware-c= onfig=3D1,period=3D6789000/}:S' kill (test-record-group2) + perf record -e '{cycles,default_core/legacy-hardware-config=3D3/}:S' kil= l (test-record-group-sampling1) + perf record -c 10000 -e '{cycles,default_core/legacy-hardware-config=3D3= /}:S' kill (test-record-group-sampling2) perf record -D kill (test-record-no-delay) perf record -i kill (test-record-no-inherit) perf record -n kill (test-record-no-samples) @@ -67,5 +67,5 @@ Following tests are defined (with perf commands): perf stat -d kill (test-stat-detailed-1) perf stat -dd kill (test-stat-detailed-2) perf stat -ddd kill (test-stat-detailed-3) - perf stat -e '{cycles,instructions}' kill (test-stat-group1) + perf stat -e '{cycles,default_core/legacy-hardware-config=3D1/}' kill (t= est-stat-group1) perf stat -i -e cycles kill (test-stat-no-inherit) diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling b/tools= /perf/tests/shell/attr/test-record-group-sampling index b43d9fe3af75c096..ed47dd1e5984535b 100644 --- a/tools/perf/tests/shell/attr/test-record-group-sampling +++ b/tools/perf/tests/shell/attr/test-record-group-sampling @@ -1,6 +1,6 @@ [config] command =3D record -args =3D --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>= &1 +args =3D --no-bpf-event -e '{cycles,default_core/legacy-hardware-config= =3D3/}:S' kill >/dev/null 2>&1 ret =3D 1 kernel_until =3D 6.12 requires =3D core-pmu @@ -16,7 +16,7 @@ inherit=3D0 fd=3D2 group_fd=3D1 =20 -# cache-misses +# cache-misses, explicitly requested with the legacy hardware encoding type=3D0 config=3D3 =20 diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling1 b/tool= s/perf/tests/shell/attr/test-record-group-sampling1 index 3def72161820dca3..9cf013dc03dd0309 100644 --- a/tools/perf/tests/shell/attr/test-record-group-sampling1 +++ b/tools/perf/tests/shell/attr/test-record-group-sampling1 @@ -1,6 +1,6 @@ [config] command =3D record -args =3D --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>= &1 +args =3D --no-bpf-event -e '{cycles,default_core/legacy-hardware-config= =3D3/}:S' kill >/dev/null 2>&1 ret =3D 1 kernel_since =3D 6.12 requires =3D core-pmu @@ -31,7 +31,7 @@ inherit=3D1 fd=3D2 group_fd=3D1 =20 -# cache-misses +# cache-misses, explicitly requested with the legacy hardware encoding type=3D0 config=3D3 =20 diff --git a/tools/perf/tests/shell/attr/test-record-group-sampling2 b/tool= s/perf/tests/shell/attr/test-record-group-sampling2 index 227c18bb221c4b2f..bd1eb4161e4aee46 100644 --- a/tools/perf/tests/shell/attr/test-record-group-sampling2 +++ b/tools/perf/tests/shell/attr/test-record-group-sampling2 @@ -1,6 +1,6 @@ [config] command =3D record -args =3D --no-bpf-event -c 10000 -e '{cycles,cache-misses}:S' kill >/de= v/null 2>&1 +args =3D --no-bpf-event -c 10000 -e '{cycles,default_core/legacy-hardwa= re-config=3D3/}:S' kill >/dev/null 2>&1 ret =3D 1 kernel_since =3D 6.12 requires =3D core-pmu @@ -37,7 +37,7 @@ write_backward=3D0 fd=3D2 group_fd=3D1 =20 -# cache-misses +# cache-misses, explicitly requested with the legacy hardware encoding type=3D0 config=3D3 =20 diff --git a/tools/perf/tests/shell/attr/test-record-group1 b/tools/perf/te= sts/shell/attr/test-record-group1 index a57c7ee8aaa4f9c9..5fdd5288555f32ea 100644 --- a/tools/perf/tests/shell/attr/test-record-group1 +++ b/tools/perf/tests/shell/attr/test-record-group1 @@ -1,6 +1,6 @@ [config] command =3D record -args =3D --no-bpf-event -e '{cycles,instructions}' kill >/dev/null 2>&1 +args =3D --no-bpf-event -e '{cycles,default_core/legacy-hardware-config= =3D1/}' kill >/dev/null 2>&1 ret =3D 1 requires =3D core-pmu =20 diff --git a/tools/perf/tests/shell/attr/test-record-group2 b/tools/perf/te= sts/shell/attr/test-record-group2 index fb6e664eeacc10ef..e7274108f5fd7e7b 100644 --- a/tools/perf/tests/shell/attr/test-record-group2 +++ b/tools/perf/tests/shell/attr/test-record-group2 @@ -1,6 +1,6 @@ [config] command =3D record -args =3D --no-bpf-event -e '{cycles/period=3D1234000/,instructions/peri= od=3D6789000/}:S' kill >/dev/null 2>&1 +args =3D --no-bpf-event -e '{cycles/period=3D1234000/,default_core/lega= cy-hardware-config=3D1,period=3D6789000/}:S' kill >/dev/null 2>&1 ret =3D 1 kernel_until =3D 6.12 requires =3D core-pmu diff --git a/tools/perf/tests/shell/attr/test-record-group3 b/tools/perf/te= sts/shell/attr/test-record-group3 index 7b90b4411d8f4b90..e74fd3a48ac9094f 100644 --- a/tools/perf/tests/shell/attr/test-record-group3 +++ b/tools/perf/tests/shell/attr/test-record-group3 @@ -1,6 +1,6 @@ [config] command =3D record -args =3D --no-bpf-event -e '{cycles/period=3D1234000/,instructions/peri= od=3D6789000/}:S' kill >/dev/null 2>&1 +args =3D --no-bpf-event -e '{cycles/period=3D1234000/,default_core/lega= cy-hardware-config=3D1,period=3D6789000/}:S' kill >/dev/null 2>&1 ret =3D 1 kernel_since =3D 6.12 requires =3D core-pmu diff --git a/tools/perf/tests/shell/attr/test-stat-group1 b/tools/perf/test= s/shell/attr/test-stat-group1 index 3d8b44ba42d6ae19..7a31b27933f11959 100644 --- a/tools/perf/tests/shell/attr/test-stat-group1 +++ b/tools/perf/tests/shell/attr/test-stat-group1 @@ -1,6 +1,6 @@ [config] command =3D stat -args =3D -e '{cycles,instructions}' kill >/dev/null 2>&1 +args =3D -e '{cycles,default_core/legacy-hardware-config=3D1/}' kill >/= dev/null 2>&1 ret =3D 1 requires =3D core-pmu =20 --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A318D418A5D; Fri, 16 Oct 2026 21:21:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185689; cv=none; b=PgjmXDOuuxle2qVGSyZ7sGYBNokA4FA6J+SNG0w3s133+NF7grNw9AeC/3tFbQ56d1zTDcE934ShFP2JooVMjWqHBvO5cydLmr+h4Dl3Xn+GOlgPng8ec3QPDJDaN9J69FitJCyrsf0l5x8ZisFe6jVkSX3irBRpuYLLLticztg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185689; c=relaxed/simple; bh=mlAKoqAp47ElnH31vfykevsPzubHUuT2atLPg+Msfyc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=odBswOosuPR2fe1UE+HT39EpvUBQHHevL6JsughNWYBJ8Pei/QZEP+dWvfkdcxysF6n0El7VUxVPJ3SdF3V9zlazv/TFvh/Z88et3PFugbazDydbWQ8RpV9ezbHA2wNtyRK/JSCfuRZYU051cUjpwvTyjkEUuzjgDu4R2EhIPw8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fqKxhghC; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fqKxhghC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D3061F000C6; Fri, 16 Oct 2026 21:21:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185686; bh=G2bRHw/WsY7tZExKOOh+6/MPF3Mg3H1POOxEkYjx+zw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=fqKxhghCR1OCyQ2fHQ9Dl1ofzeJuWLhTvf8BY8A9pKrVQ4jJfFlHmkD3u7Gvg9+hf Gnurc0A0ePT4jt9JBZpdOo5Zo2rluwKYZVildW8WPCFS4a608HmSF0QtvMMS5PrQus nogUO80tWRtRF8cPFGVC5QdsQurzvsm6wnHvvHoJ/qFXEAjhbxIvFZAQsGPOpYefB6 KFAsCpoc7nMxtcFxbcV2SXxwjjAqokgFVbLHdygerM/gqjZbw9oD/WDdi7J2UmJ7+5 Tt6DSJdGMJeugx0fWCHnnjq5yYsgZ2/XiRmjR20y0miHRsnbx35LcV+6E/7ogIrU0h fpPzVnhnq8ksw== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 05/21] perf test attr: Fix default stat metrics expectations Date: Fri, 16 Oct 2026 18:20:46 -0300 Message-ID: <20261016212102.76550-6-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Since commit c7adeb0974f1 ("perf jevents: Add set of common metrics based on default ones") and commit 2dfc0cab3da4 ("perf stat: Add detail -d,-dd,-d= dd metrics") the perf stat default metrics open their events in groups, so group leaders and members have read_format=3D15 and members are enabled without enable_on_exec, while standalone events keep read_format=3D3 and are disabled until exec. Also, since commit b1c5efbfd92e ("perf parse-events: Remove hard coded legacy hardware and cache parsing") bare hardware events resolve to the core PMU sysfs/JSON events (type 4), so add the raw encodings the Intel and AMD core PMUs use for instructions, branch-misses, cpu-cycles and stalled-cycles-frontend/backend to test-stat-default and test-stat-detailed-1/2/3. Add base-stat-group, that accepts both the standalone and the group variants of read_format, disabled and enable_on_exec, and point the four default/detailed expectations at it. test-stat-basic, test-stat-C0 and test-stat-no-inherit keep base-stat, whose events aren't opened in a group: for those, a change that groups or enables them differently is still something to catch. test-stat-group1 does open its events in a group, but pins read_format, disabled and enable_on_exec itself, the very terms base-stat-group loosens, so it doesn't need it either. Fixes: b1c5efbfd92eb84d ("perf parse-events: Remove hard coded legacy hardw= are and cache parsing") Fixes: c7adeb0974f18da4 ("perf jevents: Add set of common metrics based on = default ones") Fixes: 2dfc0cab3da4a205 ("perf stat: Add detail -d,-dd,-ddd metrics") Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/attr/base-stat-group | 45 +++++++ tools/perf/tests/shell/attr/test-stat-default | 90 +++++++++----- .../tests/shell/attr/test-stat-detailed-1 | 98 +++++++++------ .../tests/shell/attr/test-stat-detailed-2 | 110 ++++++++++------- .../tests/shell/attr/test-stat-detailed-3 | 114 +++++++++++------- 5 files changed, 307 insertions(+), 150 deletions(-) create mode 100644 tools/perf/tests/shell/attr/base-stat-group diff --git a/tools/perf/tests/shell/attr/base-stat-group b/tools/perf/tests= /shell/attr/base-stat-group new file mode 100644 index 0000000000000000..9bcb8ab3687ff9fb --- /dev/null +++ b/tools/perf/tests/shell/attr/base-stat-group @@ -0,0 +1,45 @@ +[event] +fd=3D1 +group_fd=3D-1 +# 0 or PERF_FLAG_FD_CLOEXEC flag +flags=3D0|8 +cpu=3D* +type=3D0 +size=3D176 +config=3D0 +sample_period=3D0 +sample_type=3D65536 +# The default and -d/-dd/-ddd metrics open part of their events in groups: +# the members get read_format=3D15 and are enabled right away, the standal= one +# ones keep read_format=3D3 and wait for the exec, and the leaders get 15 = when +# their group has members, 3 when alone, as create_perf_stat_counter() goe= s. +read_format=3D3|15 +disabled=3D0|1 +inherit=3D1 +pinned=3D0 +exclusive=3D0 +exclude_user=3D0 +exclude_kernel=3D0|1 +exclude_hv=3D0|1 +exclude_idle=3D0 +mmap=3D0 +comm=3D0 +freq=3D0 +inherit_stat=3D0 +enable_on_exec=3D0|1 +task=3D0 +watermark=3D0 +precise_ip=3D0 +mmap_data=3D0 +sample_id_all=3D0 +exclude_host=3D0|1 +exclude_guest=3D0|1 +exclude_callchain_kernel=3D0 +exclude_callchain_user=3D0 +wakeup_events=3D0 +bp_type=3D0 +config1=3D0 +config2=3D0 +branch_sample_type=3D0 +sample_regs_user=3D0 +sample_stack_user=3D0 diff --git a/tools/perf/tests/shell/attr/test-stat-default b/tools/perf/tes= ts/shell/attr/test-stat-default index 74691188e859a169..6a0c0c43f23347d8 100644 --- a/tools/perf/tests/shell/attr/test-stat-default +++ b/tools/perf/tests/shell/attr/test-stat-default @@ -5,72 +5,72 @@ ret =3D 1 requires =3D core-pmu =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK -[event1:base-stat] +[event1:base-stat-group] fd=3D1 type=3D1 config=3D1 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES -[event2:base-stat] +[event2:base-stat-group] fd=3D2 type=3D1 config=3D3 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS -[event3:base-stat] +[event3:base-stat-group] fd=3D3 type=3D1 config=3D4 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS -[event4:base-stat] +[event4:base-stat-group] fd=3D4 type=3D1 config=3D2 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES -[event5:base-stat] +[event5:base-stat-group] fd=3D5 type=3D0 config=3D0 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND -[event6:base-stat] +[event6:base-stat-group] fd=3D6 type=3D0 config=3D7 optional=3D1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND -[event7:base-stat] +[event7:base-stat-group] fd=3D7 type=3D0 config=3D8 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS -[event8:base-stat] +[event8:base-stat-group] fd=3D8 type=3D0 config=3D1 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS -[event9:base-stat] +[event9:base-stat-group] fd=3D9 type=3D0 config=3D4 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES -[event10:base-stat] +[event10:base-stat-group] fd=3D10 type=3D0 config=3D5 optional=3D1 =20 # PERF_TYPE_RAW / slots (0x400) -[event11:base-stat] +[event11:base-stat-group] fd=3D11 group_fd=3D-1 type=3D4 @@ -79,7 +79,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-retiring (0x8000) -[event12:base-stat] +[event12:base-stat-group] fd=3D12 group_fd=3D11 type=3D4 @@ -90,7 +90,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-bad-spec (0x8100) -[event13:base-stat] +[event13:base-stat-group] fd=3D13 group_fd=3D11 type=3D4 @@ -101,7 +101,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fe-bound (0x8200) -[event14:base-stat] +[event14:base-stat-group] fd=3D14 group_fd=3D11 type=3D4 @@ -112,7 +112,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-be-bound (0x8300) -[event15:base-stat] +[event15:base-stat-group] fd=3D15 group_fd=3D11 type=3D4 @@ -123,7 +123,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-heavy-ops (0x8400) -[event16:base-stat] +[event16:base-stat-group] fd=3D16 group_fd=3D11 type=3D4 @@ -134,7 +134,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-br-mispredict (0x8500) -[event17:base-stat] +[event17:base-stat-group] fd=3D17 group_fd=3D11 type=3D4 @@ -145,7 +145,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fetch-lat (0x8600) -[event18:base-stat] +[event18:base-stat-group] fd=3D18 group_fd=3D11 type=3D4 @@ -156,7 +156,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-mem-bound (0x8700) -[event19:base-stat] +[event19:base-stat-group] fd=3D19 group_fd=3D11 type=3D4 @@ -167,71 +167,99 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event20:base-stat] +[event20:base-stat-group] fd=3D20 type=3D4 config=3D4109 optional=3D1 =20 # PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=3D1,edge/ -[event21:base-stat] +[event21:base-stat-group] fd=3D21 type=3D4 config=3D17039629 optional=3D1 =20 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD -[event22:base-stat] +# PERF_TYPE_RAW / cpu-cycles (core PMU sysfs event; Intel 0x3c, AMD 0x76) +[event22:base-stat-group] fd=3D22 type=3D4 -config=3D60 +config=3D60|118 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY -[event23:base-stat] +[event23:base-stat-group] fd=3D23 type=3D4 config=3D2097421 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK -[event24:base-stat] +[event24:base-stat-group] fd=3D24 type=3D4 config=3D316 optional=3D1 =20 # PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE -[event25:base-stat] +[event25:base-stat-group] fd=3D25 type=3D4 config=3D412 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE -[event26:base-stat] +[event26:base-stat-group] fd=3D26 type=3D4 config=3D572 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS -[event27:base-stat] +[event27:base-stat-group] fd=3D27 type=3D4 config=3D706 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_ISSUED.ANY -[event28:base-stat] +[event28:base-stat-group] fd=3D28 type=3D4 config=3D270 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event29:base-stat] +[event29:base-stat-group] fd=3D29 type=3D4 config=3D4269 +optional=3D1 + +# PERF_TYPE_RAW / instructions (core PMU sysfs event) +[event30:base-stat-group] +fd=3D30 +type=3D4 +config=3D192 +optional=3D1 + +# PERF_TYPE_RAW / branch-misses (core PMU sysfs event; Intel 0xc5, AMD 0xc= 3) +[event31:base-stat-group] +fd=3D31 +type=3D4 +config=3D197|195 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-frontend (core PMU sysfs event; Intel 0x1= 80010e, AMD 0xd0/0x287/0xa9) +[event32:base-stat-group] +fd=3D32 +type=3D4 +config=3D25166094|208|647|169 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-backend (core PMU sysfs event; Intel 0x18= 001b1/0x1803fb1, AMD 0xd1/0x187) +[event33:base-stat-group] +fd=3D33 +type=3D4 +config=3D25166257|25182129|209|391 optional=3D1 \ No newline at end of file diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-1 b/tools/perf/= tests/shell/attr/test-stat-detailed-1 index d9a6236054f2dfb1..3d47dc6f815ff0a6 100644 --- a/tools/perf/tests/shell/attr/test-stat-detailed-1 +++ b/tools/perf/tests/shell/attr/test-stat-detailed-1 @@ -6,73 +6,73 @@ requires =3D core-pmu =20 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK -[event1:base-stat] +[event1:base-stat-group] fd=3D1 type=3D1 config=3D1 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES -[event2:base-stat] +[event2:base-stat-group] fd=3D2 type=3D1 config=3D3 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS -[event3:base-stat] +[event3:base-stat-group] fd=3D3 type=3D1 config=3D4 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS -[event4:base-stat] +[event4:base-stat-group] fd=3D4 type=3D1 config=3D2 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES -[event5:base-stat] +[event5:base-stat-group] fd=3D5 type=3D0 config=3D0 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND -[event6:base-stat] +[event6:base-stat-group] fd=3D6 type=3D0 config=3D7 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND -[event7:base-stat] +[event7:base-stat-group] fd=3D7 type=3D0 config=3D8 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS -[event8:base-stat] +[event8:base-stat-group] fd=3D8 type=3D0 config=3D1 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS -[event9:base-stat] +[event9:base-stat-group] fd=3D9 type=3D0 config=3D4 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES -[event10:base-stat] +[event10:base-stat-group] fd=3D10 type=3D0 config=3D5 optional=3D1 =20 # PERF_TYPE_RAW / slots (0x400) -[event11:base-stat] +[event11:base-stat-group] fd=3D11 group_fd=3D-1 type=3D4 @@ -81,7 +81,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-retiring (0x8000) -[event12:base-stat] +[event12:base-stat-group] fd=3D12 group_fd=3D11 type=3D4 @@ -92,7 +92,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-bad-spec (0x8100) -[event13:base-stat] +[event13:base-stat-group] fd=3D13 group_fd=3D11 type=3D4 @@ -103,7 +103,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fe-bound (0x8200) -[event14:base-stat] +[event14:base-stat-group] fd=3D14 group_fd=3D11 type=3D4 @@ -114,7 +114,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-be-bound (0x8300) -[event15:base-stat] +[event15:base-stat-group] fd=3D15 group_fd=3D11 type=3D4 @@ -125,7 +125,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-heavy-ops (0x8400) -[event16:base-stat] +[event16:base-stat-group] fd=3D16 group_fd=3D11 type=3D4 @@ -136,7 +136,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-br-mispredict (0x8500) -[event17:base-stat] +[event17:base-stat-group] fd=3D17 group_fd=3D11 type=3D4 @@ -147,7 +147,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fetch-lat (0x8600) -[event18:base-stat] +[event18:base-stat-group] fd=3D18 group_fd=3D11 type=3D4 @@ -158,7 +158,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-mem-bound (0x8700) -[event19:base-stat] +[event19:base-stat-group] fd=3D19 group_fd=3D11 type=3D4 @@ -169,63 +169,63 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event20:base-stat] +[event20:base-stat-group] fd=3D20 type=3D4 config=3D4109 optional=3D1 =20 # PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=3D1,edge/ -[event21:base-stat] +[event21:base-stat-group] fd=3D21 type=3D4 config=3D17039629 optional=3D1 =20 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD -[event22:base-stat] +# PERF_TYPE_RAW / cpu-cycles (core PMU sysfs event; Intel 0x3c, AMD 0x76) +[event22:base-stat-group] fd=3D22 type=3D4 -config=3D60 +config=3D60|118 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY -[event23:base-stat] +[event23:base-stat-group] fd=3D23 type=3D4 config=3D2097421 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK -[event24:base-stat] +[event24:base-stat-group] fd=3D24 type=3D4 config=3D316 optional=3D1 =20 # PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE -[event25:base-stat] +[event25:base-stat-group] fd=3D25 type=3D4 config=3D412 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE -[event26:base-stat] +[event26:base-stat-group] fd=3D26 type=3D4 config=3D572 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS -[event27:base-stat] +[event27:base-stat-group] fd=3D27 type=3D4 config=3D706 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_ISSUED.ANY -[event28:base-stat] +[event28:base-stat-group] fd=3D28 type=3D4 config=3D270 @@ -235,7 +235,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event29:base-stat] +[event29:base-stat-group] fd=3D29 type=3D3 config=3D0 @@ -245,7 +245,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event30:base-stat] +[event30:base-stat-group] fd=3D30 type=3D3 config=3D65536 @@ -255,7 +255,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_LL << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event31:base-stat] +[event31:base-stat-group] fd=3D31 type=3D3 config=3D2 @@ -265,15 +265,43 @@ optional=3D1 # PERF_COUNT_HW_CACHE_LL << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event32:base-stat] +[event32:base-stat-group] fd=3D32 type=3D3 config=3D65538 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event33:base-stat] +[event33:base-stat-group] fd=3D33 type=3D4 config=3D4269 +optional=3D1 + +# PERF_TYPE_RAW / instructions (core PMU sysfs event) +[event34:base-stat-group] +fd=3D34 +type=3D4 +config=3D192 +optional=3D1 + +# PERF_TYPE_RAW / branch-misses (core PMU sysfs event; Intel 0xc5, AMD 0xc= 3) +[event35:base-stat-group] +fd=3D35 +type=3D4 +config=3D197|195 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-frontend (core PMU sysfs event; Intel 0x1= 80010e, AMD 0xd0/0x287/0xa9) +[event36:base-stat-group] +fd=3D36 +type=3D4 +config=3D25166094|208|647|169 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-backend (core PMU sysfs event; Intel 0x18= 001b1/0x1803fb1, AMD 0xd1/0x187) +[event37:base-stat-group] +fd=3D37 +type=3D4 +config=3D25166257|25182129|209|391 optional=3D1 \ No newline at end of file diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-2 b/tools/perf/= tests/shell/attr/test-stat-detailed-2 index 582a30289ccfa6df..ebe1f9e2736ddd68 100644 --- a/tools/perf/tests/shell/attr/test-stat-detailed-2 +++ b/tools/perf/tests/shell/attr/test-stat-detailed-2 @@ -6,73 +6,73 @@ requires =3D core-pmu =20 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK -[event1:base-stat] +[event1:base-stat-group] fd=3D1 type=3D1 config=3D1 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES -[event2:base-stat] +[event2:base-stat-group] fd=3D2 type=3D1 config=3D3 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS -[event3:base-stat] +[event3:base-stat-group] fd=3D3 type=3D1 config=3D4 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS -[event4:base-stat] +[event4:base-stat-group] fd=3D4 type=3D1 config=3D2 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES -[event5:base-stat] +[event5:base-stat-group] fd=3D5 type=3D0 config=3D0 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND -[event6:base-stat] +[event6:base-stat-group] fd=3D6 type=3D0 config=3D7 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND -[event7:base-stat] +[event7:base-stat-group] fd=3D7 type=3D0 config=3D8 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS -[event8:base-stat] +[event8:base-stat-group] fd=3D8 type=3D0 config=3D1 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS -[event9:base-stat] +[event9:base-stat-group] fd=3D9 type=3D0 config=3D4 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES -[event10:base-stat] +[event10:base-stat-group] fd=3D10 type=3D0 config=3D5 optional=3D1 =20 # PERF_TYPE_RAW / slots (0x400) -[event11:base-stat] +[event11:base-stat-group] fd=3D11 group_fd=3D-1 type=3D4 @@ -81,7 +81,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-retiring (0x8000) -[event12:base-stat] +[event12:base-stat-group] fd=3D12 group_fd=3D11 type=3D4 @@ -92,7 +92,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-bad-spec (0x8100) -[event13:base-stat] +[event13:base-stat-group] fd=3D13 group_fd=3D11 type=3D4 @@ -103,7 +103,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fe-bound (0x8200) -[event14:base-stat] +[event14:base-stat-group] fd=3D14 group_fd=3D11 type=3D4 @@ -114,7 +114,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-be-bound (0x8300) -[event15:base-stat] +[event15:base-stat-group] fd=3D15 group_fd=3D11 type=3D4 @@ -125,7 +125,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-heavy-ops (0x8400) -[event16:base-stat] +[event16:base-stat-group] fd=3D16 group_fd=3D11 type=3D4 @@ -136,7 +136,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-br-mispredict (0x8500) -[event17:base-stat] +[event17:base-stat-group] fd=3D17 group_fd=3D11 type=3D4 @@ -147,7 +147,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fetch-lat (0x8600) -[event18:base-stat] +[event18:base-stat-group] fd=3D18 group_fd=3D11 type=3D4 @@ -158,7 +158,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-mem-bound (0x8700) -[event19:base-stat] +[event19:base-stat-group] fd=3D19 group_fd=3D11 type=3D4 @@ -169,63 +169,63 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event20:base-stat] +[event20:base-stat-group] fd=3D20 type=3D4 config=3D4109 optional=3D1 =20 # PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=3D1,edge/ -[event21:base-stat] +[event21:base-stat-group] fd=3D21 type=3D4 config=3D17039629 optional=3D1 =20 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD -[event22:base-stat] +# PERF_TYPE_RAW / cpu-cycles (core PMU sysfs event; Intel 0x3c, AMD 0x76) +[event22:base-stat-group] fd=3D22 type=3D4 -config=3D60 +config=3D60|118 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY -[event23:base-stat] +[event23:base-stat-group] fd=3D23 type=3D4 config=3D2097421 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK -[event24:base-stat] +[event24:base-stat-group] fd=3D24 type=3D4 config=3D316 optional=3D1 =20 # PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE -[event25:base-stat] +[event25:base-stat-group] fd=3D25 type=3D4 config=3D412 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE -[event26:base-stat] +[event26:base-stat-group] fd=3D26 type=3D4 config=3D572 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS -[event27:base-stat] +[event27:base-stat-group] fd=3D27 type=3D4 config=3D706 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_ISSUED.ANY -[event28:base-stat] +[event28:base-stat-group] fd=3D28 type=3D4 config=3D270 @@ -235,7 +235,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event29:base-stat] +[event29:base-stat-group] fd=3D29 type=3D3 config=3D0 @@ -245,7 +245,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event30:base-stat] +[event30:base-stat-group] fd=3D30 type=3D3 config=3D65536 @@ -255,7 +255,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_LL << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event31:base-stat] +[event31:base-stat-group] fd=3D31 type=3D3 config=3D2 @@ -265,7 +265,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_LL << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event32:base-stat] +[event32:base-stat-group] fd=3D32 type=3D3 config=3D65538 @@ -275,7 +275,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1I << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event33:base-stat] +[event33:base-stat-group] fd=3D33 type=3D3 config=3D1 @@ -285,7 +285,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1I << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event34:base-stat] +[event34:base-stat-group] fd=3D34 type=3D3 config=3D65537 @@ -295,7 +295,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_DTLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event35:base-stat] +[event35:base-stat-group] fd=3D35 type=3D3 config=3D3 @@ -305,7 +305,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_DTLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event36:base-stat] +[event36:base-stat-group] fd=3D36 type=3D3 config=3D65539 @@ -315,7 +315,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_ITLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event37:base-stat] +[event37:base-stat-group] fd=3D37 type=3D3 config=3D4 @@ -325,15 +325,43 @@ optional=3D1 # PERF_COUNT_HW_CACHE_ITLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event38:base-stat] +[event38:base-stat-group] fd=3D38 type=3D3 config=3D65540 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event39:base-stat] +[event39:base-stat-group] fd=3D39 type=3D4 config=3D4269 +optional=3D1 + +# PERF_TYPE_RAW / instructions (core PMU sysfs event) +[event40:base-stat-group] +fd=3D40 +type=3D4 +config=3D192 +optional=3D1 + +# PERF_TYPE_RAW / branch-misses (core PMU sysfs event; Intel 0xc5, AMD 0xc= 3) +[event41:base-stat-group] +fd=3D41 +type=3D4 +config=3D197|195 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-frontend (core PMU sysfs event; Intel 0x1= 80010e, AMD 0xd0/0x287/0xa9) +[event42:base-stat-group] +fd=3D42 +type=3D4 +config=3D25166094|208|647|169 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-backend (core PMU sysfs event; Intel 0x18= 001b1/0x1803fb1, AMD 0xd1/0x187) +[event43:base-stat-group] +fd=3D43 +type=3D4 +config=3D25166257|25182129|209|391 optional=3D1 \ No newline at end of file diff --git a/tools/perf/tests/shell/attr/test-stat-detailed-3 b/tools/perf/= tests/shell/attr/test-stat-detailed-3 index 2d0fca8b5020f504..e7eef828245c5d6c 100644 --- a/tools/perf/tests/shell/attr/test-stat-detailed-3 +++ b/tools/perf/tests/shell/attr/test-stat-detailed-3 @@ -6,73 +6,73 @@ requires =3D core-pmu =20 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK -[event1:base-stat] +[event1:base-stat-group] fd=3D1 type=3D1 config=3D1 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES -[event2:base-stat] +[event2:base-stat-group] fd=3D2 type=3D1 config=3D3 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS -[event3:base-stat] +[event3:base-stat-group] fd=3D3 type=3D1 config=3D4 =20 # PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS -[event4:base-stat] +[event4:base-stat-group] fd=3D4 type=3D1 config=3D2 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES -[event5:base-stat] +[event5:base-stat-group] fd=3D5 type=3D0 config=3D0 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND -[event6:base-stat] +[event6:base-stat-group] fd=3D6 type=3D0 config=3D7 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND -[event7:base-stat] +[event7:base-stat-group] fd=3D7 type=3D0 config=3D8 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS -[event8:base-stat] +[event8:base-stat-group] fd=3D8 type=3D0 config=3D1 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS -[event9:base-stat] +[event9:base-stat-group] fd=3D9 type=3D0 config=3D4 optional=3D1 =20 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES -[event10:base-stat] +[event10:base-stat-group] fd=3D10 type=3D0 config=3D5 optional=3D1 =20 # PERF_TYPE_RAW / slots (0x400) -[event11:base-stat] +[event11:base-stat-group] fd=3D11 group_fd=3D-1 type=3D4 @@ -81,7 +81,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-retiring (0x8000) -[event12:base-stat] +[event12:base-stat-group] fd=3D12 group_fd=3D11 type=3D4 @@ -92,7 +92,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-bad-spec (0x8100) -[event13:base-stat] +[event13:base-stat-group] fd=3D13 group_fd=3D11 type=3D4 @@ -103,7 +103,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fe-bound (0x8200) -[event14:base-stat] +[event14:base-stat-group] fd=3D14 group_fd=3D11 type=3D4 @@ -114,7 +114,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-be-bound (0x8300) -[event15:base-stat] +[event15:base-stat-group] fd=3D15 group_fd=3D11 type=3D4 @@ -125,7 +125,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-heavy-ops (0x8400) -[event16:base-stat] +[event16:base-stat-group] fd=3D16 group_fd=3D11 type=3D4 @@ -136,7 +136,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-br-mispredict (0x8500) -[event17:base-stat] +[event17:base-stat-group] fd=3D17 group_fd=3D11 type=3D4 @@ -147,7 +147,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-fetch-lat (0x8600) -[event18:base-stat] +[event18:base-stat-group] fd=3D18 group_fd=3D11 type=3D4 @@ -158,7 +158,7 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / topdown-mem-bound (0x8700) -[event19:base-stat] +[event19:base-stat-group] fd=3D19 group_fd=3D11 type=3D4 @@ -169,63 +169,63 @@ read_format=3D15 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event20:base-stat] +[event20:base-stat-group] fd=3D20 type=3D4 config=3D4109 optional=3D1 =20 # PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=3D1,edge/ -[event21:base-stat] +[event21:base-stat-group] fd=3D21 type=3D4 config=3D17039629 optional=3D1 =20 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD -[event22:base-stat] +# PERF_TYPE_RAW / cpu-cycles (core PMU sysfs event; Intel 0x3c, AMD 0x76) +[event22:base-stat-group] fd=3D22 type=3D4 -config=3D60 +config=3D60|118 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY -[event23:base-stat] +[event23:base-stat-group] fd=3D23 type=3D4 config=3D2097421 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK -[event24:base-stat] +[event24:base-stat-group] fd=3D24 type=3D4 config=3D316 optional=3D1 =20 # PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE -[event25:base-stat] +[event25:base-stat-group] fd=3D25 type=3D4 config=3D412 optional=3D1 =20 # PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE -[event26:base-stat] +[event26:base-stat-group] fd=3D26 type=3D4 config=3D572 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS -[event27:base-stat] +[event27:base-stat-group] fd=3D27 type=3D4 config=3D706 optional=3D1 =20 # PERF_TYPE_RAW / UOPS_ISSUED.ANY -[event28:base-stat] +[event28:base-stat-group] fd=3D28 type=3D4 config=3D270 @@ -235,7 +235,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event29:base-stat] +[event29:base-stat-group] fd=3D29 type=3D3 config=3D0 @@ -245,7 +245,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event30:base-stat] +[event30:base-stat-group] fd=3D30 type=3D3 config=3D65536 @@ -255,7 +255,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_LL << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event31:base-stat] +[event31:base-stat-group] fd=3D31 type=3D3 config=3D2 @@ -265,7 +265,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_LL << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event32:base-stat] +[event32:base-stat-group] fd=3D32 type=3D3 config=3D65538 @@ -275,7 +275,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1I << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event33:base-stat] +[event33:base-stat-group] fd=3D33 type=3D3 config=3D1 @@ -285,7 +285,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1I << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event34:base-stat] +[event34:base-stat-group] fd=3D34 type=3D3 config=3D65537 @@ -295,7 +295,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_DTLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event35:base-stat] +[event35:base-stat-group] fd=3D35 type=3D3 config=3D3 @@ -305,7 +305,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_DTLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event36:base-stat] +[event36:base-stat-group] fd=3D36 type=3D3 config=3D65539 @@ -315,7 +315,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_ITLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event37:base-stat] +[event37:base-stat-group] fd=3D37 type=3D3 config=3D4 @@ -325,7 +325,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_ITLB << 0 | # (PERF_COUNT_HW_CACHE_OP_READ << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event38:base-stat] +[event38:base-stat-group] fd=3D38 type=3D3 config=3D65540 @@ -335,7 +335,7 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | # (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) -[event39:base-stat] +[event39:base-stat-group] fd=3D39 type=3D3 config=3D512 @@ -345,15 +345,43 @@ optional=3D1 # PERF_COUNT_HW_CACHE_L1D << 0 | # (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | # (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) -[event40:base-stat] +[event40:base-stat-group] fd=3D40 type=3D3 config=3D66048 optional=3D1 =20 # PERF_TYPE_RAW / INT_MISC.UOP_DROPPING -[event41:base-stat] +[event41:base-stat-group] fd=3D41 type=3D4 config=3D4269 +optional=3D1 + +# PERF_TYPE_RAW / instructions (core PMU sysfs event) +[event42:base-stat-group] +fd=3D42 +type=3D4 +config=3D192 +optional=3D1 + +# PERF_TYPE_RAW / branch-misses (core PMU sysfs event; Intel 0xc5, AMD 0xc= 3) +[event43:base-stat-group] +fd=3D43 +type=3D4 +config=3D197|195 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-frontend (core PMU sysfs event; Intel 0x1= 80010e, AMD 0xd0/0x287/0xa9) +[event44:base-stat-group] +fd=3D44 +type=3D4 +config=3D25166094|208|647|169 +optional=3D1 + +# PERF_TYPE_RAW / stalled-cycles-backend (core PMU sysfs event; Intel 0x18= 001b1/0x1803fb1, AMD 0xd1/0x187) +[event45:base-stat-group] +fd=3D45 +type=3D4 +config=3D25166257|25182129|209|391 optional=3D1 \ No newline at end of file --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C0BA53D9699; Fri, 16 Oct 2026 21:21:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185691; cv=none; b=hSYvLWFPb6dbP66Zx41Lh9fVqz5LBGQmmz1F3Z0MoDxLqS19ktbUl2HoBribKsnV5WiyWRlYG3uIrlJ5wwmHGVhgnsv3jnhjdKgCIyqNFETZkNkh1C0cSAKiI6suTc4tWU1Qp5pbS3BpLkZF3G9PW0xMLFYwOxLBUMJgMPGVwOA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185691; c=relaxed/simple; bh=30A+mZvAX+X2EB/Nmf4O8qBc5lmLwSd8N/bZGzVhrIg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EHRg9qUeRyUEVOYk8ZHmEKWp33lCxJ/odvjy3m8PbCJ5wF+V/j8hx0OkwY4Ny6GutAcnLJGdI2nbG5hlx0BcHneVHLtOWmNMqYaJn4t8WSYVWHQQ0ZSuSvKPWl6na1atiWTBBJ4Ceq7MPoQl9TfWzy4smemK/4lOJmGB6rJJgR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BK/55dav; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BK/55dav" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 02E491F000C4; Fri, 16 Oct 2026 21:21:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185689; bh=r/O/LS+JOnQTqJBY3m1juJWDC12ucJNtzXROp9rHI7U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=BK/55davwTU/W2kzenFsno0scSlw+DfEAN0atSKP0gpagpketpSlmO0UckIEGcRJM rglLQoRwTDbx6vvJKjk+H2Axj/SforqcAM7YyHwkmLrwicpFNmbXkcDOQ2Ei7zkdxz XVckHlctHjCGufvKzMmZGUJdaq2UUcWcT6os9qa4O5g2q29Kk+huG5LO5JW6rnfWNd mnYUnra/U8XqPIHUyrYkwkCRKBspZpq+Vy42F0LNAXBGe/NgOJ0nqF6phsXn77Yxvk vWVQoIynMHnop5xy4X0KYwibxLobQ1lM3/19VcKWX7Czn2D5WZZjs0SzMFAkZXaNfH q3oymQQOa4bEQ== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 06/21] perf test attr: Relax group checking for ungrouped expectations Date: Fri, 16 Oct 2026 18:20:47 -0300 Message-ID: <20261016212102.76550-7-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo When matching the recorded events back against the expectations, attr.py requires every event opened in a group to match an expectation that declares the same group. The perf stat default metrics open the events of each metric in groups, but the test expectations only verify the event attributes, so test-stat-default fails with: FAILED '.../test-stat-default' - group failure Only enforce the group of a recorded event when the expectation it matches declares one. Expectations that ask for a group are still verified in both directions. Fixes: c7adeb0974f18da4 ("perf jevents: Add set of common metrics based on = default ones") Fixes: 2dfc0cab3da4a205 ("perf stat: Add detail -d,-dd,-ddd metrics") Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index 2d7dd26a5737777c..087bfa4532b69c58 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -372,7 +372,7 @@ class Test(object): else: raise Unsup(self) =20 - def compare(self, expect, result): + def compare(self, expect, result, strict_groups=3DTrue): match =3D {} =20 log.debug(" compare") @@ -406,8 +406,9 @@ class Test(object): =20 match[exp_name] =3D exp_list =20 - # For each defined group in the expected events - # check we match the same group in the result. + # Check that each expected group is matched in the result; an event + # opened in a group may match an expectation that doesn't declare + # one, as those only verify the event attributes. for exp_name, exp_event in expect.items(): group =3D exp_event.group =20 @@ -416,6 +417,8 @@ class Test(object): =20 for res_name in match[exp_name]: res_group =3D result[res_name].group + if res_group =3D=3D '' and not strict_groups: + continue if res_group not in match[group]: raise Fail(self, 'group failure') =20 @@ -454,7 +457,7 @@ class Test(object): =20 # do the expectation - results matching - both ways self.compare(self.expect, self.result) - self.compare(self.result, self.expect) + self.compare(self.result, self.expect, strict_groups=3DFalse) =20 finally: # cleanup --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 487303E7179; Fri, 16 Oct 2026 21:21:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185694; cv=none; b=OJ7qnLg4TYAjiNBQgiu9NdgNbiivyYt9gDJGKdFQQczDDG6XQsT9m1QRzERHMhvePpUzhViplaGTcif40kHsiuf6xlANiKco07WGWBFz8YhYvFTL3Jjmbk5WzA/He7fX35uCRVto2S4Tbh/3TwN8S2cUdzEpD2dHFscid8IWH4c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185694; c=relaxed/simple; bh=D6gBH4rzn9ofW182vOzOgRcRuc+ozHzrNi9DP0nNdXg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qD4HNHLtNckKkAsEyF5+rrZTCyRjweGzhZb6ebHiOJ72/D7g1XjE6gXyd3igyUldPzrV1g+KeHXTcJoIAdtsakiuD47KsPp10XTApjj/JTNBLbpG4J8WtGWJEGcOnEaL59W+LsV3vy42BUPosbRftMjznW+fuBZEQbFZ33bMSFU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n8IGA6mX; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n8IGA6mX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2B6771F000C5; Fri, 16 Oct 2026 21:21:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185692; bh=wS0fg57Vpynd21ZO3GmtvsnsHKdxN1CGGQHPTIoEj6E=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=n8IGA6mX3QU2ewSxkP6D/ZgnsN1K6HPGn3DrR0ozWd9QZuCr4i+k0NXPfVBlyZBG2 jDXsyKgjb5y9F+c/UlBeLmphzir50hdXPegeeyw8KcD0pkQ+OwFxWGb2IxjnKCvlt6 3pN6bCChy/nfGjvsiyuL2MAJUwmU2+4Sf3Gjqir2Bk2LOsiwpedyVT5P+kSvjxEGpj qHQLnlh4YnOjLqiZO0GYkGCB92G7gD49diI78Sb8BrZYyGC3E/ES0Q2NJQG/a3NJtZ bwvSI0gGdk8Pt9CBgsN3Tyxds/2X2b5e0Xu3JhCZt5zcuxciGDVdNx2G2C53LXosBt kPoVfMqapUktw== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 07/21] perf evsel: Mark the event as supported when retrying an open Date: Fri, 16 Oct 2026 18:20:48 -0300 Message-ID: <20261016212102.76550-8-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Opening a group with perf record on a machine with perf_event_paranoid > 1 and no CAP_PERFMON fails the first perf_event_open() with EACCES, after which evsel__open_cpu() clears evsel->supported; evsel__fallback() then adds exclude_kernel and record__open() retries, and the retry succeeds with supported left false. get_group_fd() treats unsupported events as ungroupable, so the retry opens the group members without their leader: sys_perf_event_open: pid 12345 cpu 0 group_fd -1 FAILED '.../test-record-group-sampling1' - group failure which fails the group subtests of "perf test 82", the Perf attribute expectations test, when it is run as a regular user, while it passes as root or with CAP_PERFMON, where the first open doesn't fail. commit 2cc7aa995ce9 ("perf stat: Refactor retry/skip/fatal error handling") dropped the pos->supported =3D true that record__open() did after a successful open and moved the resets into the stat code only, while saying "When an event is tried the supported is set to true again". Do that in evsel__open_cpu(), which every open entry point funnels through, so that a retry describes its own try instead of the previous failure. Fixes: 2cc7aa995ce9ecd8 ("perf stat: Refactor retry/skip/fatal error handli= ng") Cc: Ian Rogers Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/util/evsel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9c5e7510f0c019c3..e61f309e93dccc7f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3014,6 +3014,12 @@ static int evsel__open_cpu(struct evsel *evsel, stru= ct perf_cpu_map *cpus, enum rlimit_action set_rlimit =3D NO_CHANGE; struct perf_cpu cpu; =20 + /* + * A failed attempt being retried after evsel__fallback() would + * otherwise keep group members out of their group in get_group_fd(). + */ + evsel->supported =3D true; + if (evsel__is_retire_lat(evsel)) { err =3D evsel__tpebs_open(evsel); goto out; --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D4B04477E0; Fri, 16 Oct 2026 21:21:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185697; cv=none; b=IYq3/92Iuv5WSlYtPBrrcbv838UomW7APANzLFWh6BeprTxJ1D5cukFNRkqN0LN6HujmYgYPvFutoN9Kmr+6xF+uErUZtCLMXisCsBeEJCkNxnTrcX+cs3qbiikNE7eNo7AzNylwLJm1bwsM/HVG2tQ386tjJVWJXGCmGp9geSE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185697; c=relaxed/simple; bh=UbJdWg4cMwwUCnOcNbUXuoZNU8T2tVtOEqWqfQQpDNg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o3J5Q9lykFC8MZUn+qFNhC3H7FL2Pt/0qjfd7Mb3OdtDFVVDSH+h1qfpbtOrU7Wkv7l6LAWVreP2wJXTIA7BbUFzudkv6KYJ4ExJMMmgyPqNHGitpj279Sd71VqOVPWH7nPrEELfV9y61DliYcEb2Yp3lLnKnZQv5AgmkdTj51Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SZJViSF0; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SZJViSF0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 542221F000C4; Fri, 16 Oct 2026 21:21:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185696; bh=youFpWWKwQRdiiolqh8PN2/x33e4xnhU7tr3jliOsPM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=SZJViSF0c1gtIrS2MfhZ/nnabYBquUKOIQEgKCbarzBU/dkUKmNdEpcWREyj5Ck91 vBza9DWWn47tiibMhK0l8TMNjJL5zwQoNu5mOj5h5DH9RTC02qkISzG0v4F3FW65zU nHv5ob67FYqWfMH45gGMm74+2CW9WXmY6HiK4bI2vkCw/IRkzKjq3kePcg8XmEdbW4 E8I3wz4bHJAvuXV0bLOViKESKqZ/cBVqjLu20KTAFEjNRm6FlYxeb/dYzboei8U1xm 5hHnyOeq5KqLP0zMzubgbKdDHfbVmUdsEgV57K8W+70PbWSnnbAvQxc5gY2bFYIA34 i0rx1GjLAnerA== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 08/21] perf test attr: Ignore the core PMU type perf puts in 'config' Date: Fri, 16 Oct 2026 18:20:49 -0300 Message-ID: <20261016212102.76550-9-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Since commit 55bcf6ef314a ("perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACH= E") in v5.13, and arm_pmu opted in with commit 5c816728651a ("arm_pmu: Add PERF_PMU_CAP_EXTENDED_HW_TYPE capability= ") in v6.6, the kernel can be told which core PMU a legacy type event is meant for, with its type in the top 32 bits of 'config', see perf_pmus__supports_extended_type(), which __parse_events_add_numeric() does for HARDWARE and HW_CACHE events, but only when there is more than one core PMU, i.e. on heterogeneous machines, where asking for one event ends up being one event per core PMU: $ perf stat -e cycles -a -- sleep 1 20,520,998 armv8_cortex_a53/cycles/ 13,029,350 armv8_cortex_a73/cycles/ and what lands in PERF_TEST_ATTR is the extended encoding: type=3D0 config=3D38654705664 # core PMU type 9, PERF_COUNT_HW_CPU_CYCLES so the expectations written for the single core PMU case fail with: expected config=3D0|1, got 38654705664 expected config=3D0, got 38654705664 # 'perf stat -d' L1-dcache events which is what now happens on an Amlogic A311D (2 Cortex-A53 + 4 Cortex-A73), a machine that just got the CPU PMU nodes it was missing. Take those bits out when comparing the 'config' of legacy type events, keeping what these expectations mean on machines with a single core PMU: which of the PMUs is counting is not what we're asking here. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 53 ++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index 087bfa4532b69c58..fb866fb75175dc95 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -73,6 +73,32 @@ def core_pmu_probe(): =20 return True =20 +PERF_TYPE_HARDWARE =3D 0 +PERF_TYPE_HW_CACHE =3D 3 + +# The legacy event types, where perf may qualify 'config' with the core PMU +# type in its top 32 bits when there is more than one core PMU. +LEGACY_TYPES =3D (str(PERF_TYPE_HARDWARE), str(PERF_TYPE_HW_CACHE)) + +def hide_core_pmu_type(value): + """ + The kernel can be told which core PMU a legacy type event is meant for= by + putting its type in the top 32 bits of 'config', which perf only does = when + there is more than one core PMU, so take those bits out to keep the + expectations written for the single core PMU case matching on + heterogeneous machines. + """ + hidden =3D [] + + for alternative in value.split('|'): + try: + alternative =3D str(int(alternative, 0) & 0xffffffff) + except ValueError: + pass + hidden.append(alternative) + + return '|'.join(hidden) + class Fail(Exception): def __init__(self, test, msg): self.msg =3D msg @@ -146,12 +172,33 @@ class Event(dict): self.add(base) self.add(data) =20 + def hide_core_pmu_type_terms(self, other): + """ + Is this a legacy type event? Then the core PMU type that perf may = have + put in the top 32 bits of 'config' to tell the kernel which core P= MU it + wants isn't part of what we asked for, see hide_core_pmu_type(). + """ + for event in (self, other): + for type in event.get('type', '').split('|'): + if type in LEGACY_TYPES: + return True + + return False + + def hide_core_pmu_type(self, term, value, other): + if term =3D=3D 'config' and self.hide_core_pmu_type_terms(other): + return hide_core_pmu_type(value) + + return value + def equal(self, other): for t in Event.terms: log.debug(" [%s] %s %s", t, self[t], other[t]) if t not in self or t not in other: return False - if not data_equal(self[t], other[t]): + exp =3D self.hide_core_pmu_type(t, self[t], other) + got =3D self.hide_core_pmu_type(t, other[t], other) + if not data_equal(exp, got): return False return True =20 @@ -164,7 +211,9 @@ class Event(dict): for t in Event.terms: if t not in self or t not in other: continue - if not data_equal(self[t], other[t]): + exp =3D self.hide_core_pmu_type(t, self[t], other) + got =3D self.hide_core_pmu_type(t, other[t], other) + if not data_equal(exp, got): log.warning("expected %s=3D%s, got %s", t, self[t], other[= t]) =20 def parse_version(version): --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 459EF457E4F; Fri, 16 Oct 2026 21:21:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185700; cv=none; b=qz8Ox0rpSNvqFTT8UqpAeiEESPGab8GSYZGEBtCrbB8D5S97vow6th0Qems7DVsBvXUFYNmCOkVrhMrhGChGsQNJRDcN1ATylXjhz25CcxRXlBbt5dfhLTEWShEQDtEnPTPwEdvl+vhN5QUiOB71/E3q0BHGZcbTrs4J6EwzK6A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185700; c=relaxed/simple; bh=qNHb1CLjTtMHqgMCXUwp0cCKIIKt9WNSlisl2evFjMA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SkgTMbPzo5SRYCLvUaOg3kJ9UnPb7oiDh0ewaKbj6mAwsY+ewAF9vhsyg1gn4S4PyefviDKt0TU6nA7yGtaB5ppFO8wHyk3MFJeRdNUwC7vaseeRYvp0bcIvirzUKnpyDNwz63R1RFxANVjjN1TOJFQ2soYFQ3xSU/ddizHNIAg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UymbWPdv; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UymbWPdv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7C6AA1F000C5; Fri, 16 Oct 2026 21:21:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185699; bh=eXXSCiITuXuvwb3zfcXD2NXYropFwuSwM81SLh+Zg28=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UymbWPdvv+9WzmNaZulbZG/LBbWY5IQ9OMXNeBOsQISJ02UxKlTo8yw2URYV+qqzD ZE8gPV85wc71VxkoqejvMUtZ/nJGg8EMdlf6eDlPYlJ8oEr8mptJ9xVJEJYbhJDt6f XC6uJ1ONPMCpR3vJmjtffWwOkvZuY3RcmYuumAPfCNvf7CvGfdLM0Wc0A/V18QfWUG dnLgWjSuE8yxIYbZCJIxuwjzJzWqYTjv09WIUyNJT6Ch2p/h/LMdveuXlNFbUvKW1+ J3kccY/9FXRZUp3xRsMwDCPcnwsoIhREOMGyJRF8dN13ivaNBSkqb7F2kV2xqgZiCf Gqkx2zUyR96GQ== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 09/21] perf evsel: Don't dump probe events to PERF_TEST_ATTR Date: Fri, 16 Oct 2026 18:20:50 -0300 Message-ID: <20261016212102.76550-10-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Events opened just to ask if they are supported, i.e. the ones in is_event_supported() and is_libpfm_event_supported(), go through the regular evsel__open() path and thus end up in the event files written to $PERF_TEST_ATTR, with everything but type, config and disabled zeroed: [event-0-38654705664-3] fd=3D3 cpu=3D-1 pid=3D0 type=3D0 size=3D0 config=3D38654705664 sample_type=3D0 ... which 'perf test attr' then takes as one of the events that were asked for, failing with: expected cpu=3D0, got -1 expected size=3D176, got 0 expected sample_type=3D65927, got 0 expected freq=3D1, got 0 This started showing up when there is more than one core PMU, as perf_pmus__supports_extended_type() probes one such event per core PMU, but these records were always bogus: nothing asked for them. Flag those evsels as support probes, keeping the name clear of the kprobe/uprobe meaning probe already has in evsel, and leave them out of the dump. Reported-by: Namhyung Kim Link: https://lore.kernel.org/linux-perf-users/asWQvXRdqp_RK85c@google.com/ Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/util/evsel.c | 6 +++++- tools/perf/util/evsel.h | 1 + tools/perf/util/pfm.c | 1 + tools/perf/util/print-events.c | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e61f309e93dccc7f..59318fef03cb17ff 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3104,7 +3104,11 @@ static int evsel__open_cpu(struct evsel *evsel, stru= ct perf_cpu_map *cpus, =20 bpf_counter__install_pe(evsel, idx, fd); =20 - if (unlikely(test_attr__enabled())) { + /* + * Support probes aren't what was asked for, leave them + * out of the PERF_TEST_ATTR dump. + */ + if (unlikely(test_attr__enabled() && !evsel->support_probe)) { test_attr__open(&evsel->core.attr, pid, cpu, fd, group_fd, evsel->open_flags); } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 174f3414fd3cfa0d..53f3641b66e18674 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -120,6 +120,7 @@ struct evsel { u64 db_id; bool uniquified_name; bool supported; + bool support_probe; /* Opened just to check for support. */ bool needs_swap; bool disabled; bool no_aux_samples; diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c index f80d6b0df47ae64d..ad9bc481da70604e 100644 --- a/tools/perf/util/pfm.c +++ b/tools/perf/util/pfm.c @@ -141,6 +141,7 @@ static bool is_libpfm_event_supported(const char *name,= struct perf_cpu_map *cpu return false; =20 evsel->is_libpfm_event =3D true; + evsel->support_probe =3D true; =20 ret =3D evsel__open(evsel, cpus, threads); if (ret =3D=3D -EACCES) { diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index 0242243681b6b6f9..77428d9e73c4f1b6 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -147,6 +147,7 @@ bool is_event_supported(u8 type, u64 config) =20 evsel =3D evsel__new(&attr); if (evsel) { + evsel->support_probe =3D true; ret =3D evsel__open(evsel, NULL, tmap) >=3D 0; =20 if (!ret) { --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09DAC44470C; Fri, 16 Oct 2026 21:21:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185704; cv=none; b=suODhe4SvvD+X/4/X9aIFV/vyQ/GwVJk0Dvx/I/dfGCPoZLmKax7ZcyMQ/m9ScZvCo9RznZ/UeWxYMG75aROz5JO/7Id1xQqy1POiWLvRfZrdSRquf+Y1YH2bG8pCT9ouazSARYMM1oJgud1Tuoc4ZFEHsM4zi3pWY5asJkCPM0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185704; c=relaxed/simple; bh=LRq8J5VI/c5F4mdl9yO6INb5fMccOMFyxeFMLCWierg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Mm/wFsH5TW+vM67i1tvVs0kL7lE1K8mOgwIo+qsPXT21gaXEs/elBnJs3AOHFiv/6MHDlHHdHpztcqWex/8o42ij9G0UjhiLMNt9g4GenUKVohKOsJHxS+Md4+EzYyNGPVkWu5H2PwK7xKcFj/bcx7BqZRsUMHg1P2ykfNj8wkI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hl+J3gmh; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hl+J3gmh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A57B91F000C4; Fri, 16 Oct 2026 21:21:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185702; bh=92DCjrzrW+PZSmkPKLfzePb6H6t+YqDZbYECatKavO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=hl+J3gmh4rwaWVZ1f/17Jk1JJ1SU78I0R6YEbETkhAVFuEJYB0aD6JkaNWa7JxW62 XZOiuaKIPr7e7P2Xe4W6Cwbc6QklHgo/9JP3V87kr0glcPieVPO72KUzPr1/tIZaeh v/13vYp8ZNV/bDwHJUD2cv/0p4zyGKNbuodNM2/TG8R8RM0gxmwHQqNjW5KL3Z8s1R gcJQAuilNKbnYeBN7lg5qL5i2ISMoVHYcWA7GaIksSREilHZx8p822xh8jkMhsB6R1 aZkfzVnr/0zo+s+hgQmbGnJMg7JCcAfUuWKbkifZtoiyl71SEi881LDMpYVESoZ2d+ UdZjKr+58NVRQ== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo , Sashiko , stable@vger.kernel.org Subject: [PATCH v4 10/21] perf evsel: Close the fds opened so far when disabling missing features Date: Fri, 16 Oct 2026 18:20:51 -0300 Message-ID: <20261016212102.76550-11-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo evsel__open_cpu() opens the events one by one and, when an open fails with EINVAL and evsel__detect_missing_features() has a feature to leave out, goes back to fallback_missing_features to open them all again from start_cpu_map_idx, without closing what the abandoned attempt opened: the fd of every CPU or thread that was opened before the failing one is overwritten in the FD() array, leaking it. Close them first, the same way out_close does when returning an error, leaving the entries at -1 for the retry. Fixes: af954f76eea5 ("perf tools: Check fallback error and order") Reported-by: Sashiko Closes: https://lore.kernel.org/r/sashiko-outbox-173532@kernel.org Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/util/evsel.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 59318fef03cb17ff..d060fca8090f6e26 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3005,6 +3005,19 @@ static bool evsel__detect_missing_features(struct ev= sel *evsel, struct perf_cpu return false; } =20 +static void evsel__close_fds(struct evsel *evsel, int start_cpu_map_idx, + int cpu_map_idx, int thread, int nthreads) +{ + do { + while (--thread >=3D 0) { + if (FD(evsel, cpu_map_idx, thread) >=3D 0) + close(FD(evsel, cpu_map_idx, thread)); + FD(evsel, cpu_map_idx, thread) =3D -1; + } + thread =3D nthreads; + } while (--cpu_map_idx >=3D start_cpu_map_idx); +} + static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, struct perf_thread_map *threads, int start_cpu_map_idx, int end_cpu_map_idx) @@ -3150,8 +3163,14 @@ static int evsel__open_cpu(struct evsel *evsel, stru= ct perf_cpu_map *cpus, if (err =3D=3D -EMFILE && rlimit__increase_nofile(&set_rlimit)) goto retry_open; =20 - if (err =3D=3D -EINVAL && evsel__detect_missing_features(evsel, cpu)) + if (err =3D=3D -EINVAL && evsel__detect_missing_features(evsel, cpu)) { + /* + * The restart opens the events again, so close what this + * attempt opened before its entries are overwritten. + */ + evsel__close_fds(evsel, start_cpu_map_idx, idx, thread, nthreads); goto fallback_missing_features; + } =20 if (evsel__precise_ip_fallback(evsel)) goto retry_open; @@ -3161,14 +3180,7 @@ static int evsel__open_cpu(struct evsel *evsel, stru= ct perf_cpu_map *cpus, threads->err_thread =3D thread; =20 old_errno =3D errno; - do { - while (--thread >=3D 0) { - if (FD(evsel, idx, thread) >=3D 0) - close(FD(evsel, idx, thread)); - FD(evsel, idx, thread) =3D -1; - } - thread =3D nthreads; - } while (--idx >=3D start_cpu_map_idx); + evsel__close_fds(evsel, start_cpu_map_idx, idx, thread, nthreads); errno =3D old_errno; out: if (err) --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 47D04487CCB; Fri, 16 Oct 2026 21:21:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185707; cv=none; b=krrAP1U++TVFisIrHryRJu9xjTybwPQKziTnCw40rlQeWKKAl6Z3Sr7k2mlKLkJm+h1sq20Ffp+4rEzqRJkxVDgoy2qIBErC019CkSd2nj7fqD3rCpJSgaNOL6yAqqb2EGioagifTD3ruC9hwJH6aNIzRD3XhE75CsfNMwaDj8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185707; c=relaxed/simple; bh=J1ANDjFW3B/OVcU+v+e7FHQc8GZMSZ+NJ3zYi4+AsuU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hmhhGIf3EYJg++xnmGoMVprofvh7Xt+ou0kqx60vQploOVCj9GzUZEaN30VReG0UJu3r3MQZmiGPLuRHbz9s7eVCwyM0A6XR3dLjAc+HhJnKilOUBv6d6RMU5YMJmy9E2ltCABES4FXkuhgqTyX86Lh8Oug5pB5k1+Prv8VKb9g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Hoyh35Ir; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Hoyh35Ir" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 388891F000C5; Fri, 16 Oct 2026 21:21:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185705; bh=xh/fOWK01/mrtVy7URa7Zle8xiDCJNDmcmJINOhtI4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Hoyh35Ir2Nue1JrNOalPCMXDYzbHZUv4Iwc4BSZH5vHexJuAl7lx8sx4UDtfuyz4e PdvzpVcjR88eAU6ZO2TQcVORqf9hCrKoGyeR+qz2FaMFAJe+ikmR5fy9QpZAXUym5f mWlFlFvzO7wHggNkw/HZqPfZrP8nGAA4CsKO4MsL+XOBY/3TvGCummpS3RFhdXXbIU TaObBwMAOx5MkJOOmdAlWu1FVwqsDj8erY67xiJTB1m/PpDHtVcYC8Fy64nFk5QvKp 4Mxx+K3jmpC0ZqOU5+lBbOYtSnSEBrTSkraVKUa5QsnzzUoqL2b/3teBTq78YIly7P KmN+1uLMkcLCw== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 11/21] perf test attr: Introduce mask_bits(), generalizing hide_core_pmu_type() Date: Fri, 16 Oct 2026 18:20:52 -0300 Message-ID: <20261016212102.76550-12-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo What hide_core_pmu_type() does is take a set of bits out of each of the '|'-separated alternatives in a value, wildcards included, keeping the rest of the expression: extract that as mask_bits() and implement hide_core_pmu_type() in terms of it, a prep for using the same thing to ignore, when comparing expectations, the sample id bit perf ends up asking for and the read_format group bit that a PMU count can remove. No change in behaviour. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index fb866fb75175dc95..ee55fbe6f07bd7b5 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -80,24 +80,31 @@ PERF_TYPE_HW_CACHE =3D 3 # type in its top 32 bits when there is more than one core PMU. LEGACY_TYPES =3D (str(PERF_TYPE_HARDWARE), str(PERF_TYPE_HW_CACHE)) =20 -def hide_core_pmu_type(value): +def mask_bits(value, bits): """ - The kernel can be told which core PMU a legacy type event is meant for= by - putting its type in the top 32 bits of 'config', which perf only does = when - there is more than one core PMU, so take those bits out to keep the - expectations written for the single core PMU case matching on - heterogeneous machines. + Take the bits in 'bits' out of each of the '|'-separated alternatives = in + 'value', keeping the rest of the expression, wildcards included. """ - hidden =3D [] + masked =3D [] =20 for alternative in value.split('|'): try: - alternative =3D str(int(alternative, 0) & 0xffffffff) + alternative =3D str(int(alternative, 0) & ~bits) except ValueError: pass - hidden.append(alternative) + masked.append(alternative) =20 - return '|'.join(hidden) + return '|'.join(masked) + +def hide_core_pmu_type(value): + """ + The kernel can be told which core PMU a legacy type event is meant for= by + putting its type in the top 32 bits of 'config', which perf only does = when + there is more than one core PMU, so take those bits out to keep the + expectations written for the single core PMU case matching on + heterogeneous machines. + """ + return mask_bits(value, 0xffffffff00000000) =20 class Fail(Exception): def __init__(self, test, msg): --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2B92048488D; Fri, 16 Oct 2026 21:21:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185710; cv=none; b=fDyvZbrOxnwpn70047g29myxy7bRzabBVtTkAVzTt7/OFeCa+fUue8R/JjQsq9ezsXnypudj9QI64hl/P54GSeljYzvGC4O/UtO67mWXDfK4w90pEhd0riyLmP8s304gwmwnCIy1VYSbcfRISjIcbOOHe2wB+rU9n2tv8gdu/jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185710; c=relaxed/simple; bh=n47Psr6MPSi3wQtSz1SbioIXNVsGrf/FLc9GjKjMxzY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cDiVrPclBfyMZ7R3bRb9Ls1OpcetFvTp8zjYGJ8yqlfBxIfZvb99i4MtGnG0AZiUpx2YNqXoPbZPZ5RP6eEDC+FSd+1pGQIi9YTSO/19J2OkqrshJPKGDK6dDMIvITTKB6ICukBQRd63arDFNWghO5havWIcDH0mq8mc0dMVi88= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UHj/2kFN; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UHj/2kFN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 61E6E1F000C4; Fri, 16 Oct 2026 21:21:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185709; bh=1h/sIa/RFikuJlmd9FoDWTqHTjPWM3t1e5d4lH8iJfU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UHj/2kFN6RptcZqRQ5C/OSWNyDuwBGI69B49IhkdSkicnA6ljX9Ek+GoPZFUMh/oN Nqo0MaLICKU4Mh2udqRmpxPbLqPZ+qV916rsXGCpAOXTHAKZzlN9lUUq6Hk2hYvrKF sITZ54H/eJaZJZv/8T8gzWcd6VxXw03sZKxp9nC4fmxp6ic+XbRQsIsl9wcCAiJCFt rnIJSEIfP3bIbQu/qwnUk3VGHbD8wUUBJ946ScCRT1zYm7CI9uB+hSbncehKzJ6OEH PSOEDbZjtqye2qNFi0BaCXLJzg6WW9kppMAGDqiUyKRXlK28GcBEKoZ2UmjP9wBDcD J0eeCXJjVRTCg== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 12/21] perf test attr: Accept either sample id bit perf asks for Date: Fri, 16 Oct 2026 18:20:53 -0300 Message-ID: <20261016212102.76550-13-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo evlist__config() asks for a way to tell the samples apart, PERF_SAMPLE_IDENTIFIER where available, PERF_SAMPLE_ID otherwise: bool sample_id =3D opts->sample_id; ... if (opts->full_auxtrace || opts->sample_identifier) { ... use_sample_identifier =3D perf_can_sample_identifier(); sample_id =3D true; } else if (evlist__nr_entries(evlist) > 1) { ... use_sample_identifier =3D perf_can_sample_identifier(); sample_id =3D true; } so the id is asked for whenever the evlist has more than one event, and also when asked to outright, with --sample-identifier or by an auxtrace session, or by record__config() for a pipe run, through opts->sample_id, none of which depends on the sample types: 'perf record --sample-identifier -e cycles' and the arm SPE expectations in this very directory ask for it with a single event. Which one it asks for depends on the composition of the evlist: with more than one core PMU a request for 'cycles' becomes one event per core PMU, the extra dummy tracking events then make the sample types differ and perf goes for IDENTIFIER, while the expectations were written on machines with a single core PMU, where perf asks for ID: expected sample_type=3D263, got 65799 # 263 | (1 << 16) expected sample_type=3D343, got 65815 # (343 & ~(1 << 6)) | (1 << 16),= group-sampling Both bits mean the same thing here, how the samples get associated with the event that produced them, so when the expectation asks for one of them, ask for "an id of some sort" on both sides, and when the expectation doesn't ask for any, take the bits out of what got recorded: whether they are there and which one it is are consequences of what was asked for and of how the request got expanded, none of that is what these expectations are about. Since Test.compare() looks at both directions, expectations matching the recorded events and recorded events matching the expectations, keep track of which side is the one perf recorded to take the bits out of the right side. The masking is only for the comparison: the warnings keep showing the values as they are, nothing to un-mask by hand to see what is being complained about. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 88 ++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index ee55fbe6f07bd7b5..7b0e9944ea299bd9 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -75,6 +75,8 @@ def core_pmu_probe(): =20 PERF_TYPE_HARDWARE =3D 0 PERF_TYPE_HW_CACHE =3D 3 +PERF_SAMPLE_ID =3D 1 << 6 +PERF_SAMPLE_IDENTIFIER =3D 1 << 16 =20 # The legacy event types, where perf may qualify 'config' with the core PMU # type in its top 32 bits when there is more than one core PMU. @@ -106,6 +108,49 @@ def hide_core_pmu_type(value): """ return mask_bits(value, 0xffffffff00000000) =20 +# The two sample id bits mean the same thing here: how the samples of the +# events in the evlist get associated with the event that produced them. +SAMPLE_ID_BITS =3D PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER + +# No real sample_type bit is this high, so it can stand for "either of the +# sample id bits" when comparing the two sides. +SAMPLE_ID_EITHER =3D 1 << 40 + +def hide_sample_id(expected, recorded): + """ + perf asks for a way to tell the samples apart, PERF_SAMPLE_IDENTIFIER = where + available, PERF_SAMPLE_ID otherwise, see evlist__config(): whenever the + evlist has more than one event, and when asked to outright, with + --sample-identifier, by an auxtrace session, or by record__config() fo= r a + pipe run, none of which depends on the sample types, as those only cho= ose + between the two bits: + with more than one core PMU the dummy tracking events make the sample = types + differ, so IDENTIFIER is asked for even for events whose expectations = ask + for ID, written on a machine with a single core PMU. + + So treat the two as the same thing: when the expectation asks for eith= er + of them, ask for "an id of some sort" on both sides, and when the + expectation doesn't ask for any, take the bits out of what got recorde= d. + """ + try: + asked =3D int(expected, 0) & SAMPLE_ID_BITS + except ValueError: + # The expectation is a wildcard or a set of alternatives. + return expected, recorded + + try: + recorded_id_bits =3D int(recorded, 0) & SAMPLE_ID_BITS + except ValueError: + # The recorded side is a wildcard or a set of alternatives. + return expected, mask_bits(recorded, SAMPLE_ID_BITS) + + if not asked: + return expected, mask_bits(recorded, SAMPLE_ID_BITS) + + return (str(int(expected, 0) & ~SAMPLE_ID_BITS | SAMPLE_ID_EITHER), + str(int(recorded, 0) & ~SAMPLE_ID_BITS | + (SAMPLE_ID_EITHER if recorded_id_bits else 0))) + class Fail(Exception): def __init__(self, test, msg): self.msg =3D msg @@ -198,13 +243,36 @@ class Event(dict): =20 return value =20 + def hide_event_count_dependent_terms(self, term, expected, recorded): + if term =3D=3D 'sample_type': + return hide_sample_id(expected, recorded) + + return expected, recorded + + def recorded_side(self, other): + """ + Which one is what perf recorded? Both directions get compared, see + Test.compare(), so this can't be taken from the arguments' order. + """ + if getattr(other, 'recorded', False): + return other + + return self if getattr(self, 'recorded', False) else None + def equal(self, other): for t in Event.terms: log.debug(" [%s] %s %s", t, self[t], other[t]) if t not in self or t not in other: return False - exp =3D self.hide_core_pmu_type(t, self[t], other) - got =3D self.hide_core_pmu_type(t, other[t], other) + recorded =3D self.recorded_side(other) + if recorded is self: + expected, got_event =3D other, self + else: + expected, got_event =3D self, other + exp =3D self.hide_core_pmu_type(t, expected[t], other) + got =3D self.hide_core_pmu_type(t, got_event[t], other) + if recorded is not None: + exp, got =3D self.hide_event_count_dependent_terms(t, exp,= got) if not data_equal(exp, got): return False return True @@ -218,10 +286,18 @@ class Event(dict): for t in Event.terms: if t not in self or t not in other: continue - exp =3D self.hide_core_pmu_type(t, self[t], other) - got =3D self.hide_core_pmu_type(t, other[t], other) + recorded =3D self.recorded_side(other) + if recorded is self: + expected, got_event =3D other, self + else: + expected, got_event =3D self, other + exp =3D self.hide_core_pmu_type(t, expected[t], other) + got =3D self.hide_core_pmu_type(t, got_event[t], other) + if recorded is not None: + exp, got =3D self.hide_event_count_dependent_terms(t, exp,= got) if not data_equal(exp, got): - log.warning("expected %s=3D%s, got %s", t, self[t], other[= t]) + log.warning("expected %s=3D%s, got %s", t, expected[t], + got_event[t]) =20 def parse_version(version): if not version: @@ -506,6 +582,8 @@ class Test(object): log.debug(" loading result events") for f in glob.glob(tempdir + '/event*'): self.load_events(f, self.result) + for event in self.result.values(): + event.recorded =3D True =20 # resolve group_fd to event names self.resolve_groups(self.expect) --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A605044BCB4; Fri, 16 Oct 2026 21:21:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185713; cv=none; b=gKLZ9isHD32Wioi58vvyRgxSW+9utd1CpHJGhaGGRzjnlnRL4+W1eOfAtWs5ysGby0Ecem06nn+piDut2cT8t3Nx2RBICaE4TFQIovEanUy5KAnobzPlWV8sUrdnUZQ1cCwVWfpAnMYNdHv96i0rwVlP25Mp2/ZWujSN+wRmRDs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185713; c=relaxed/simple; bh=v+fqRHVpf/VmyJ1Yo59RihFlb1U12b0JrEMQIq7SkJM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R6IaF0xp+JHVLN+cLVd7HVZdP+cIKACqlpLenn6RUBWj67a7f79y7hbQmIjU5a6eqyW3w2bfh11B8KktsmUr6uY9ccqnmNYEvebZ8IMrX7C/aH6VD+CI5dQrOVPwsduH88Y09Ora+9Nzdt5OvQdQSZ6zJV54nxZpMe9YNQ5N3xM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fXQtYVkw; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fXQtYVkw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8AECA1F000C5; Fri, 16 Oct 2026 21:21:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185712; bh=pnDAKm+Au1xaZ8ArKsT0GxxKAtGTvE4AgWUEmegeeuo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=fXQtYVkwAs2Ml/qSdHQTgCCzWQcu7kPTx6hPSxxI6lW9uNJSfkzpjheGr1IUvQ/hd pja5ezdQbuYS8Y+VHrswVs2ruXfx4AYjF78I0XbIbA03wWkIBW3xd1ODkCy3dhAb+r UO3DOZKVsr0gfJuCw4PDg3f4uvlgZIiz6iSlaot3Vv8MsvBBHJW97USxMA70wpZWeh eVmXM0x29JU3dMwJhepp0RK67YSU5WnyUDOwTRT/kr8JfEMmuDEr+eaMgzG/k/oDzn EA9UX3U2hA2KglRN9J3jp4ig1yv6Dz5KtWqUy3KIc4gtfVgbmbh4+8cQ6sYBghW8qc c6iYUtwpViCJw== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 13/21] perf test attr: Ignore the dummy tracking event and the terms it carries Date: Fri, 16 Oct 2026 18:20:54 -0300 Message-ID: <20261016212102.76550-14-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo With more than one core PMU the requested events can't cover all the CPUs, each cluster has its own PMU, so perf opens the software dummy event to carry the tracking terms (mmap, comm, task, mmap_data), leaving the requested events without them: expected mmap=3D1, got 0 expected comm=3D1, got 0 expected task=3D1, got 0 That dummy event is not part of what the expectations are about, so leave it out of the comparison, unless the expectations ask for one, like system-wide-dummy and test-record-dummy-C0 do. And when perf used it to carry the tracking terms, those terms can't be matched on the requested events, leave them out of the match as well. The terms are left out only where the dropped dummy actually carried them, from the sample_type it was opened with, a dummy that didn't is no reason to stop verifying them. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 61 ++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index 7b0e9944ea299bd9..47a09f00000ff762 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -77,6 +77,21 @@ PERF_TYPE_HARDWARE =3D 0 PERF_TYPE_HW_CACHE =3D 3 PERF_SAMPLE_ID =3D 1 << 6 PERF_SAMPLE_IDENTIFIER =3D 1 << 16 +PERF_TYPE_SOFTWARE =3D 1 +PERF_COUNT_SW_DUMMY =3D 9 + +def is_dummy_tracking_event(event): + """ + Is this the dummy event perf opens to carry the tracking events (mmap, + comm, task) when the requested ones can't, like when there is more tha= n one + core PMU and each core PMU's events run on only part of the CPUs? + """ + return (event.get('type') =3D=3D str(PERF_TYPE_SOFTWARE) and + event.get('config') =3D=3D str(PERF_COUNT_SW_DUMMY)) + +# With more than one core PMU the tracking terms go to the dummy tracking = event, +# leaving the requested events without them, so they can't be matched ther= e. +TRACKING_TERMS =3D ['mmap', 'comm', 'task', 'mmap_data'] =20 # The legacy event types, where perf may qualify 'config' with the core PMU # type in its top 32 bits when there is more than one core PMU. @@ -259,11 +274,29 @@ class Event(dict): =20 return self if getattr(self, 'recorded', False) else None =20 + def hide_tracking_via_dummy(self, term, other): + """ + The tracking terms are set on the tracking event, which is the dum= my + event when there is more than one core PMU, leaving the requested + events without them, nothing to match on then. + """ + if term not in TRACKING_TERMS: + return False + + for event in (self, other): + if term in getattr(event, 'tracking_moved_to_dummy', ()): + return True + + return False + def equal(self, other): for t in Event.terms: log.debug(" [%s] %s %s", t, self[t], other[t]) if t not in self or t not in other: return False + if self.hide_tracking_via_dummy(t, other): + continue + recorded =3D self.recorded_side(other) if recorded is self: expected, got_event =3D other, self @@ -286,6 +319,9 @@ class Event(dict): for t in Event.terms: if t not in self or t not in other: continue + if self.hide_tracking_via_dummy(t, other): + continue + recorded =3D self.recorded_side(other) if recorded is self: expected, got_event =3D other, self @@ -504,6 +540,29 @@ class Test(object): else: raise Unsup(self) =20 + def drop_dummy_tracking_events(self): + """ + Leave out the dummy event perf itself opened, see + is_dummy_tracking_event(), unless the expectations ask for one. + """ + if any(is_dummy_tracking_event(e) for e in self.expect.values()): + return + + if not any(is_dummy_tracking_event(e) for e in self.result.values(= )): + return + + moved =3D set() + for name, event in list(self.result.items()): + if is_dummy_tracking_event(event): + log.debug(" dropping dummy tracking event [%s]", name) + moved.update(t for t in TRACKING_TERMS if event.get(t) =3D= =3D '1') + del self.result[name] + + # The tracking terms the dropped dummies carried, flag the remaini= ng + # events so that the match leaves only those out. + for event in self.result.values(): + event.tracking_moved_to_dummy =3D moved + def compare(self, expect, result, strict_groups=3DTrue): match =3D {} =20 @@ -585,6 +644,8 @@ class Test(object): for event in self.result.values(): event.recorded =3D True =20 + self.drop_dummy_tracking_events() + # resolve group_fd to event names self.resolve_groups(self.expect) self.resolve_groups(self.result) --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2C0A48DB2E; Fri, 16 Oct 2026 21:21:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185716; cv=none; b=mJ+JqLJEgrJfC8ZwjvGozDTrDpw1hhXwvnGaDua6iB57GOs7eJRm1Er/jfrk3esUQ9ZWk/M14UiNJPdEkMUV6NgP/Lz5m+m9s4KcP+CESdSHiIqWeyWHPPtoRIdo/RseKwt3P79uu9aGn74C73CVxYRLoYSgmGWjVDn4MK1jECk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185716; c=relaxed/simple; bh=2GwR2vPjo6ao1MAIQsAqU1UG+er2vCL47+HNf6XhhpY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jJh0JkeSzxkY2ZG8MImXEaqgmiRBb3KftcjzHC4p2ONBHsNrCkK9ixhrJiWpHzC3r12G3JQ/xHGaEvZTtr+KyjmanBrnKdKHA1y9qKpgaMRnzSk73v5sPrFHPXc6JIs7JtsUw4VQRMFQSvfVKw5kfS/gQZjopFhboLvpn0P/SbY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PvmJZ1tJ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PvmJZ1tJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B2F5F1F000C4; Fri, 16 Oct 2026 21:21:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185715; bh=S02rUCMUk6BgE4l4cral83kTRBp5hEJpTHW2k3WwjZ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=PvmJZ1tJx8UmNnQULPHEwstGY5U1biwZrVx2/AuIS8AQWGiE3Pq/NpLFaDmxtyBKd Eyv/07TwX7YyLDEUchVGoBVrRvg0lTf9buSere/sv3VGpMdJ5/9nidE0HGCsol3WWN cmyZyJSwAuxZmZnqJUgL+zDo1sA9QevrN7G5Gpe2BD1f/ttzmBlpmVFGAMORMZ75B9 E+euQpxMX1D+TJzrGc0rwc/91TvOnVmqD2AbHBgKRb6UzKhpwLkfFPklGIEn1ghy2V Pn9NQEWvl9oeiz055yZNURqcbd43JJZVKbMlGsQb49PKYDLGY5M7ooWITLbs1j5zUa mNNasT6GUn8XQ== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 14/21] perf test attr: Leave out the events of the other core PMUs Date: Fri, 16 Oct 2026 18:20:55 -0300 Message-ID: <20261016212102.76550-15-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo On a hybrid machine the default stat metrics are opened on each core PMU, and the events of the other one have their own encodings: on an i7-14700K cpu_atom (type 10) opens UOPS_RETIRED.ALL, config 194, which the expectations, written for cpu_core (type 4), don't name: expected type=3D4, got 10 expected config=3D209|391, got 194 The test already masks the core PMU type out of 'config' for the legacy events, but raw events keep their type and encoding, so leave out the events of the core PMUs no expectation names, like the dummy tracking event. Core PMUs are found as perf finds them: 'cpu' or 'cpum_cf', or a PMU with a 'cpus' file in sysfs. Nothing is left out unless an expectation names a core PMU, so single core PMU machines and the tests with only legacy expectations are not affected. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index 47a09f00000ff762..d485a491c717c96c 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -563,6 +563,44 @@ class Test(object): for event in self.result.values(): event.tracking_moved_to_dummy =3D moved =20 + def drop_other_core_pmu_events(self, devices=3D'/sys/bus/event_source/= devices'): + """ + Leave out the events of the other core PMUs, which have their own + encodings, when the expectations name one of the core PMUs. + """ + asked =3D set() + for event in self.expect.values(): + types =3D event.get('type', '').split('|') + if '*' in types: + return + asked.update(types) + + try: + names =3D os.listdir(devices) + except OSError: + return + + core =3D set() + for name in names: + path =3D os.path.join(devices, name) + has_cpus =3D os.path.exists(os.path.join(path, 'cpus')) + if name not in ('cpu', 'cpum_cf') and not has_cpus: + continue + try: + with open(os.path.join(path, 'type'), encoding=3D'utf-8') = as f: + core.add(f.read().strip()) + except OSError: + pass + + if not core & asked: + return + + others =3D core - asked + for name, event in list(self.result.items()): + if event.get('type') in others: + log.debug(" dropping other core PMU event [%s]", name) + del self.result[name] + def compare(self, expect, result, strict_groups=3DTrue): match =3D {} =20 @@ -645,6 +683,7 @@ class Test(object): event.recorded =3D True =20 self.drop_dummy_tracking_events() + self.drop_other_core_pmu_events() =20 # resolve group_fd to event names self.resolve_groups(self.expect) --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0289848DB57; Fri, 16 Oct 2026 21:21:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185720; cv=none; b=MzRbxOwWIqJ5gWzS7kvzoJT8f3oXZcVzKkCQD8aUDTljDKyCbo9ZyBH+HFD6BNESLhDjdfo3eipsF0t83ESWpX9qzX6gNTX48uTzwJ9OQvEcNpDhYyIIJKC6tXtJGsanpsdeg2dLlcFpyziGw7oIWdYOG2HO0eDx6anBn4kbLhM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185720; c=relaxed/simple; bh=OjSan2BMYnIlS++ZHCXwRg4U8LB4xQENcbvxxD6e/GQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dXQ4gmKnqUujxRZkGirxzZjpeEKk1q5kblUty6B8CeDbLBLW7MQoTsJyL9dUXl3DI3uW0XrTHXU3prZoQ8OZqamloCCZG/zKrCtQ+/NSQuSRMMjLTeZW+QLb6Djno/g4j189MTwIk4inuqgVMNGLUraikUhWilBYoQte/+9JRyg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EclzSZ1c; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EclzSZ1c" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DBFC31F000C5; Fri, 16 Oct 2026 21:21:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185718; bh=mKzw1bE2JKRKG6Uj0mGK+WDnDZ5D1dXy7uj6nYUhq9k=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=EclzSZ1cXoPrnF6NIbrKFuzaDKBwV5wzX0KUhfh2zcYkY3DKP3fH6IPCIkf1R4wSr TEE4/A9QlO8R9u7nlQJZVXnf0ppm4dS6MI9UfYcMrUxgH3U+f1vaBSCMjQCRvbbI4Z RSgPS0Cg5JSzXOhJkP4LvtJx/bE/q4FAoxN7+9sHdTJslMoro83hKcBiQzzIG3N5IB OqfqNolr/EE4jl1aL6TaoaH5hVkJdiEmlFhJcvy/3abWOOEAOj3/4MxhXvEBatTepj 4wzu0CKivlDsREnLX5o+j0wldsZ2JYyz+72LXf5jEysWmc6eG34o6twgGAlcGy3VSh 9+os2H2UBeu0A== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 15/21] perf test attr: Ignore the group read_format bit the PMU count can remove Date: Fri, 16 Oct 2026 18:20:56 -0300 Message-ID: <20261016212102.76550-16-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo read_format's PERF_FORMAT_GROUP bit asks for the group members to be read along with the leader, which aside from this bit is verified with the fd/group_fd based group checking in Test.compare(), and with more than one core PMU a group whose members are pinned to one of them, say 'default_core', leaves the clones for the other core PMUs without any members: $ perf stat -e '{cycles,default_core/legacy-hardware-config=3D3/}:S' ... the A53 leader keeps its cohort, both A73 cycles clones are alone, read_format 20 instead of 28 so that bit isn't there: whether it is there is a consequence of how the evlist got expanded to more than one core PMU, not of the groupness the expectations say about, which is verified structurally, so take it out on both sides. That leaves the A73 leader clones, now with: expected read_format=3D28|31, got 20 matching the base event expectations again. With a single core PMU there is nothing to expand, so there is nothing to explain away: count the core PMUs when the script starts, from what perf makes of 'cycles', see parse_events_multi_pmu_add(), and take the bit out only when there is more than one, leaving the machines with a single core PMU verifying what the expectations say about it. That count is 2 on the Amlogic A311D, where its A53 and A73 PMUs both answer for 'cycles', and 1 on a machine with a single core PMU. Where there is no binding to ask, as when attr.py runs without setup_python.sh, the count isn't available and the bit is taken out as well. core_pmu_count() takes the count from the same probe core_pmu_available() uses, so the binding is asked once, and only when a comparison needs the answer, not at import time. The sample id bits hide_sample_id() takes out when the expectations ask for none are another consequence of having more than one core PMU, so the same single core PMU gate covers them; equating the two id bits, needed when the evlist has more than one event even with a single core PMU, keeps applying. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 75 +++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index d485a491c717c96c..09ee496b4947f470 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -30,6 +30,7 @@ def data_equal(a, b): return False =20 CORE_PMU_AVAILABLE =3D None +CORE_PMU_COUNT =3D None =20 def core_pmu_available(): """ @@ -38,40 +39,47 @@ def core_pmu_available(): check the expectations that pin their legacy encodings. The answer ca= n't change while the tests run, so probe the binding only once. """ - global CORE_PMU_AVAILABLE - - if CORE_PMU_AVAILABLE is None: - CORE_PMU_AVAILABLE =3D core_pmu_probe() - + core_pmu_probe() return CORE_PMU_AVAILABLE =20 def core_pmu_probe(): """ - Ask perf itself, through its python binding, to parse and open 'cycles= ': - a parse failure or an ENOENT means no PMU can count it, any other error - means we can't tell whether there is one. + Ask perf itself, through its python binding, to parse and open 'cycles' + once: a parse failure or an ENOENT means no PMU can count it, any other + error means we can't tell whether there is one, and the number of even= ts + it expanded to is the number of core PMUs, see + parse_events_multi_pmu_add(), which is what core_pmu_count() asks for. """ + global CORE_PMU_AVAILABLE, CORE_PMU_COUNT + + if CORE_PMU_AVAILABLE is not None: + return + try: import perf parse_events =3D perf.parse_events except (ImportError, AttributeError): # Nothing to ask about it, let the expectations speak. - return True + CORE_PMU_AVAILABLE =3D True + return =20 try: evlist =3D parse_events('cycles') except OSError: # No PMU that can count it, the same as the ENOENT below. - return False + CORE_PMU_AVAILABLE =3D False + return =20 + CORE_PMU_COUNT =3D len(evlist) try: evlist.open() except OSError as err: # Anything else is a permission problem or alike, not our business= here. - return err.errno !=3D errno.ENOENT + CORE_PMU_AVAILABLE =3D err.errno !=3D errno.ENOENT + return evlist.close() =20 - return True + CORE_PMU_AVAILABLE =3D True =20 PERF_TYPE_HARDWARE =3D 0 PERF_TYPE_HW_CACHE =3D 3 @@ -131,6 +139,45 @@ SAMPLE_ID_BITS =3D PERF_SAMPLE_ID | PERF_SAMPLE_IDENTI= FIER # sample id bits" when comparing the two sides. SAMPLE_ID_EITHER =3D 1 << 40 =20 +PERF_FORMAT_GROUP =3D 1 << 3 + +def core_pmu_count(): + """ + How many core PMUs does perf see? An event with no PMU named in it + becomes one event per core PMU, see parse_events_multi_pmu_add(), and + that is the expansion that leaves the clones for the other core PMUs + without any group members and that makes perf qualify 'config' with the + type of the PMU it is for, so this is the number of events perf makes = of + 'cycles', from the probe core_pmu_available() shares. + """ + core_pmu_probe() + return CORE_PMU_COUNT + +def single_core_pmu(): + """ + Does perf see only one core PMU? Asked for by the comparisons that ne= ed + it, not at import time, as a run may never get to one. + """ + return core_pmu_count() =3D=3D 1 + +def hide_group_format(expected, recorded): + """ + read_format's PERF_FORMAT_GROUP bit asks for the group members to be r= ead + along with the leader, which aside from this bit is verified with the + fd/group_fd based group checking, and with more than one core PMU a gr= oup + whose members are pinned to one of them, say 'default_core', leaves the + clones for the other core PMUs without any members, so that bit isn't + there: whether it is there is a consequence of how the evlist got + expanded to more than one core PMU, not of what the expectations are + about, so take it out on both sides. On a machine with a single core = PMU + there is nothing to expand, so the expectations keep verifying it. + """ + if single_core_pmu(): + return expected, recorded + + return (mask_bits(expected, PERF_FORMAT_GROUP), + mask_bits(recorded, PERF_FORMAT_GROUP)) + def hide_sample_id(expected, recorded): """ perf asks for a way to tell the samples apart, PERF_SAMPLE_IDENTIFIER = where @@ -160,6 +207,8 @@ def hide_sample_id(expected, recorded): return expected, mask_bits(recorded, SAMPLE_ID_BITS) =20 if not asked: + if single_core_pmu(): + return expected, recorded return expected, mask_bits(recorded, SAMPLE_ID_BITS) =20 return (str(int(expected, 0) & ~SAMPLE_ID_BITS | SAMPLE_ID_EITHER), @@ -261,6 +310,8 @@ class Event(dict): def hide_event_count_dependent_terms(self, term, expected, recorded): if term =3D=3D 'sample_type': return hide_sample_id(expected, recorded) + if term =3D=3D 'read_format': + return hide_group_format(expected, recorded) =20 return expected, recorded =20 --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF035443AAF; Fri, 16 Oct 2026 21:22:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185723; cv=none; b=pLLtL42EScKpnY7YEmmYJCsdUGPkleJ6TwuaUd7+jMfX2f7zxHDk5OFMLykRaUL7FOQKdmtfYpTCQI4C3DBmbG/jVKP8tkcnWGd1eQT0mrEHdyWGrd0hcuLpJWH5LXMkHXLuWVwfP6vclo9RJYH42rk0UwgJ+GiJA3QtER4Fyg8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185723; c=relaxed/simple; bh=t7w3rIBGsa4Af3BZ8BHHddD2vNJkW/osDtGG+N2YRBo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e/1a+OrBk3Ir2SRt4O0CTqYSpxtyE/ZRq/mmrBS3g667P6eSCifWMPsmt/6MfsjzDsA+UikWU8SzJnwc/sVFlmh3/faL+jpe4vyMW27ecSLhdkOOFuxlj/JzchfymzsKnNrfuehUf1EZUn9/lbOuKPKvXX5l8Nf7CTtGNcPy/tM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OKpGL1X8; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OKpGL1X8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 113AF1F000C4; Fri, 16 Oct 2026 21:21:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185721; bh=9BtvQL0SqR3j9LZTwodMHPKREEH5LQ5EKL3EypBf02s=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=OKpGL1X8rhu+yByjUkXn+ccMp31BC65/wXOUm63GEPWy8Dtm1wA88YDfF3NDgzrZd IVsL4lMEdHsEObearOXoJtp1sWKvo+Z5o2lu/sGSIxbVtiCh6cDNWJnaLUhMLxb0J4 MA//+CT1qPzxQNc6sVTS+hB/l9v0XMuyldPdlUQk0bbImD45pCcV9AXg0IvUeyZ3s1 4WDf97V0s20j3eJukc8H6LJaQA+kFVdeKZvo0BSLPu8+RCiMZvPMoJM8DHiWxd4e3g VPqCelFvNkmp//LynBdXmYH+0Mqwf0H0KWkRjhWSCJqdHTlh0gGBihrZncywuzbZlR s3lULMGsn2X2w== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 16/21] perf test attr: State, spelled out in a line, why a test is skipped Date: Fri, 16 Oct 2026 18:20:57 -0300 Message-ID: <20261016212102.76550-17-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Per skip the default output shows a self contained one liner: unsupp 'test-record-branch-filter-any' exit 255, expected 1, no attrs re= corded to verify skipped [kernel newer than 6.12] 'test-record-group-sampling' skipped [arch =3D !aarch64, machine =3D aarch64] 'test-record-graph-defau= lt' The extra notes explaining the reason, with a copy pasteable command to observe the failure, come in the very same stream when the verbosity is bumped, at -vvv, nothing is written to a separate place for later consultation, it is just the logging ladder: detail: '/root/bin/perf record -o /dev/null --no-bpf-event -j any kill' exited with 255, the expectations want the workload's 1 exit, so there are no attrs recorded to verify; this is normally a capability problem, run '/root/bin/perf record -o /dev/null --no-bpf-event -j any kill' to see why Note that 'perf test -v/-vv/-vvv attribute' appends a single -v to the shell test entry (shell_test__run()), so to see the notes one runs the python module directly, f.i.: python3 tests/shell/lib/attr.py -vvv -d tests/shell/attr -p ./perf The skip functions now return the reason fragment when they want to skip and None when the test can go on. The command suggested to observe the failure writes to /dev/null, so it doesn't leave a perf.data in the directory it is run from. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/lib/attr.py | 106 +++++++++++++++++++---------- 1 file changed, 70 insertions(+), 36 deletions(-) diff --git a/tools/perf/tests/shell/lib/attr.py b/tools/perf/tests/shell/li= b/attr.py index 09ee496b4947f470..df1993883199866c 100644 --- a/tools/perf/tests/shell/lib/attr.py +++ b/tools/perf/tests/shell/lib/attr.py @@ -223,17 +223,20 @@ class Fail(Exception): return '\'%s\' - %s' % (self.test.path, self.msg) =20 class Notest(Exception): - def __init__(self, test, arch): - self.arch =3D arch + def __init__(self, test, reason): + self.reason =3D reason self.test =3D test def getMsg(self): - return '[%s] \'%s\'' % (self.arch, self.test.path) + return '[%s] \'%s\'' % (self.reason, self.test.path) =20 class Unsup(Exception): - def __init__(self, test): + def __init__(self, test, ret, expected): self.test =3D test + self.ret =3D ret + self.expected =3D expected def getMsg(self): - return '\'%s\'' % self.test.path + return '\'%s\' exit %d, expected %s, no attrs recorded to verify' = % ( + self.test.path, self.ret, self.expected) =20 class Event(dict): terms =3D [ @@ -391,6 +394,9 @@ def parse_version(version): return None return [int(v) for v in version.split(".")[0:2]] =20 +def format_version(version): + return ".".join(str(v) for v in version) + # Test file description needs to have following sections: # [config] # - just single instance in file @@ -456,13 +462,17 @@ class Test(object): =20 def skip_test_kernel_since(self): if not self.kernel_since: - return False - return not self.kernel_since <=3D parse_version(platform.release()) + return None + if self.kernel_since <=3D parse_version(platform.release()): + return None + return "kernel older than %s" % format_version(self.kernel_since) =20 def skip_test_kernel_until(self): if not self.kernel_until: - return False - return not parse_version(platform.release()) < self.kernel_until + return None + if parse_version(platform.release()) < self.kernel_until: + return None + return "kernel newer than %s" % format_version(self.kernel_until) =20 def skip_test_auxv(self): def new_auxv(a, pattern): @@ -478,18 +488,20 @@ class Test(object): return (items[0], value) =20 if not self.auxv: - return False + return None auxv =3D subprocess.check_output("LD_SHOW_AUXV=3D1 sleep 0", shell= =3DTrue) \ .decode(sys.stdout.encoding) pattern =3D re.compile(r"[: ]+") auxv =3D dict([new_auxv(a, pattern) for a in auxv.splitlines()]) - return not eval(self.auxv) + if eval(self.auxv): + return None + + return "the auxv condition doesn't hold here" =20 def skip_test_arch(self, myarch): # If architecture not set always run test if self.arch =3D=3D '': - # log.warning("test for arch %s is ok" % myarch) - return False + return None =20 # Allow multiple values in assignment separated by ',' arch_list =3D self.arch.split(',') @@ -499,27 +511,26 @@ class Test(object): arch_list[0] =3D arch_list[0][1:] log.warning("excluded architecture list %s", arch_list) for arch_item in arch_list: - # log.warning("test for %s arch is %s" % (arch_item, myarc= h)) if arch_item =3D=3D myarch: - return True - return False + return "arch =3D %s, machine =3D %s" % (self.arch, mya= rch) + return None =20 for arch_item in arch_list: - # log.warning("test for architecture '%s' current '%s'" % (arc= h_item, myarch)) if arch_item =3D=3D myarch: - return False - return True + return None + + return "arch =3D %s, machine =3D %s" % (self.arch, myarch) =20 def skip_test_requires(self): for requirement in filter(None, map(str.strip, self.requires.split= (','))): if requirement =3D=3D 'core-pmu': if not core_pmu_available(): log.warning("test limitation 'requires %s'", requireme= nt) - return True + return "needs a core PMU, none here" else: log.warning("unknown requirement '%s', ignored", requireme= nt) =20 - return False + return None =20 def restore_sample_rate(self, value=3D10000): try: @@ -563,20 +574,36 @@ class Test(object): def run_cmd(self, tempdir): _junk1, _junk2, _junk3, _junk4, myarch =3D (os.uname()) =20 - if self.skip_test_arch(myarch): - raise Notest(self, myarch) - - if self.skip_test_auxv(): - raise Notest(self, "auxv skip") - - if self.skip_test_kernel_since(): - raise Notest(self, "old kernel skip") - - if self.skip_test_kernel_until(): - raise Notest(self, "new kernel skip") - - if self.skip_test_requires(): - raise Notest(self, "requirements skip") + arch =3D self.skip_test_arch(myarch) + if arch: + log.debug(" detail: the test file has arch =3D %s, the machin= e reports %s", + self.arch, myarch) + raise Notest(self, arch) + + auxv =3D self.skip_test_auxv() + if auxv: + log.debug(" detail: the auxv condition %s doesn't hold, the b= its come " + "from the LD_SHOW_AUXV=3D1 output", self.auxv) + raise Notest(self, auxv) + + kernel =3D self.skip_test_kernel_since() + if kernel: + log.debug(" detail: the test file's kernel_since =3D %s, this= kernel is %s", + format_version(self.kernel_since), platform.release()) + raise Notest(self, kernel) + + kernel =3D self.skip_test_kernel_until() + if kernel: + log.debug(" detail: the test file's kernel_until =3D %s, this= kernel is %s", + format_version(self.kernel_until), platform.release()) + raise Notest(self, kernel) + + requirement =3D self.skip_test_requires() + if requirement: + log.debug(" detail: requires core-pmu, nothing countable here= , check " + "kernel.perf_event_paranoid and the PMU nodes under " + "/sys/bus/event_source/") + raise Notest(self, requirement) =20 self.restore_sample_rate() cmd =3D "PERF_TEST_ATTR=3D%s %s %s -o %s/perf.data %s" % (tempdir, @@ -586,10 +613,17 @@ class Test(object): log.info(" '%s' ret '%s', expected '%s'", cmd, str(ret), str(self= .ret)) =20 if not data_equal(str(ret), str(self.ret)): + plain_cmd =3D "%s %s -o /dev/null %s" % ( + self.perf, self.command, + self.args.split('>/dev/null')[0].rstrip()) if self.test_ret: raise Fail(self, "Perf exit code failure") else: - raise Unsup(self) + log.debug(" detail: '%s' exited with %d, the expectations= want the " + "workload's %s exit, so there are no attrs record= ed to " + "verify; this is normally a capability problem, r= un '%s' " + "to see why", plain_cmd, ret, self.ret, plain_cmd) + raise Unsup(self, ret, str(self.ret)) =20 def drop_dummy_tracking_events(self): """ --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 342AE49427E; Fri, 16 Oct 2026 21:22:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185728; cv=none; b=agQlhujK1v++eHqqyqRetCJTXSNDPGydDxWZdS0KGNnslyjJD4zK+Hz3HAjpWWsTA1Ik0Z3JeIPpINNq7s3wEF7yfRYYyRYuxtpLAxQa8bakib/uWQ6R2i1qzS5UkrrBfxTTp7+o/jGVRdiqgrNDicNKnoe8/x1mpe5y9g5H/WQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185728; c=relaxed/simple; bh=If/1U4Xke5vj/8m/mFhH9KqZ8QUNl/pBGccebD3HBJA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uWG21B8QkWSQlC19XE1WAc7qw93LCVpsqVuRjcUetUIkFB2W9UxZilEMAdT9F3Ws3Krq6MO2QCl5dy1kCnT0t+rBZmZlWw46qnvdZhddcNdSRYiyQe8u17AvHJ1m5i1x8rrcGqQ2Y2FwVgUvqsfJVJQhtaOsydZLTjyAjICQ1Q0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AHtMhZ19; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AHtMhZ19" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3AB851F000C5; Fri, 16 Oct 2026 21:22:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185724; bh=391hSwrPoLCyUR6sENaU5GIso8gaYIUibgkQESVmGnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=AHtMhZ19W6GlZjmFKDd8aB0XKTrdPxuyVlAJHbH0ic3uPlyWrfC3+ezg3lyMsBPgP iSWsT/0S9wfQt+Op7tW1MvxbSFJzGWnApaOoZ/Xhdt7kz5GPXOB78l4QbL4ot3mXez rrO+Ut0BrraJeFyajzi44e5+9vMb39TKYBx4sSvogH5UCb0bpWFPvL/2Xqy9ltn3rQ wo1GNB1bv1KHQs0ePLIJSmC7l7uXKy4rZm6jh2OG6dPVEeKSLlrkbAcoUFOgSdemnh +6+ba10aKiga2n7ge1M1T+DPF/aPjqwucFB9BULRn1fYpeDZoW0hjO0Rlws7wSYmBZ 3lbU3AEakwb2Q== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 17/21] perf tests: Introduce a 'needs_mlock' suite flag Date: Fri, 16 Oct 2026 18:20:58 -0300 Message-ID: <20261016212102.76550-18-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Each perf instance maps one ring buffer per CPU, all charged to the same per user budget set in kernel.perf_event_mlock_kb, so suites that map them need to be told apart from the ones that don't, to later have them take turns using that budget while the other tests keep running in parallel. Add the flag to 'struct test_suite' and a DEFINE_SUITE_NEEDS_MLOCK() variant for the suites using the DEFINE_SUITE() form. Shell tests run perf, that maps ring buffers, so they are taken to need room in that budget by default; the requisites, a comma separated list in the parens ending their description line, name what a test needs and take a "no_" prefix to waive it, e.g.: # perf stat tests (no_mlock) "mlock" is room in that budget, so stating it only spells the default out, "no_mlock" waives it, and "exclusive" is the catch-all that keeps a test from running alongside any other, so it runs alone, in sequence, and implies every other requisite, which is why it can't be waived either. More requisites are to come, each stating what a test needs, till the catch-all isn't needed anymore. 'perf test requisites' lists what each test needs, reusing the listing routine and taking the same test name fragments and numbers as 'list'. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/Documentation/perf-test.txt | 35 ++++++++++- tools/perf/tests/builtin-test.c | 45 ++++++++++++-- tools/perf/tests/tests-scripts.c | 85 ++++++++++++++++++++++++-- tools/perf/tests/tests.h | 17 ++++++ 4 files changed, 168 insertions(+), 14 deletions(-) diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentat= ion/perf-test.txt index 859df74e62efc4b1..156c6e8caa75f153 100644 --- a/tools/perf/Documentation/perf-test.txt +++ b/tools/perf/Documentation/perf-test.txt @@ -8,7 +8,7 @@ perf-test - Runs sanity tests. SYNOPSIS -------- [verse] -'perf test [] [{list |[|= ]}]' +'perf test [] [{list|requisites} []|[|]]' =20 DESCRIPTION ----------- @@ -18,9 +18,38 @@ also will look for a directory with more tests in the fo= rm of scripts. To get a list of available tests use 'perf test list', specifying a test n= ame fragment will show all tests that have it. =20 +To get a list of what the tests need, i.e. of their requisites (see below)= , use +'perf test requisites', that takes the same test name fragments and number= s as +'list'. + To run just specific tests, inform test name fragments or the numbers obta= ined from 'perf test list'. =20 +REQUISITES +---------- +Shell tests run perf, that maps ring buffers, so they are taken to need ro= om +in the per user budget set in kernel.perf_event_mlock_kb, shared by the te= sts +running at the same time. Tests state what they need, or waive, in a comma +separated list in the parens ending their description line, e.g.: + + # perf stat tests (no_mlock) + +Each requisite is named in that list, "mlock" being room in the budget set= in +kernel.perf_event_mlock_kb, and takes a "no_" prefix to waive it: "(mlock)" +states the default, "(no_mlock)" waives it, for tests that don't map ring +buffers. Leaving a requisite out states nothing about it, so what happens +then is up to each kind of test: shell ones run perf, that maps ring buffe= rs, +so they are taken to need room in the budget unless they waive it, while C +suites say which ones map, see DEFINE_SUITE_NEEDS_MLOCK() in tests.h. +"exclusive" is a catch-all: the test can't run alongside any other one, so +it runs alone, in sequence, and implies every other requisite; it can't be +waived. More requisites are to come, each stating what a test needs, till +the catch-all isn't needed anymore. + +Use 'perf test requisites' to list what each test needs. That listing sta= tes +the needs, not the requisites form used in the scripts: a test listed as +needing "mlock" is one whose script doesn't say "(no_mlock)". + OPTIONS ------- -s:: @@ -36,8 +65,8 @@ OPTIONS =20 -S:: --sequential:: - Run all tests one after the other. By default "exclusive" - tests are run sequentially, but other tests are run in + Run all tests one after the other. By default the tests asking to be + "exclusive" (see REQUISITES) run sequentially, but other tests run in parallel to speed execution. =20 -r:: diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index 98134b1c74cf80f4..c187772948c41cf7 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -11,6 +11,7 @@ #include #endif #include +#include #include #include =20 @@ -56,6 +57,8 @@ static struct strbuf junit_xml_buf =3D STRBUF_INIT; static bool dont_fork; /* Fork the tests in parallel and wait for their completion. */ static bool sequential; +/* List what each test needs, set by the "requisites" subcommand. */ +static bool list_requisites; /* Number of times each test is run. */ static unsigned int runs_per_test =3D 1; /* Number of lines to include in failure snippet. */ @@ -283,6 +286,30 @@ static const char *test_description(const struct test_= suite *t, int test_case) return t->desc; } =20 +static void requisites__fprintf(FILE *fp, const struct test_suite *t, int = test_case) +{ + bool needs_mlock =3D t->needs_mlock, exclusive; + + if (test_case < 0) + test_case =3D test_suite__num_test_cases(t) =3D=3D 1 ? 0 : -1; + + if (test_case >=3D 0) { + exclusive =3D t->test_cases[test_case].exclusive; + /* The catch-all implies every other requisite. */ + needs_mlock =3D needs_mlock || exclusive; + } else { + exclusive =3D false; + } + + if (!exclusive && !needs_mlock) + return; + + fprintf(fp, " ("); + if (exclusive) + fprintf(fp, "exclusive, "); + fprintf(fp, "mlock)"); +} + static test_fnptr test_function(const struct test_suite *t, int test_case) { if (test_case <=3D 0) @@ -1450,14 +1477,20 @@ static int perf_test__list(FILE *fp, struct test_su= ite **suites, int argc, const if (!perf_test__matches(test_description(*t, -1), curr_suite, argc, argv= )) continue; =20 - fprintf(fp, "%3d: %s\n", curr_suite + 1, test_description(*t, -1)); + fprintf(fp, "%3d: %s", curr_suite + 1, test_description(*t, -1)); + if (list_requisites) + requisites__fprintf(fp, *t, /*test_case=3D*/-1); + fprintf(fp, "\n"); =20 if (test_suite__num_test_cases(*t) <=3D 1) continue; =20 test_suite__for_each_test_case(*t, curr_test_case) { - fprintf(fp, "%3d.%1d: %s\n", curr_suite + 1, curr_test_case + 1, + fprintf(fp, "%3d.%1d: %s", curr_suite + 1, curr_test_case + 1, test_description(*t, curr_test_case)); + if (list_requisites) + requisites__fprintf(fp, *t, curr_test_case); + fprintf(fp, "\n"); } } return 0; @@ -1747,7 +1780,8 @@ static struct test_suite **build_suites(void) int cmd_test(int argc, const char **argv) { const char *test_usage[] =3D { - "perf test [] [{list |[= |]}]", + "perf test [] [{list|requisites} []|" + "[|]]", NULL, }; const char *skip =3D NULL; @@ -1776,7 +1810,7 @@ int cmd_test(int argc, const char **argv) "Generate junit XML output, default test.xml", "test.xml"), OPT_END() }; - const char * const test_subcommands[] =3D { "list", NULL }; + const char * const test_subcommands[] =3D { "list", "requisites", NULL }; struct intlist *skiplist =3D NULL; struct test_suite **suites; int ret; @@ -1808,10 +1842,11 @@ int cmd_test(int argc, const char **argv) setvbuf(stdout, NULL, _IONBF, 0); =20 argc =3D parse_options_subcommand(argc, argv, test_options, test_subcomma= nds, test_usage, 0); - if (argc >=3D 1 && !strcmp(argv[0], "list")) { + if (argc >=3D 1 && (!strcmp(argv[0], "list") || !strcmp(argv[0], "requisi= tes"))) { suites =3D build_suites(); if (!suites) return errno ? -errno : -ENOMEM; + list_requisites =3D !strcmp(argv[0], "requisites"); ret =3D perf_test__list(stdout, suites, argc - 1, argv + 1); free(suites); return ret; diff --git a/tools/perf/tests/tests-scripts.c b/tools/perf/tests/tests-scri= pts.c index 0370bc7013737e31..a86b5289f09b1e63 100644 --- a/tools/perf/tests/tests-scripts.c +++ b/tools/perf/tests/tests-scripts.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -179,6 +180,79 @@ static int shell_test__run(struct test_suite *test, in= t subtest __maybe_unused) return WEXITSTATUS(err) =3D=3D 2 ? TEST_SKIP : TEST_FAIL; } =20 +/* + * The requisites are a comma separated list in the parens ending the + * description line, e.g. "perf stat tests (no_mlock)": "exclusive" is the + * catch-all, implying every other requisite, "no_mlock" waives the defaul= t of + * needing room in the per user budget set in kernel.perf_event_mlock_kb. + */ +static void shell_test__requisites(char *desc, bool *exclusive, bool *need= s_mlock) +{ + char *lparen, *rparen, *requisites, *token, *tokp; + bool known =3D false; + + /* Only a list closing the description line is taken for requisites. */ + rparen =3D strrchr(desc, ')'); + if (rparen =3D=3D NULL || rparen[1] !=3D '\0') + return; + + lparen =3D strrchr(desc, '('); + if (lparen =3D=3D NULL || lparen > rparen) + return; + + /* Tokenize a copy: a list with nothing recognized leaves desc alone. */ + requisites =3D strndup(lparen + 1, rparen - lparen - 1); + if (requisites =3D=3D NULL) { + pr_err("Failed to copy the requisites of '%s'\n", desc); + return; + } + + for (token =3D strtok_r(requisites, ",", &tokp); token; + token =3D strtok_r(NULL, ",", &tokp)) { + char *end =3D token + strlen(token); + const char *requisite =3D token; + bool waived; + + while (isspace(*token)) + token++; + while (end > token && isspace(end[-1])) + end--; + *end =3D '\0'; + + /* A "no_" prefix waives the requisite named after it. */ + waived =3D strncmp(token, "no_", sizeof("no_") - 1) =3D=3D 0; + if (waived) + token +=3D sizeof("no_") - 1; + + if (!strcmp(token, "mlock")) { + *needs_mlock =3D !waived; + } else if (!strcmp(token, "exclusive") && !waived) { + *exclusive =3D true; + } else { + pr_debug("Ignoring %s requisite '%s' in '%s'\n", + strcmp(token, "exclusive") =3D=3D 0 ? "a waived" : "an unknown", + requisite, desc); + continue; + } + + known =3D true; + } + + zfree(&requisites); + + if (!known) + return; + + /* Drop the list and the space before it from the description. */ + *lparen =3D '\0'; + if (lparen > desc && isspace(lparen[-1])) + lparen[-1] =3D '\0'; + + /* The catch-all implies every other requisite, whatever the order. */ + if (*exclusive) + *needs_mlock =3D true; +} + static void append_script(int dir_fd, const char *name, char *desc, struct test_suite ***result, size_t *result_sz) @@ -187,7 +261,8 @@ static void append_script(int dir_fd, const char *name,= char *desc, struct test_suite *test_suite, **result_tmp; struct test_case *tests; ssize_t len; - char *exclusive; + /* Shell tests run perf, that maps ring buffers, so they need the budget.= */ + bool exclusive =3D false, needs_mlock =3D true; =20 snprintf(link, sizeof(link), "/proc/%d/fd/%d", getpid(), dir_fd); len =3D readlink(link, filename, sizeof(filename) - 1); @@ -204,11 +279,8 @@ static void append_script(int dir_fd, const char *name= , char *desc, return; } tests[0].name =3D strdup_check(name); - exclusive =3D strstr(desc, " (exclusive)"); - if (exclusive !=3D NULL) { - tests[0].exclusive =3D true; - exclusive[0] =3D '\0'; - } + shell_test__requisites(desc, &exclusive, &needs_mlock); + tests[0].exclusive =3D exclusive; tests[0].desc =3D strdup_check(desc); tests[0].run_case =3D shell_test__run; test_suite =3D zalloc(sizeof(*test_suite)); @@ -220,6 +292,7 @@ static void append_script(int dir_fd, const char *name,= char *desc, test_suite->desc =3D desc; test_suite->test_cases =3D tests; test_suite->priv =3D strdup_check(filename); + test_suite->needs_mlock =3D needs_mlock; /* Realloc is good enough, though we could realloc by chunks, not that * anyone will ever measure performance here */ result_tmp =3D realloc(*result, (*result_sz + 1) * sizeof(*result_tmp)); diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index f379620069d34f3a..5982c4e62cd37206 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -46,6 +46,12 @@ struct test_suite { struct test_case *test_cases; void *priv; int (*setup)(struct test_suite *suite); + /* + * Set for the suites mapping perf ring buffers, that need room in the + * per user budget set in kernel.perf_event_mlock_kb, see + * shell_test__requisites() for the shell suites. + */ + bool needs_mlock; }; =20 #define DECLARE_SUITE(name) \ @@ -103,6 +109,17 @@ struct test_suite { .test_cases =3D tests__##_name, \ } =20 +#define DEFINE_SUITE_NEEDS_MLOCK(description, _name) \ + struct test_case tests__##_name[] =3D { \ + TEST_CASE(description, _name), \ + { .name =3D NULL, } \ + }; \ + struct test_suite suite__##_name =3D { \ + .desc =3D description, \ + .test_cases =3D tests__##_name, \ + .needs_mlock =3D true, \ + } + /* Tests */ DECLARE_SUITE(vmlinux_matches_kallsyms); DECLARE_SUITE(openat_syscall_event); --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2219D487CC1; Fri, 16 Oct 2026 21:22:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185731; cv=none; b=MIh2t3GcWavwPyRvPb9RiqE+NLYWYC+NoSivU6dqkVz6Vv4aTbZFSC4G9uQtNQoPX698BvjnXaJg1NLt7IeAF00kKl3r24ZPrh3g+DsuAk2pOUv+TJKFtJ9AUI98p5UPxORDybf0LoP1JRCgso/v4DGCm6Gv1du9ZM4DWwUtlBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185731; c=relaxed/simple; bh=OpIlLjiTysxfDVRxktllByqVZ7DOp/4tw+K6KtWohc0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PUssCNjXIU63EyqZZHTgjL7YP3jBsdVloZkvwrovTqhagHIiwtu0tcL+OR6hAvAMb2KNlr/kJMh4W1xPuGGr0skDyLTvE8hxVkCVvTRTeLaRGSZirq45em4feUaaLa/RtZZY4LJbbI5uVC02+xm2faeYhW02Vgg8+Lhnb17dYjQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mec6AhDS; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mec6AhDS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 662821F000C4; Fri, 16 Oct 2026 21:22:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185728; bh=NsYY1h2BPTo9Qr8Q3wCnAt7APVuwPdmAUcMqXqx64nw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=mec6AhDS9cmTcxfqDoyxMYtLxqblsICPoPJ6G09ewIBvilGzpNyxIUEMm+eOL4ZbQ np6i8q8YBEoEhmrRzrqll2UA12t5NACVwilEvDcTmC/4R6AsidvTRzVKG7Tay1C7uq /kg+WjaCtbEnCOFcbcgL5BWk+xh1Rougbs+ieuxJN48IgHGcCmhyLr3Lh8t9fWc48V uT0HZl2WjPpJb5wIJA3lxvzRb+aosrrk/n5IUKY7uMAA3Z6+okeh6HFcoh48ybHD/l 43Y1YmU4PX0LVWFWk9MSx6pI/GQBT4xnAMiTu3uUY4yQ/5aRmpGTbXmDU6UuXuLhFV igTiBc5y7iSbw== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 18/21] perf tests: Mark the C tests mapping perf ring buffers Date: Fri, 16 Oct 2026 18:20:59 -0300 Message-ID: <20261016212102.76550-19-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo The C tests that run 'perf record' in the test process itself map ring buffers and so need room in the per user budget set in kernel.perf_event_mlock_kb: mark them with the new 'needs_mlock' suite flag, read by the turnstile added later in the series, so that they take turns using that budget while the tests that don't map them keep running in parallel. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 1 + tools/perf/tests/openat-syscall-tp-fields.c | 1 + tools/perf/tests/perf-record.c | 1 + tools/perf/tests/perf-time-to-tsc.c | 1 + tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/task-exit.c | 1 + 9 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/bac= kward-ring-buffer.c index 2735cc26d7eec3fb..9314696858ff7c84 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -167,4 +167,4 @@ static int test__backward_ring_buffer(struct test_suite= *test __maybe_unused, in return ret; } =20 -DEFINE_SUITE("Read backward ring buffer", backward_ring_buffer); +DEFINE_SUITE_NEEDS_MLOCK("Read backward ring buffer", backward_ring_buffer= ); diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index c50b526f44fb523f..130cd6021f930597 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -885,4 +885,4 @@ static int test__code_reading(struct test_suite *test _= _maybe_unused, int subtes }; } =20 -DEFINE_SUITE("Object code reading", code_reading); +DEFINE_SUITE_NEEDS_MLOCK("Object code reading", code_reading); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-track= ing.c index b760041bed307859..6d8d8cd57200645d 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -161,4 +161,4 @@ static int test__keep_tracking(struct test_suite *test = __maybe_unused, int subte return err; } =20 -DEFINE_SUITE("Use a dummy software event to keep tracking", keep_tracking); +DEFINE_SUITE_NEEDS_MLOCK("Use a dummy software event to keep tracking", ke= ep_tracking); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 5cec7644952c7dba..02cfe8533ac05036 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -448,4 +448,5 @@ static struct test_case tests__basic_mmap[] =3D { struct test_suite suite__basic_mmap =3D { .desc =3D "mmap interface tests", .test_cases =3D tests__basic_mmap, + .needs_mlock =3D true, }; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests= /openat-syscall-tp-fields.c index 5365889d326f8bc7..1ea336fbc7e7c030 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -160,4 +160,5 @@ static struct test_case tests__syscall_openat_tp_fields= [] =3D { struct test_suite suite__syscall_openat_tp_fields =3D { .desc =3D "syscalls:sys_enter_openat event fields", .test_cases =3D tests__syscall_openat_tp_fields, + .needs_mlock =3D true, }; diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 0cac6ae1a1fc05ed..370dbde08eac71c3 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -372,4 +372,5 @@ static struct test_case tests__PERF_RECORD[] =3D { struct test_suite suite__PERF_RECORD =3D { .desc =3D "PERF_RECORD_* events & perf_sample fields", .test_cases =3D tests__PERF_RECORD, + .needs_mlock =3D true, }; diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-ti= me-to-tsc.c index f8f71fdd32b1bfed..0cefa2df2db728f8 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -218,4 +218,5 @@ static struct test_case time_to_tsc_tests[] =3D { struct test_suite suite__perf_time_to_tsc =3D { .desc =3D "Convert perf time to TSC", .test_cases =3D time_to_tsc_tests, + .needs_mlock =3D true, }; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index d181858816352c67..1b62dae55f076d30 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -149,4 +149,4 @@ static int test__sw_clock_freq(struct test_suite *test = __maybe_unused, int subte return ret; } =20 -DEFINE_SUITE("Software clock events period values", sw_clock_freq); +DEFINE_SUITE_NEEDS_MLOCK("Software clock events period values", sw_clock_f= req); diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 95393edbfe363e5e..9fac426ac2f9eab3 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -158,4 +158,5 @@ struct test_case tests__task_exit[] =3D { struct test_suite suite__task_exit =3D { .desc =3D "Number of exit events of a simple workload", .test_cases =3D tests__task_exit, + .needs_mlock =3D true, }; --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F651487CFF; Fri, 16 Oct 2026 21:22:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185733; cv=none; b=XcHAqSi60AHzm8iGnCY+mexVTewYFZ41AdJVGhZK22QiCi3Hzmrz8MON5SdU7mxCtn2t4ntTmlTMX2SETgCEmbucF1zMcobybbhKtzUW7F9elLQEVB2p6ZTm+qcOm2VxNI38+OthfBoT1sNWFtOeCP9l5hODvjsNC6etGHXiXXo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185733; c=relaxed/simple; bh=3Kb9em5FMFYZuE5472BeV4xNe+VYBgnd1Wzf3UTQtfM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hqeQbb8QTGMAykXR3LfKN3USmsW7zdrpBC7FoMpHD07JCOZJveL0MbM60G2cd9BJK3Mk5BAXBoKOxNo2oW2tbKDb8uvvhNOSbIB5lT9Egub6viOBLVAWSYuIgN+xBYV8gCKna12mxkqVd2c3ik4ORNnqcgyEgCKnj+87YF5L87I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iMipuA1f; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iMipuA1f" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8F0B11F000C5; Fri, 16 Oct 2026 21:22:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185731; bh=hSL1j5xAyoTslHpt3OLlOBt1Mfp8Stg5mYSfwvg6/xA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=iMipuA1fKOprJ2c+CSp5qYx+M/rbzpNVFh21vnwKjBCMI03LKGvy2+Cvfz/3ymVU8 6tNO4bf7jmax31zsUpRKnjd3GpQkpRzE8cfFEBjZpNlkwK6H5pzqUlL/k21ImB4HXE OUYuFs7UUxjzaHcg9DctnsRSCPD9uxjKCKhIq9w5zhTI8mm5YFs+epjUVrWayPTIJ/ 13AYJWaqELTv27ASakesUSSJsRfy0mz/d8yXJQ06fK+1CS9dTPbd3wiaMQsja2QZRL vPUlcHJIobfHAEU6HnD84/eEZWGq1xbLozoEvsPJUTtVywnY76XWrRUuiMyPpNWlNF 9J8GjxVxn5fpw== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 19/21] perf tests: Mark the shell tests not mapping perf ring buffers Date: Fri, 16 Oct 2026 18:21:00 -0300 Message-ID: <20261016212102.76550-20-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo Shell tests run perf, that maps ring buffers, so they take a turn using the per user budget in kernel.perf_event_mlock_kb by default; the ones that don't map them, like the ones running just 'perf stat', say " (no_mlock)" in their description line and thus keep running in parallel with the ones taking turns. The 'perf sched stats' tests are among them, they synthesize the samples from /proc/schedstat without mapping a ring buffer, and the tests already marked " (exclusive)" don't need it, exclusive implies every other requisite and keeps them running alone. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/tests/shell/drm_pmu.sh | 2 +- tools/perf/tests/shell/ftrace.sh | 2 +- tools/perf/tests/shell/kallsyms.sh | 2 +- tools/perf/tests/shell/list.sh | 2 +- tools/perf/tests/shell/perf_sched_stats.sh | 2 +- tools/perf/tests/shell/probe_vfs_getname.sh | 2 +- tools/perf/tests/shell/python-use.sh | 2 +- tools/perf/tests/shell/schedstat_snapshots.sh | 2 +- tools/perf/tests/shell/stat+csv_output.sh | 2 +- tools/perf/tests/shell/stat+csv_summary.sh | 2 +- tools/perf/tests/shell/stat+event_uniquifying.sh | 2 +- tools/perf/tests/shell/stat+json_output.sh | 2 +- tools/perf/tests/shell/stat+shadow_stat.sh | 2 +- tools/perf/tests/shell/stat+std_output.sh | 2 +- tools/perf/tests/shell/stat.sh | 2 +- tools/perf/tests/shell/stat_all_metricgroups.sh | 2 +- tools/perf/tests/shell/stat_all_metrics.sh | 2 +- tools/perf/tests/shell/stat_all_pfm.sh | 2 +- tools/perf/tests/shell/stat_bpf_counters_cgrp.sh | 2 +- tools/perf/tests/shell/stat_metrics_cgrp.sh | 2 +- tools/perf/tests/shell/stat_metrics_values.sh | 2 +- tools/perf/tests/shell/test_ilist_python.sh | 2 +- tools/perf/tests/shell/test_stat_cpi_python.sh | 2 +- tools/perf/tests/shell/test_test_junit_output.sh | 5 ++++- tools/perf/tests/shell/test_uprobe_from_different_cu.sh | 2 +- 25 files changed, 28 insertions(+), 25 deletions(-) diff --git a/tools/perf/tests/shell/drm_pmu.sh b/tools/perf/tests/shell/drm= _pmu.sh index e629fe0e8463d6cc..c827e613fc66ee0f 100755 --- a/tools/perf/tests/shell/drm_pmu.sh +++ b/tools/perf/tests/shell/drm_pmu.sh @@ -1,5 +1,5 @@ #!/bin/bash -# DRM PMU +# DRM PMU (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/ftrace.sh b/tools/perf/tests/shell/ftra= ce.sh index 9f6e590f6437b2d9..84d6126bf94d1e61 100755 --- a/tools/perf/tests/shell/ftrace.sh +++ b/tools/perf/tests/shell/ftrace.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf ftrace tests +# perf ftrace tests (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/kallsyms.sh b/tools/perf/tests/shell/ka= llsyms.sh index d0eb99753f477f57..e3674cc52b30983f 100755 --- a/tools/perf/tests/shell/kallsyms.sh +++ b/tools/perf/tests/shell/kallsyms.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf kallsyms tests +# perf kallsyms tests (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 err=3D0 diff --git a/tools/perf/tests/shell/list.sh b/tools/perf/tests/shell/list.sh index 14a03e0290ed1b4d..d4a0b04154d636f0 100755 --- a/tools/perf/tests/shell/list.sh +++ b/tools/perf/tests/shell/list.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf list tests +# perf list tests (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/perf_sched_stats.sh b/tools/perf/tests/= shell/perf_sched_stats.sh index f13eb0a75b76ef5a..4ede9d701630c719 100755 --- a/tools/perf/tests/shell/perf_sched_stats.sh +++ b/tools/perf/tests/shell/perf_sched_stats.sh @@ -1,5 +1,5 @@ #!/bin/sh -# perf sched stats tests +# perf sched stats tests (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/probe_vfs_getname.sh b/tools/perf/tests= /shell/probe_vfs_getname.sh index c40e5f3f0825b051..43bdd693076b408c 100755 --- a/tools/perf/tests/shell/probe_vfs_getname.sh +++ b/tools/perf/tests/shell/probe_vfs_getname.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Add vfs_getname probe to get syscall args filenames +# Add vfs_getname probe to get syscall args filenames (no_mlock) # SPDX-License-Identifier: GPL-2.0 # Arnaldo Carvalho de Melo , 2017 =20 diff --git a/tools/perf/tests/shell/python-use.sh b/tools/perf/tests/shell/= python-use.sh index 2d6017d5dd9d9eab..ece4d306869ae48e 100755 --- a/tools/perf/tests/shell/python-use.sh +++ b/tools/perf/tests/shell/python-use.sh @@ -1,5 +1,5 @@ #!/bin/bash -# 'import perf' in python +# 'import perf' in python (no_mlock) # SPDX-License-Identifier: GPL-2.0 # Just test if we can load the python binding. set -e diff --git a/tools/perf/tests/shell/schedstat_snapshots.sh b/tools/perf/tes= ts/shell/schedstat_snapshots.sh index a4bdf2673d43ccc0..2050478e3f1a682f 100755 --- a/tools/perf/tests/shell/schedstat_snapshots.sh +++ b/tools/perf/tests/shell/schedstat_snapshots.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Validate CPU and domain pairing in perf sched stats snapshots +# Validate CPU and domain pairing in perf sched stats snapshots (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/s= hell/stat+csv_output.sh index a5b34c42e8d72aff..8beb6c674d055a52 100755 --- a/tools/perf/tests/shell/stat+csv_output.sh +++ b/tools/perf/tests/shell/stat+csv_output.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat CSV output linter +# perf stat CSV output linter (no_mlock) # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) # Tests various perf stat CSV output commands for the # correct number of fields and the CSV separator set to ','. diff --git a/tools/perf/tests/shell/stat+csv_summary.sh b/tools/perf/tests/= shell/stat+csv_summary.sh index 9a4353db3825ede9..6d8beb88fb6f300a 100755 --- a/tools/perf/tests/shell/stat+csv_summary.sh +++ b/tools/perf/tests/shell/stat+csv_summary.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat csv summary test +# perf stat csv summary test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/stat+event_uniquifying.sh b/tools/perf/= tests/shell/stat+event_uniquifying.sh index b5dec6b6da369382..f5c6fa30d8db38d1 100755 --- a/tools/perf/tests/shell/stat+event_uniquifying.sh +++ b/tools/perf/tests/shell/stat+event_uniquifying.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat events uniquifying +# perf stat events uniquifying (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/stat+json_output.sh b/tools/perf/tests/= shell/stat+json_output.sh index 4969ad70b67b6196..cbf7a4ffd7e8ab4f 100755 --- a/tools/perf/tests/shell/stat+json_output.sh +++ b/tools/perf/tests/shell/stat+json_output.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat JSON output linter +# perf stat JSON output linter (no_mlock) # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) # Checks various perf stat JSON output commands for the # correct number of fields. diff --git a/tools/perf/tests/shell/stat+shadow_stat.sh b/tools/perf/tests/= shell/stat+shadow_stat.sh index cabbbf17c662df23..7a58e1507ce27957 100755 --- a/tools/perf/tests/shell/stat+shadow_stat.sh +++ b/tools/perf/tests/shell/stat+shadow_stat.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat metrics (shadow stat) test +# perf stat metrics (shadow stat) test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/stat+std_output.sh b/tools/perf/tests/s= hell/stat+std_output.sh index 64c2b81f02deb18b..b915656a20f69d68 100755 --- a/tools/perf/tests/shell/stat+std_output.sh +++ b/tools/perf/tests/shell/stat+std_output.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat STD output linter +# perf stat STD output linter (no_mlock) # SPDX-License-Identifier: GPL-2.0 # Tests various perf stat STD output commands for # default event and metricgroup diff --git a/tools/perf/tests/shell/stat.sh b/tools/perf/tests/shell/stat.sh index 1f5d4cc05807a247..ac9e031831daca9c 100755 --- a/tools/perf/tests/shell/stat.sh +++ b/tools/perf/tests/shell/stat.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat tests +# perf stat tests (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/stat_all_metricgroups.sh b/tools/perf/t= ests/shell/stat_all_metricgroups.sh index 81bc7070b5ab0d5c..074a437da0ae3dce 100755 --- a/tools/perf/tests/shell/stat_all_metricgroups.sh +++ b/tools/perf/tests/shell/stat_all_metricgroups.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf all metricgroups test +# perf all metricgroups test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 ParanoidAndNotRoot() diff --git a/tools/perf/tests/shell/stat_all_metrics.sh b/tools/perf/tests/= shell/stat_all_metrics.sh index df5fa27b21ae28d8..9d0d4b8a217e6730 100755 --- a/tools/perf/tests/shell/stat_all_metrics.sh +++ b/tools/perf/tests/shell/stat_all_metrics.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf all metrics test +# perf all metrics test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 ParanoidAndNotRoot() diff --git a/tools/perf/tests/shell/stat_all_pfm.sh b/tools/perf/tests/shel= l/stat_all_pfm.sh index c08c186af2c42e84..78d8006fb729c8f4 100755 --- a/tools/perf/tests/shell/stat_all_pfm.sh +++ b/tools/perf/tests/shell/stat_all_pfm.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf all libpfm4 events test +# perf all libpfm4 events test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 if perf version --build-options | grep HAVE_LIBPFM | grep -q OFF diff --git a/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh b/tools/perf/= tests/shell/stat_bpf_counters_cgrp.sh index febe3af0644157f3..d1b4632c17a3e8e1 100755 --- a/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh +++ b/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat --bpf-counters --for-each-cgroup test +# perf stat --bpf-counters --for-each-cgroup test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/stat_metrics_cgrp.sh b/tools/perf/tests= /shell/stat_metrics_cgrp.sh index 0728f48f21fa971d..75b8e01d11cc7ff3 100755 --- a/tools/perf/tests/shell/stat_metrics_cgrp.sh +++ b/tools/perf/tests/shell/stat_metrics_cgrp.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf stat metrics --for-each-cgroup test +# perf stat metrics --for-each-cgroup test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/stat_metrics_values.sh b/tools/perf/tes= ts/shell/stat_metrics_values.sh index 0982f6b9737a780f..3e073a0e5b9f9b99 100755 --- a/tools/perf/tests/shell/stat_metrics_values.sh +++ b/tools/perf/tests/shell/stat_metrics_values.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf metrics value validation +# perf metrics value validation (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 shelldir=3D$(dirname "$0") diff --git a/tools/perf/tests/shell/test_ilist_python.sh b/tools/perf/tests= /shell/test_ilist_python.sh index 83048474710d2857..a235539c01767ee5 100755 --- a/tools/perf/tests/shell/test_ilist_python.sh +++ b/tools/perf/tests/shell/test_ilist_python.sh @@ -1,5 +1,5 @@ #!/bin/bash -# perf script ilist and perf list --tui test +# perf script ilist and perf list --tui test (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e diff --git a/tools/perf/tests/shell/test_stat_cpi_python.sh b/tools/perf/te= sts/shell/test_stat_cpi_python.sh index 6cb376c92e2f13a7..d1571a20f4683d73 100755 --- a/tools/perf/tests/shell/test_stat_cpi_python.sh +++ b/tools/perf/tests/shell/test_stat_cpi_python.sh @@ -1,6 +1,6 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 -# stat-cpi python test +# stat-cpi python test (no_mlock) =20 set -e =20 diff --git a/tools/perf/tests/shell/test_test_junit_output.sh b/tools/perf/= tests/shell/test_test_junit_output.sh index 38a29e646906e3aa..8fc92e083c342a5c 100755 --- a/tools/perf/tests/shell/test_test_junit_output.sh +++ b/tools/perf/tests/shell/test_test_junit_output.sh @@ -1,6 +1,9 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 -# perf test junit XML output validation +# perf test junit XML output validation (no_mlock) +# +# Waiving the mlock requisite this way holds only while the 'perf test' +# runs below keep picking tests that don't map ring buffers. =20 set -e =20 diff --git a/tools/perf/tests/shell/test_uprobe_from_different_cu.sh b/tool= s/perf/tests/shell/test_uprobe_from_different_cu.sh index 33bf36c4037e45ae..0a02ff9b86d6f326 100755 --- a/tools/perf/tests/shell/test_uprobe_from_different_cu.sh +++ b/tools/perf/tests/shell/test_uprobe_from_different_cu.sh @@ -1,5 +1,5 @@ #!/bin/bash -# test perf probe of function from different CU +# test perf probe of function from different CU (no_mlock) # SPDX-License-Identifier: GPL-2.0 =20 set -e --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A33D447238; Fri, 16 Oct 2026 21:22:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185735; cv=none; b=Qmh3st4szyYF7mPqLdwSsKi4klTjFRrma7dIuWWB95hex4ycSCu22fvfi1qxRAvgRI9i3x+ASinBMTFLTK7+8g0cnoEp3D7zD+Q0vYDlXKg3IJCqRT92nX4MVUX+1XI90++TmARrGxOFV3MqdNN448teLbbE53n0LjUH4h/shBQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185735; c=relaxed/simple; bh=mOgM/f/qnDsKW6XdMSTXIRaN6C4wdEUudWVcYzIPz7U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aVcS5VGb13wHCMaWKBdZIGqepZ2fO30ktNeCBf8pyXcFi12/pVZGMB7ydOPTvHNTP/ILBsxvIjjjNpy9sdzMUrH7q7omJ4SEarMKt3tzXs1wsi0GHgDeCGt8oZ/EcWwgSINLhc8IjnFnCxmCLb5+uhzYrRsbx3t6FnEoVF0JkBo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hHsn8Pdq; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hHsn8Pdq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B7EF41F000C4; Fri, 16 Oct 2026 21:22:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185734; bh=iVUpMp1ZNqzgMx/GKdnUJ/dt5nzO2iLIlc6Czzamges=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=hHsn8Pdq6iEfRuqaROrUg+JfPgZGLKrhzPLZLkePY/XersV0FeCs5YoHSstupcUQ9 lwpHQWM1qnl1XM1z7iFvH1YtvkxaLe//saKjEib6vjFrAdTr5nTgYc/eAGNSq3ORKX fIisJt+NN7cWSvZDpmeQhsRR7HjAvriYNW9A/Vyhoh4NwxK05+bP5ejTpF98kdLoQE sIoH0jCz27rARfMC3592nYv6CWvTaWp5PdH9h63ifAUaFES9geRZSLUqNXdtmCQMUw tLaxPqfBMoNCvaYBu63ucygHSESvEjS8S9Xi5uO6xIIIjnIca0eU5mF0j4NT5QIj3h CgCI2Sj2t/7UA== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 20/21] perf mutex: Add a robust, process-shared mutex initializer Date: Fri, 16 Oct 2026 18:21:01 -0300 Message-ID: <20261016212102.76550-21-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo A mutex held by a process that can die before unlocking it, like the tests forked by 'perf test' that will take turns using the per user budget set in kernel.perf_event_mlock_kb, has to be taken over by the next locker instead of staying locked forever. Robust mutexes, on top of the kernel's robust futexes, do that: when an owner dies while holding it the kernel marks the futex word owner-died and the next pthread_mutex_lock() returns EOWNERDEAD, then mutex_lock() makes it consistent and takes it over; mutex_trylock() and cond_wait() come back with EOWNERDEAD too, so they take it over the same way, with mutex_trylock() giving the mutex back when it can't be taken over: it is held all the same, and a failed trylock must not leak it. Add mutex_init_pshared_robust(), returning false when robust mutexes aren't available: from libcs without the API, gated by a feature check, to musl and glibc refusing them at runtime, when get_robust_list(2) or set_robust_list(2) aren't usable. glibc only sets a flag in pthread_mutexattr_setrobust(), refusing the mutex itself in pthread_mutex_init() with ENOTSUP instead, other errors from it still being reported. Robust mutexes being unavailable isn't an error, just a debug message for whoever then falls back. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/build/Makefile.feature | 1 + tools/build/feature/Makefile | 4 + tools/build/feature/test-all.c | 5 + .../build/feature/test-pthread-mutex-robust.c | 18 ++++ tools/perf/Makefile.config | 4 + tools/perf/util/mutex.c | 101 +++++++++++++++--- tools/perf/util/mutex.h | 6 ++ 7 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 tools/build/feature/test-pthread-mutex-robust.c diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index dbef5b6c4e43c857..4d37d11f674c5bd5 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -85,6 +85,7 @@ FEATURE_TESTS_BASIC :=3D \ libcpupower \ pthread-attr-setaffinity-np \ pthread-barrier \ + pthread-mutex-robust \ reallocarray \ stackprotector-all \ timerfd \ diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 62f9cbf3dee97936..10340a5372242e05 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -41,6 +41,7 @@ FILES=3D \ $(foreach arch,$(LIBUNWIND_ARCHS),test-libunwind-$(arch).bin test= -libunwind-debug-frame-$(arch).bin) \ test-pthread-attr-setaffinity-np.bin \ test-pthread-barrier.bin \ + test-pthread-mutex-robust.bin \ test-stackprotector-all.bin \ test-timerfd.bin \ test-babeltrace2-ctf-writer.bin \ @@ -128,6 +129,9 @@ $(OUTPUT)test-pthread-attr-setaffinity-np.bin: $(OUTPUT)test-pthread-barrier.bin: $(BUILD) -lpthread =20 +$(OUTPUT)test-pthread-mutex-robust.bin: + $(BUILD) -lpthread + $(OUTPUT)test-stackprotector-all.bin: $(BUILD) -fstack-protector-all =20 diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index 0ee16eccd9e05788..4a6890290f7462a7 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c @@ -90,6 +90,10 @@ # include "test-pthread-barrier.c" #undef main =20 +#define main main_test_pthread_mutex_robust +# include "test-pthread-mutex-robust.c" +#undef main + #define main main_test_scandirat # include "test-scandirat.c" #undef main @@ -167,6 +171,7 @@ int main(int argc, char *argv[]) main_test_zlib(); main_test_pthread_attr_setaffinity_np(); main_test_pthread_barrier(); + main_test_pthread_mutex_robust(); main_test_lzma(); main_test_bpf(); main_test_scandirat(); diff --git a/tools/build/feature/test-pthread-mutex-robust.c b/tools/build/= feature/test-pthread-mutex-robust.c new file mode 100644 index 0000000000000000..d8409074713d172b --- /dev/null +++ b/tools/build/feature/test-pthread-mutex-robust.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include + +int main(void) +{ + pthread_mutexattr_t attr; + pthread_mutex_t mtx; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); + pthread_mutex_init(&mtx, &attr); + pthread_mutex_consistent(&mtx); + pthread_mutex_destroy(&mtx); + pthread_mutexattr_destroy(&attr); + + return 0; +} diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index cafc7be79643b26c..b4764f69f47f4d8c 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -417,6 +417,10 @@ ifeq ($(feature-pthread-barrier), 1) CFLAGS +=3D -DHAVE_PTHREAD_BARRIER endif =20 +ifeq ($(feature-pthread-mutex-robust), 1) + CFLAGS +=3D -DHAVE_PTHREAD_MUTEX_ROBUST +endif + ifndef NO_BIONIC $(call feature_check,bionic) ifeq ($(feature-bionic), 1) diff --git a/tools/perf/util/mutex.c b/tools/perf/util/mutex.c index 7aa1f3f55a7d4089..df3b7cce3d5a6a35 100644 --- a/tools/perf/util/mutex.c +++ b/tools/perf/util/mutex.c @@ -17,37 +17,106 @@ static void check_err(const char *fn, int err) =20 #define CHECK_ERR(err) check_err(__func__, err) =20 -static void __mutex_init(struct mutex *mtx, bool pshared, bool recursive) +#ifdef HAVE_PTHREAD_MUTEX_ROBUST +/* + * A robust mutex whose owner died while holding it comes back as EOWNERDE= AD, + * with the caller holding it: make it consistent, which takes it over; fa= iling + * that, a give_up caller unlocks it, leaving it ENOTRECOVERABLE, not leak= ed. + */ +static int mutex_take_over(struct mutex *mtx, int err, bool give_up) +{ + if (err !=3D EOWNERDEAD) + return err; + + pr_debug("mutex: taking over one left by a dead owner\n"); + err =3D pthread_mutex_consistent(&mtx->lock); + if (err && give_up) + CHECK_ERR(pthread_mutex_unlock(&mtx->lock)); + + return err; +} +#else +#define mutex_take_over(mtx, err, give_up) ((void)(mtx), (void)(give_up), = (err)) +#endif + +static bool __mutex_init(struct mutex *mtx, bool pshared, bool recursive, = bool robust) { pthread_mutexattr_t attr; + bool ok =3D false, robust_unavailable =3D false; + int err; =20 - CHECK_ERR(pthread_mutexattr_init(&attr)); + err =3D pthread_mutexattr_init(&attr); + if (err) + goto out; =20 #ifndef NDEBUG /* In normal builds enable error checking, such as recursive usage. */ - CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); + err =3D pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); + if (err) + goto out_destroy; #endif - if (recursive) - CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); - if (pshared) - CHECK_ERR(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); - CHECK_ERR(pthread_mutex_init(&mtx->lock, &attr)); + if (recursive) { + err =3D pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + if (err) + goto out_destroy; + } + if (pshared) { + err =3D pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + if (err) + goto out_destroy; + } + if (robust) { +#ifdef HAVE_PTHREAD_MUTEX_ROBUST + err =3D pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); + if (err) + robust_unavailable =3D true; +#else + robust_unavailable =3D true; +#endif + if (robust_unavailable) + goto out_destroy; + } + + err =3D pthread_mutex_init(&mtx->lock, &attr); + if (!err) + ok =3D true; + else if (robust && pshared && err =3D=3D ENOTSUP) + /* + * glibc refuses a robust process shared mutex with ENOTSUP when + * set_robust_list(2) isn't usable, i.e. when the machine provides + * no robust mutexes for the process shared case: an unavailable + * API, not a bad request. + */ + robust_unavailable =3D true; +out_destroy: CHECK_ERR(pthread_mutexattr_destroy(&attr)); +out: + if (robust_unavailable) + pr_debug("mutex: robust mutexes aren't available\n"); + else if (err) + CHECK_ERR(err); + + return ok; } =20 void mutex_init(struct mutex *mtx) { - __mutex_init(mtx, /*pshared=3D*/false, /*recursive=3D*/false); + __mutex_init(mtx, /*pshared=3D*/false, /*recursive=3D*/false, /*robust=3D= */false); } =20 void mutex_init_pshared(struct mutex *mtx) { - __mutex_init(mtx, /*pshared=3D*/true, /*recursive=3D*/false); + __mutex_init(mtx, /*pshared=3D*/true, /*recursive=3D*/false, /*robust=3D*= /false); } =20 void mutex_init_recursive(struct mutex *mtx) { - __mutex_init(mtx, /*pshared=3D*/false, /*recursive=3D*/true); + __mutex_init(mtx, /*pshared=3D*/false, /*recursive=3D*/true, /*robust=3D*= /false); +} + +bool mutex_init_pshared_robust(struct mutex *mtx) +{ + return __mutex_init(mtx, /*pshared=3D*/true, /*recursive=3D*/false, /*rob= ust=3D*/true); } =20 void mutex_destroy(struct mutex *mtx) @@ -58,7 +127,8 @@ void mutex_destroy(struct mutex *mtx) void mutex_lock(struct mutex *mtx) NO_THREAD_SAFETY_ANALYSIS { - CHECK_ERR(pthread_mutex_lock(&mtx->lock)); + CHECK_ERR(mutex_take_over(mtx, pthread_mutex_lock(&mtx->lock), + /*give_up=3D*/false)); } =20 void mutex_unlock(struct mutex *mtx) @@ -69,7 +139,8 @@ void mutex_unlock(struct mutex *mtx) =20 bool mutex_trylock(struct mutex *mtx) { - int ret =3D pthread_mutex_trylock(&mtx->lock); + int ret =3D mutex_take_over(mtx, pthread_mutex_trylock(&mtx->lock), + /*give_up=3D*/true); =20 if (ret =3D=3D 0) return true; /* Lock acquired. */ @@ -111,7 +182,9 @@ void cond_destroy(struct cond *cnd) =20 void cond_wait(struct cond *cnd, struct mutex *mtx) { - CHECK_ERR(pthread_cond_wait(&cnd->cond, &mtx->lock)); + CHECK_ERR(mutex_take_over(mtx, + pthread_cond_wait(&cnd->cond, &mtx->lock), + /*give_up=3D*/false)); } =20 void cond_signal(struct cond *cnd) diff --git a/tools/perf/util/mutex.h b/tools/perf/util/mutex.h index 5554937675886ef3..5de1065ea2b94bbb 100644 --- a/tools/perf/util/mutex.h +++ b/tools/perf/util/mutex.h @@ -142,6 +142,12 @@ void mutex_init(struct mutex *mtx); void mutex_init_pshared(struct mutex *mtx); /* Initializes a mutex that may be recursively held on the same thread. */ void mutex_init_recursive(struct mutex *mtx); +/* + * As mutex_init_pshared(), plus the robust attribute: a process dying whi= le + * holding it doesn't leave it locked, but the takeover isn't reported and= the + * data it protects may be mid update. Returns false when not available. + */ +bool mutex_init_pshared_robust(struct mutex *mtx); void mutex_destroy(struct mutex *mtx); =20 void mutex_lock(struct mutex *mtx) EXCLUSIVE_LOCK_FUNCTION(*mtx); --=20 2.55.0 From nobody Sat Oct 24 14:02:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DC2C248DB24; Fri, 16 Oct 2026 21:22:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185739; cv=none; b=Vq8nIpuHniomB49P5r8j7cjCngGSY4i/um7YZrwSGwD/jBQ/3DIRTM9HIugMEjP/HzKckjveXxycMn7zAC2h9vb2ZXzFb7p0AMNEK7jfUR+mPvK3njXzE5MwLiaesklSPIQp+UOXuBzlOVUlrZUO+d2n+DD2MW2YvKToULTTaSA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792185739; c=relaxed/simple; bh=Vo+a6erBo/9sE0oL8mSi84oy2qqTRdxx79RGL6NB97k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tMFUMGOixd5nb7ZjVis5pJSc3Gk71Fg1gOsCb1edllqUfhabMoRqirhPnBFLb5H0tWXpHE6VELjtPXehpZXTwxykz9uQZHFccy8BdIZ4r7Id3jFvXVq4s9lTyZsOCrN8UyMdUJXtZWuXcH5luedBjgldlJH5eSs87JWHb99G1wg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=beePJec/; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="beePJec/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E16C51F000C5; Fri, 16 Oct 2026 21:22:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1792185737; bh=+qI1LGhCvmSQKlL30zv52EctO4QIkrOMPQUs2hmBAUk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=beePJec/38h0EmWq+dspt4U84tzAtx1fue1Ua4WhFnd1PmSz6z7XQvAK23aMGc7ES Qm+YNyN09EMJFKfPtAm/lhLwa5E282tulyHh12Kgd8nl2lGmq26dGHvz9TDiVhy15B a2juhKXE4L7Xop7FPMVAHeUSPQTw3xdAcNyz1dSV8sWYdmHCYY2Q75u8+ZL0gk7gCE ct0hbHptfZgpaQu2XGri5R1tqT0hARcjc2nwo+XZHtRLVLuHESd/ViIYHSJUn7QK+t N3t6cXOBlTdqII7/LFfezX5I41Uge9mJHptqk9KQT+RN0ORNnWi7gDfAosq+VpQuUs TI3UulFHw/8GA== From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ingo Molnar , Thomas Gleixner , James Clark , Jiri Olsa , Ian Rogers , Adrian Hunter , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo Subject: [PATCH v4 21/21] perf test: Take turns using the perf mlock budget in the mmaping tests Date: Fri, 16 Oct 2026 18:21:02 -0300 Message-ID: <20261016212102.76550-22-acme@kernel.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261016212102.76550-1-acme@kernel.org> References: <20261016212102.76550-1-acme@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Arnaldo Carvalho de Melo The mmap size used when none is asked for is derived from kernel.perf_event_mlock_kb itself (see perf_event_mlock_kb_in_pages()), that after rounding down to a power of two number of pages ends up being about all of a single CPU's share of that per user budget, so with 'perf test' starting all the selected tests at once, any further mapping done while another test still has its ring buffers mapped fails with: Permission error mapping pages. Consider increasing /proc/sys/kernel/perf_event_mlock_kb, or try again with a smaller value of -m/--mmap_pages. that then shows up as a failure or, worse, as an "unsupp" skip in tests like the attr ones, i.e. as a false pass. Instead of making those tests exclusive, which would serialize them against every other test, keep them running in parallel with the tests that don't map ring buffers and have them take turns using the budget, via a robust, process-shared mutex (see mutex_init_pshared_robust()) in a MAP_SHARED|MAP_ANONYMOUS area that is inherited by the forked test processes: a test killed by a signal doesn't leave the budget locked, the kernel marks the mutex owner-died and the next locker takes it over; a signal that is caught rather than kills ends up the same way, with the longjmp out of child_test_sig_handler() leaving it held until the child exits and the kernel hands it over. Perf's struct mutex is used, so the lock discipline is checked in clang builds via -Wthread-safety; as the thread safety analysis can't verify conditionally held locks, the tests that map ring buffers run through a helper taking the mutex unconditionally around the test function call. Robust mutexes aren't always available, at build time or, as glibc and musl can do when get_robust_list(2)/set_robust_list(2) aren't usable, at run time: in that case the budget is not shared and the tests run as before, failing or skipping on starvation instead of hanging on a lock left behind by a test killed by a signal. Taking turns is unnecessary when nothing can exhaust the budget: once it is spent, whatever maps on top of it is charged against RLIMIT_MEMLOCK and the mapping is refused with EPERM when that runs out too, but only for the processes the kernel is paranoid about and that have no CAP_IPC_LOCK to lift the check, see perf_mmap_calc_limits(). Root, then, has no turns to take: it never has a mapping refused, so the turnstile only buys it the wall clock cost measured below, for a budget nothing is contending for. The area is shared by the tests of one 'perf test' invocation only: a second invocation running at the same time maps its own, so the two don't take turns with each other. The sysctl is left alone. Growing it, to leave room for whatever else the user has running, would need the original value shared between the invocations, so that the last one out puts it back, and it only helps a user who can write the sysctl but lacks CAP_IPC_LOCK, the one capability that lifts the limit. Raising the soft RLIMIT_MEMLOCK to the hard one when a mapping is refused is left for a follow-up: it would buy back the wall clock above without taking turns, where the hard limit allows the raise. None of this is done when just one of the selected tests maps ring buffers, as there is nothing to share the budget with in that case. Taking turns isn't free: a test that hangs while holding the budget now holds with it every other test mapping ring buffers, where before it would fail, or skip, by itself. And there is a cost even when nothing goes wrong, this being the whole suite on a Ryzen 9 9950X3D, kernel 7.2.7, 32 CPUs, with the default 516 KiB budget, before and after taking turns: budget not shared: 42 s wall clock, 72 tests Ok, 28 failed tests take turns: 133 s wall clock, 101 tests Ok, 10 failed Both are non-root runs of the whole series applied, the shell test markings included, and none of the ten failures is about the budget: eight of them pass as root, where it can't be exhausted, and the two that fail there too, the addr2line inline unwinding one, with no branch stack sampling to ask this machine for, and the BPF metadata collection one, whose output isn't what the test expects, are not budget related either. Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo Reviewed-by: Ian Rogers Tested-by: Ian Rogers --- tools/perf/Documentation/perf-test.txt | 5 +- tools/perf/tests/builtin-test.c | 129 ++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentat= ion/perf-test.txt index 156c6e8caa75f153..f66ccd77bfe749e4 100644 --- a/tools/perf/Documentation/perf-test.txt +++ b/tools/perf/Documentation/perf-test.txt @@ -29,8 +29,9 @@ REQUISITES ---------- Shell tests run perf, that maps ring buffers, so they are taken to need ro= om in the per user budget set in kernel.perf_event_mlock_kb, shared by the te= sts -running at the same time. Tests state what they need, or waive, in a comma -separated list in the parens ending their description line, e.g.: +running at the same time, that take turns using it. Tests state what they +need, or waive, in a comma separated list in the parens ending their +description line, e.g.: =20 # perf stat tests (no_mlock) =20 diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index c187772948c41cf7..880eece0bc12386d 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -33,6 +33,8 @@ #include #include =20 +#include + #include "builtin.h" #include "color.h" #include "config.h" @@ -43,6 +45,9 @@ #include "symbol.h" #include "tests-scripts.h" #include "tests.h" +#include "util/cap.h" +#include "util/event.h" +#include "util/mutex.h" #include "util/rlimit.h" #include "util/strbuf.h" #include "util/term.h" @@ -63,6 +68,17 @@ static bool list_requisites; static unsigned int runs_per_test =3D 1; /* Number of lines to include in failure snippet. */ static unsigned int failure_snippet_lines =3D 10; +/* + * The tests mapping ring buffers take turns using their share of + * kernel.perf_event_mlock_kb via this mutex, shared with the forked test + * processes and robust so that a test killed while holding it doesn't lea= ve + * the budget locked, see mutex_init_pshared_robust(). + */ +struct mlock_budget { + struct mutex lock; +}; + +static struct mlock_budget *mlock_budget; const char *dso_to_test; const char *test_objdump_path =3D "objdump"; static const char *workload_control; @@ -379,12 +395,30 @@ static void child_test_sig_handler(int sig) siglongjmp(run_test_jmp_buf, sig); } =20 +static int run_test_case(struct child_test *child) +{ + return test_function(child->test, child->test_case_num)(child->test, chil= d->test_case_num); +} + +/* The thread safety analysis can't express a lock held conditionally. */ +static int run_test_case_mlocked(struct child_test *child) +{ + int err; + + mutex_lock(&mlock_budget->lock); + err =3D run_test_case(child); + mutex_unlock(&mlock_budget->lock); + + return err; +} + static int run_test_child(struct child_process *process) { const int signals[] =3D { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGINT, SIGPIPE, SIGQUIT, SIGSEGV, SIGT= ERM, }; struct child_test *child =3D container_of(process, struct child_test, pro= cess); + bool needs_mlock =3D mlock_budget && child->test->needs_mlock; int err; =20 close_parent_fds(); @@ -401,7 +435,12 @@ static int run_test_child(struct child_process *proces= s) =20 pr_debug("---- start ----\n"); pr_debug("test child forked, pid %d\n", getpid()); - err =3D test_function(child->test, child->test_case_num)(child->test, chi= ld->test_case_num); + + if (needs_mlock) + err =3D run_test_case_mlocked(child); + else + err =3D run_test_case(child); + pr_debug("---- end(%d) ----\n", err); =20 check_leaks(); @@ -1777,6 +1816,92 @@ static struct test_suite **build_suites(void) #undef for_each_suite } =20 +static bool perf_test__shares_mlock_budget(struct test_suite **suites, int= argc, + const char *argv[], struct intlist *skiplist) +{ + int sharing =3D 0; + + /* The selection rules mirrored here are __cmd_test()'s: when they change= , change both. */ + for (int curr_suite =3D 0; suites[curr_suite]; curr_suite++) { + struct test_suite *t =3D suites[curr_suite]; + int curr_test_case; + bool suite_matched; + + if (!t->needs_mlock || intlist__find(skiplist, curr_suite + 1)) + continue; + + suite_matched =3D perf_test__matches(test_description(t, /*test_case=3D*= /-1), + curr_suite, argc, argv); + test_suite__for_each_test_case(t, curr_test_case) { + if (test_exclusive(t, curr_test_case)) + continue; + + if (suite_matched || + perf_test__matches(test_description(t, curr_test_case), + curr_suite, argc, argv)) + sharing +=3D runs_per_test; + } + if (sharing > 1) + return true; + } + return false; +} + +/* + * Once the per user budget set in kernel.perf_event_mlock_kb is spent, wh= at + * maps on top of it is charged against RLIMIT_MEMLOCK and the mapping is + * refused with EPERM when that runs out too, but only for the processes t= he + * kernel is paranoid about and that have no CAP_IPC_LOCK to lift the chec= k, + * see perf_mmap_calc_limits() in the kernel: used by + * perf_test__setup_mlock_budget() below, that has nothing to take turns on + * when neither applies. + */ +static bool perf_test__mlock_budget_exhaustible(void) +{ + if (perf_cap__capable(CAP_IPC_LOCK)) + return false; + + return perf_event_paranoid() > -1; +} + +static void perf_test__setup_mlock_budget(struct test_suite **suites, int = argc, + const char *argv[], struct intlist *skiplist) +{ + /* Nothing can be denied the budget, nothing to take turns for. */ + if (!perf_test__mlock_budget_exhaustible()) { + pr_debug("Not taking turns using the perf mlock budget: nothing can exha= ust it\n"); + return; + } + + /* Nothing runs at the same time, nothing to share the budget with. */ + if (sequential || !perf_test__shares_mlock_budget(suites, argc, argv, ski= plist)) + return; + + mlock_budget =3D mmap(NULL, sizeof(*mlock_budget), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, /*fd=3D*/-1, /*offset=3D*/0); + if (mlock_budget =3D=3D MAP_FAILED) { + mlock_budget =3D NULL; + pr_err("Failed to map the shared area used to take turns using the perf = mlock budget\n"); + return; + } + + if (!mutex_init_pshared_robust(&mlock_budget->lock)) { + munmap(mlock_budget, sizeof(*mlock_budget)); + mlock_budget =3D NULL; + pr_debug("Not taking turns using the perf mlock budget\n"); + } +} + +static void perf_test__teardown_mlock_budget(void) +{ + if (!mlock_budget) + return; + + mutex_destroy(&mlock_budget->lock); + munmap(mlock_budget, sizeof(*mlock_budget)); + mlock_budget =3D NULL; +} + int cmd_test(int argc, const char **argv) { const char *test_usage[] =3D { @@ -1885,7 +2010,9 @@ int cmd_test(int argc, const char **argv) intlist__delete(skiplist); return err ? -err : -ENOMEM; } + perf_test__setup_mlock_budget(suites, argc, argv, skiplist); ret =3D __cmd_test(suites, argc, argv, skiplist); + perf_test__teardown_mlock_budget(); free(suites); intlist__delete(skiplist); return ret; --=20 2.55.0