From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794706886; b=MkSwM1JvCz163AElpv8hj5brPb/w++pAO7yjFaceIENDVmbVTGulKLcKuKY5AhcQDr0S oMAsU9uNEkZK+XPtp+oqkYii1dHQgQU49Utv4t9XfeoWqgWbugUytlcqCjTbxJSpwNs1a svL/HKOpHE5KfJk2IykKlSI3smdSsJ7KYHcXKfBMkvcURNT48NefL0azK1v4breIjrYwb ZXgF8W57jNOCWlY3LU1aIco9qajk++6UZ7wz6hBsxuu37+h7fS3fnca8zBa7jBx14vspZ SH5cKoAJ+zhFxWUsvgxGhFNUH4b3/jvPfyJDhHqWJy59sN2uJ76c1oQLeZULnKt9zxA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794706886; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:Content-Transfer-Encoding; bh=YbW431jVUYKxJtFo/3WpaU2FxmrqRnnJ/Lg3PCsgoUU=; b=AnPyNxPJlom/HW6fRRhRgrdxwWNupqI6I0I3Nrh92DKZrdoh1ftyfk25ZTKT18dzSMob v3o5viKIFzn0V8gagBR4Be3UEaXPrnEgq+3pa0AUcubVkIkpJA0HqyeTLd/WR6Vp3t+WG 8a1nIR1RvRwJDWyRVf/oHZHcg0vHk9aRLv3CCpSN6KianSpTAjbOgi7zw0FRaYPu3nXV4 kAbBaeS4G4K0qiw0KRVdspzQGS8WQ8Igj5rFngTwfasFBPBDNuuSKTHX/08qWS+pF5Mhq dYsJGIK+BgOX3rJLpnberU2t/M55T0EY77lzONTc5ZUJvUkrf+52Q9O7WsE2KL3gcqQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=aqYPnBkS; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5BC19606A88A; Sun, 15 Nov 2026 01:41:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=aqYPnBkS Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8B1CC1F000C6; Sun, 15 Nov 2026 01:41:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1794706886; bh=YbW431jVUYKxJtFo/3WpaU2FxmrqRnnJ/Lg3PCsgoUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=aqYPnBkSGLOGVrtpNsW91QG9ZoN7Kvl5BA11TdeLKc/C+h+lw3byCY/MLIIPPyhIP 7nAhBWbG9+mdQUKNtwT53kzQZgblP151qruX7h6i2isvoNJanQ+VYC11RR80hEfZDw vDRf2gyaC/vx3a8hExhhd4vSjEebjav+hq9ZViagIkILq0Hi8R34dssgSwqvEUxTWD WltjVZ27wHCqckPngvOdYll1VdqbtEmjTGki98lUMSDErmGrVdaJQfeptPZRli3Ocx lgyDi90CZ6DWE9ICn2c35c5FakpGewI32PYNoK3iyFNefehPTBo5o8b4MzB5oOfdD7 E3iNbc11ugudw== 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 , Arnaldo Carvalho de Melo Subject: [PATCH v3 06/12] perf tests: Exercise data type resolution from a register Date: Sat, 14 Nov 2026 22:40:54 -0300 Message-ID: <20261115014102.2879372-7-acme@kernel.org> X-Mailer: git-send-email 2.56.1 In-Reply-To: <20261115014102.2879372-1-acme@kernel.org> References: <20261115014102.2879372-1-acme@kernel.org> X-Mailing-List: linux-perf-users@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit At -O2 a struct pointer lives in a register and DWARF describes it with a register location, while the unoptimized workloads the data type tests profile keep their variables on the stack. Add a regptr workload with a noinline function that gets the pointer from a volatile global, which keeps it in a register, and check that its three member accesses are resolved from that location. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/shell/data_type_register.sh | 64 ++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 2 + tools/perf/tests/workloads/regptr.c | 60 ++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100755 tools/perf/tests/shell/data_type_register.sh create mode 100644 tools/perf/tests/workloads/regptr.c diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 18311673b231e657..b6d31f5f009d206b 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -201,6 +201,7 @@ static struct test_workload *workloads[] = { &workload__false_sharing, &workload__global_data, &workload__flex_array, + &workload__regptr, #ifdef HAVE_RUST_SUPPORT &workload__code_with_type, diff --git a/tools/perf/tests/shell/data_type_register.sh b/tools/perf/tests/shell/data_type_register.sh new file mode 100755 index 0000000000000000..0b7cb4bfe0aacfbe --- /dev/null +++ b/tools/perf/tests/shell/data_type_register.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# perf data type profiling tests for register variables +# SPDX-License-Identifier: GPL-2.0 + +set -e + +perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) +perfout=$(mktemp /tmp/__perf_test.perf.out.XXXXX) + +cleanup() +{ + rm -f "$perfdata" "$perfout" + trap - EXIT TERM INT +} + +trap_cleanup() +{ + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup EXIT TERM INT + +if ! perf check feature -q dwarf; then + echo "Skip: no DWARF (libdw) support" + cleanup + exit 2 +fi + +# No point in recording if the PMU cannot do memory events. +if perf mem record -o /dev/null -- true 2>&1 | \ + grep -q "failed: no PMU supports the memory events"; then + cleanup + exit 2 +fi +if ! perf mem record -o /dev/null -- true 2>/dev/null; then + echo "Skip: cannot record memory events on this PMU" + cleanup + exit 2 +fi + +if ! perf mem record -o "$perfdata" -- perf test -w regptr 1 > /dev/null 2>&1; then + echo "FAIL: perf mem record" + cleanup + exit 1 +fi + +if ! perf annotate --code-with-type -i "$perfdata" --stdio \ + --percent-limit 1 > "$perfout" 2>/dev/null; then + echo "FAIL: perf annotate" + cleanup + exit 1 +fi + +for member in "+0 (a)" "+0x8 (b)" "+0x10 (c)"; do + if ! grep -Fq "# data-type: struct node ${member}" "$perfout"; then + echo "FAIL: member ${member} not resolved from the register" + cleanup + exit 1 + fi +done + +echo "register held access resolved" +cleanup diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index f99910b0f8d93a82..6d284bc79cc31779 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -274,6 +274,7 @@ DECLARE_WORKLOAD(callchain); DECLARE_WORKLOAD(false_sharing); DECLARE_WORKLOAD(global_data); DECLARE_WORKLOAD(flex_array); +DECLARE_WORKLOAD(regptr); #ifdef HAVE_RUST_SUPPORT DECLARE_WORKLOAD(code_with_type); diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index 74a0cbe49dc93533..17189458032c0a17 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -19,6 +19,7 @@ perf-test-y += callchain.o perf-test-y += false_sharing.o perf-test-y += global_data.o perf-test-y += flex_array.o +perf-test-y += regptr.o ifeq ($(CONFIG_RUST_SUPPORT),y) perf-test-y += code_with_type.o @@ -39,3 +40,4 @@ CFLAGS_callchain.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_false_sharing.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_global_data.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_flex_array.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE +CFLAGS_regptr.o = -g -O2 diff --git a/tools/perf/tests/workloads/regptr.c b/tools/perf/tests/workloads/regptr.c new file mode 100644 index 0000000000000000..d5d357b047e1cfd1 --- /dev/null +++ b/tools/perf/tests/workloads/regptr.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * A struct pointer that -O2 keeps in a register, so the member accesses + * have to be resolved from the register's type state and not from a + * stack slot. + * + * See tests/shell/data_type_register.sh. + */ +#include +#include +#include +#include +#include "../tests.h" + +struct node { + long long a; + long long b; + long long c; +}; + +static struct node n; +static struct node *volatile vp; +static volatile unsigned long long reg_sink; +static volatile sig_atomic_t done; + +static void sighandler(int sig __maybe_unused) +{ + done = 1; +} + +static noinline long long touch(struct node *p) +{ + long long sum = 0; + + sum += p->a; + p->b = sum; + sum += p->c; + return sum; +} + +static int regptr(int argc, const char **argv) +{ + unsigned long long sum = 0; + int sec = 1; + + if (argc > 0) + sec = atoi(argv[0]); + + vp = &n; + signal(SIGINT, sighandler); + signal(SIGALRM, sighandler); + alarm(sec); + + while (!done) + sum += touch(vp); + reg_sink = sum; + return 0; +} + +DEFINE_WORKLOAD(regptr); -- 2.56.0