All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Olsa <olsajiri@gmail.com>
To: Jiawei Zhao <phoenix500526@163.com>
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	yonghong.song@linux.dev, bpf@vger.kernel.org,
	linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH bpf-next v10 3/3] selftests/bpf: make usdt_o2 reliably generate SIB USDT arg spec
Date: Fri, 15 Aug 2025 14:44:32 +0200	[thread overview]
Message-ID: <aJ8rsK2-XcPXNX7h@krava> (raw)
In-Reply-To: <20250814160740.96150-4-phoenix500526@163.com>

On Thu, Aug 14, 2025 at 04:07:39PM +0000, Jiawei Zhao wrote:
> usdt_o2 is intended to exercise the SIB (Scale-Index-Base) argument
> handling in libbpf's USDT path. With GCC 13 this reliably produced a
> SIB-form argument (e.g. 8@(%rdx,%rax,8)), but with newer GCC (e.g. 15)
> the compiler frequently optimizes the probe argument into a plain
> register (e.g. 8@%rax) or a stack slot, so the test stops covering the
> SIB code path and becomes flaky across toolchains.
> 
> Force a SIB memory operand in the probe by:
> * placing the base pointer into %rdx and the index into %rax using an
>   empty inline asm with output constraints ("=d", "=a") and matching
>   inputs
> * immediately passing base[idx] to STAP_PROBE1.
> * only enable on x86 platform.
> 
> This makes the compiler encode the operand as SIB (base + index8),
> which in .note.stapsdt shows up as 8@(%rdx,%rax,8) regardless of GCC
> version. A memory clobber and noinline prevent reordering/re-allocation
> around the probe site.
> 
> This change is x86_64-specific and does not alter program semantics; it
> only stabilizes the USDT argument shape so the test consistently
> validates SIB handling. Clang historically prefers stack temporaries for
> such operands, but the selftests build with GCC, and this keeps behavior
> stable across GCC versions without introducing a separate .S file.
> 
> Signed-off-by: Jiawei Zhao <phoenix500526@163.com>
> ---
>  .../selftests/bpf/prog_tests/usdt_o2.c        | 20 ++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
> index f02dcf5188ab..e46d5743ad24 100644
> --- a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
> +++ b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
> @@ -15,11 +15,19 @@ __attribute__((optimize("O2")))
>  int lets_test_this(int);
>  static volatile __u64 array[1] = {test_value};
>  
> -static __always_inline void trigger_func(void)
> +static noinline void trigger_func(void)
>  {
> +#if defined(__x86_64__) || defined(__i386__)
>  	/* Base address + offset + (index * scale) */
> -	for (volatile int i = 0; i <= 0; i++)
> -		STAP_PROBE1(test, usdt1, array[i]);
> +	/* Force SIB addressing with inline assembly */
> +	const __u64 *base;
> +	__u32 idx;
> +	/* binding base to %rdx and idx to %rax */
> +	asm volatile("" : "=d"(base), "=a"(idx) : "0"(array), "1"((__u32)0) : "memory");
> +	STAP_PROBE1(test, usdt1, base[idx]);

hum, I still end up with

	  stapsdt              0x0000002a       NT_STAPSDT (SystemTap probe descriptors)
	    Provider: test
	    Name: usdt1
	    Location: 0x00000000007674c9, Base: 0x00000000035bc698, Semaphore: 0x0000000000000000
	    Arguments: 8@%rax

disasm being:

	static noinline void trigger_func(void)
	{
	  76749f:       55                      push   %rbp
	  7674a0:       48 89 e5                mov    %rsp,%rbp
		/* Base address + offset + (index * scale) */
		/* Force SIB addressing with inline assembly */
		const __u64 *base;
		__u32 idx;
		/* binding base to %rdx and idx to %rax */
		asm volatile("" : "=d"(base), "=a"(idx) : "0"(array), "1"((__u32)0) : "memory");
	  7674a3:       ba 20 49 9c 03          mov    $0x39c4920,%edx
	  7674a8:       b8 00 00 00 00          mov    $0x0,%eax
	  7674ad:       48 89 55 f8             mov    %rdx,-0x8(%rbp)
	  7674b1:       89 45 f4                mov    %eax,-0xc(%rbp)
		STAP_PROBE1(test, usdt1, base[idx]);
	  7674b4:       8b 45 f4                mov    -0xc(%rbp),%eax
	  7674b7:       48 8d 14 c5 00 00 00    lea    0x0(,%rax,8),%rdx
	  7674be:       00
	  7674bf:       48 8b 45 f8             mov    -0x8(%rbp),%rax
	  7674c3:       48 01 d0                add    %rdx,%rax
	  7674c6:       48 8b 00                mov    (%rax),%rax
	  7674c9:       90                      nop
	#else
		STAP_PROBE1(test, usdt1, array[0]);
	#endif
	}
	  7674ca:       90                      nop
	  7674cb:       5d                      pop    %rbp
	  7674cc:       c3                      ret


I wonder we could also try to bring in Andrii's usdt.h [1] and overload usdt
arguments like outlined in the hack below (full code in [1])

we will probably need smarter and sustainable change, but you I guess you get
the idea

jirka


[1] https://github.com/anakryiko/usdt
[2] git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git usdt_hack
---
diff --git a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
index e46d5743ad24..7bb098c37de5 100644
--- a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
+++ b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
@@ -4,6 +4,8 @@
 
 #include "../sdt.h"
 #include "test_usdt_o2.skel.h"
+#define USDT_ARGS ".asciz \"(,%%rax,8)\"\n"
+#include "usdt.h"
 
 #if defined(__GNUC__) && !defined(__clang__)
 __attribute__((optimize("O2")))
@@ -28,6 +30,7 @@ static noinline void trigger_func(void)
 #else
 	STAP_PROBE1(test, usdt1, array[0]);
 #endif
+	USDT(krava, test1, 1, 2);
 }
 
 static void basic_sib_usdt(void)
diff --git a/tools/testing/selftests/bpf/usdt.h b/tools/testing/selftests/bpf/usdt.h
index 549d1f774810..960ebd6aa88b 100644
--- a/tools/testing/selftests/bpf/usdt.h
+++ b/tools/testing/selftests/bpf/usdt.h
@@ -403,6 +403,10 @@ struct usdt_sema { volatile unsigned short active; };
 	__asm__ __volatile__ ("" :: "m" (sema));
 #endif
 
+#ifndef USDT_ARGS
+#define USDT_ARGS __usdt_asm_args(__VA_ARGS__)
+#endif
+
 /* main USDT definition (nop and .note.stapsdt metadata) */
 #define __usdt_probe(group, name, sema_def, sema, ...) do {					\
 	sema_def(sema)										\
@@ -418,7 +422,7 @@ struct usdt_sema { volatile unsigned short active; };
 	__usdt_asm1(		__usdt_asm_addr sema)						\
 	__usdt_asm_strz(group)									\
 	__usdt_asm_strz(name)									\
-	__usdt_asm_args(__VA_ARGS__)								\
+	USDT_ARGS										\
 	__usdt_asm1(		.ascii "\0")							\
 	__usdt_asm1(994:	.balign 4)							\
 	__usdt_asm1(		.popsection)							\

  reply	other threads:[~2025-08-15 12:44 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-14 16:07 [PATCH bpf-next v10 0/3] libbpf: fix USDT SIB argument handling causing unrecognized register error Jiawei Zhao
2025-08-14 16:07 ` [PATCH bpf-next v10 1/3] " Jiawei Zhao
2025-08-14 16:07 ` [PATCH bpf-next v10 2/3] selftests/bpf: Add an usdt_o2 test case in selftests to cover SIB handling logic Jiawei Zhao
2025-08-14 16:07 ` [PATCH bpf-next v10 3/3] selftests/bpf: make usdt_o2 reliably generate SIB USDT arg spec Jiawei Zhao
2025-08-15 12:44   ` Jiri Olsa [this message]
2025-08-16  7:04     ` 赵佳炜
2025-08-18  6:56       ` Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aJ8rsK2-XcPXNX7h@krava \
    --to=olsajiri@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=phoenix500526@163.com \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.