diff mbox series

[bpf-next] selftests/bpf: Fix tests after change in struct file

Message ID 20250327185528.1740787-1-song@kernel.org (mailing list archive)
State Accepted
Commit bd06a13f44e15e2e83561ea165061c445a15bd9e
Delegated to: BPF
Headers show
Series [bpf-next] selftests/bpf: Fix tests after change in struct file | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success Errors and warnings before: 26 (+0) this patch: 26 (+0)
netdev/cc_maintainers warning 13 maintainers not CCed: sdf@fomichev.me linux-kselftest@vger.kernel.org yonghong.song@linux.dev eddyz87@gmail.com jolsa@kernel.org martin.lau@linux.dev haoluo@google.com toke@redhat.com mykolal@fb.com john.fastabend@gmail.com vmalik@redhat.com shuah@kernel.org kpsingh@kernel.org
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: Unknown commit id 'e249056c91a2', maybe rebased or not pulled? WARNING: Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / GCC BPF
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-11 success Logs for aarch64-gcc / veristat-kernel
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / GCC BPF
bpf/vmtest-bpf-next-VM_Test-18 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for aarch64-gcc / veristat-meta
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-20 success Logs for s390x-gcc / veristat-meta
bpf/vmtest-bpf-next-VM_Test-19 success Logs for s390x-gcc / veristat-kernel
bpf/vmtest-bpf-next-VM_Test-21 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for x86_64-gcc / veristat-kernel / x86_64-gcc veristat_kernel
bpf/vmtest-bpf-next-VM_Test-32 success Logs for x86_64-gcc / veristat-meta / x86_64-gcc veristat_meta
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-next-VM_Test-40 success Logs for x86_64-llvm-17 / veristat-kernel
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-17 / veristat-meta
bpf/vmtest-bpf-next-VM_Test-44 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-next-VM_Test-43 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-50 success Logs for x86_64-llvm-18 / veristat-kernel
bpf/vmtest-bpf-next-VM_Test-51 success Logs for x86_64-llvm-18 / veristat-meta
bpf/vmtest-bpf-next-VM_Test-27 fail Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / GCC BPF / GCC BPF
bpf/vmtest-bpf-next-VM_Test-30 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / GCC BPF / GCC BPF
bpf/vmtest-bpf-next-VM_Test-42 success Logs for x86_64-llvm-18 / GCC BPF / GCC BPF
bpf/vmtest-bpf-next-VM_Test-26 fail Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-16 fail Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 fail Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-39 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-37 fail Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-38 fail Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-45 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-49 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-47 fail Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-48 fail Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-46 fail Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18

Commit Message

Song Liu March 27, 2025, 6:55 p.m. UTC
Change in struct file [1] moves f_ref to the 3rd cache line. This makes
deferencing file pointer as a 8-byte variable invalid, because
btf_struct_walk() will walk into f_lock, which is 4-byte long.

Fix the selftests to deference the file pointer as a 4-byte variable.

[1] commit e249056c91a2 ("fs: place f_ref to 3rd cache line in struct
                          file to resolve false sharing")
Reported-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Song Liu <song@kernel.org>
---
 tools/testing/selftests/bpf/progs/test_module_attach.c    | 2 +-
 tools/testing/selftests/bpf/progs/test_subprogs_extable.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

Comments

Andrii Nakryiko March 28, 2025, 5:30 p.m. UTC | #1
On Thu, Mar 27, 2025 at 11:55 AM Song Liu <song@kernel.org> wrote:
>
> Change in struct file [1] moves f_ref to the 3rd cache line. This makes
> deferencing file pointer as a 8-byte variable invalid, because
> btf_struct_walk() will walk into f_lock, which is 4-byte long.
>
> Fix the selftests to deference the file pointer as a 4-byte variable.
>
> [1] commit e249056c91a2 ("fs: place f_ref to 3rd cache line in struct
>                           file to resolve false sharing")
> Reported-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Song Liu <song@kernel.org>
> ---
>  tools/testing/selftests/bpf/progs/test_module_attach.c    | 2 +-
>  tools/testing/selftests/bpf/progs/test_subprogs_extable.c | 6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/progs/test_module_attach.c b/tools/testing/selftests/bpf/progs/test_module_attach.c
> index fb07f5773888..7f3c233943b3 100644
> --- a/tools/testing/selftests/bpf/progs/test_module_attach.c
> +++ b/tools/testing/selftests/bpf/progs/test_module_attach.c
> @@ -117,7 +117,7 @@ int BPF_PROG(handle_fexit_ret, int arg, struct file *ret)
>
>         bpf_probe_read_kernel(&buf, 8, ret);
>         bpf_probe_read_kernel(&buf, 8, (char *)ret + 256);
> -       *(volatile long long *)ret;
> +       *(volatile int *)ret;

we already have `*(volatile int *)&ret->f_mode;` below, do we really
need this int casting case?.. Maybe instead of guessing the size of
file's first field, let's just remove `*(volatile long long *)ret;`
altogether?

>         *(volatile int *)&ret->f_mode;
>         return 0;
>  }
> diff --git a/tools/testing/selftests/bpf/progs/test_subprogs_extable.c b/tools/testing/selftests/bpf/progs/test_subprogs_extable.c
> index e2a21fbd4e44..dcac69f5928a 100644
> --- a/tools/testing/selftests/bpf/progs/test_subprogs_extable.c
> +++ b/tools/testing/selftests/bpf/progs/test_subprogs_extable.c
> @@ -21,7 +21,7 @@ static __u64 test_cb(struct bpf_map *map, __u32 *key, __u64 *val, void *data)
>  SEC("fexit/bpf_testmod_return_ptr")
>  int BPF_PROG(handle_fexit_ret_subprogs, int arg, struct file *ret)
>  {
> -       *(volatile long *)ret;
> +       *(volatile int *)ret;
>         *(volatile int *)&ret->f_mode;
>         bpf_for_each_map_elem(&test_array, test_cb, NULL, 0);
>         triggered++;
> @@ -31,7 +31,7 @@ int BPF_PROG(handle_fexit_ret_subprogs, int arg, struct file *ret)
>  SEC("fexit/bpf_testmod_return_ptr")
>  int BPF_PROG(handle_fexit_ret_subprogs2, int arg, struct file *ret)
>  {
> -       *(volatile long *)ret;
> +       *(volatile int *)ret;
>         *(volatile int *)&ret->f_mode;
>         bpf_for_each_map_elem(&test_array, test_cb, NULL, 0);
>         triggered++;
> @@ -41,7 +41,7 @@ int BPF_PROG(handle_fexit_ret_subprogs2, int arg, struct file *ret)
>  SEC("fexit/bpf_testmod_return_ptr")
>  int BPF_PROG(handle_fexit_ret_subprogs3, int arg, struct file *ret)
>  {
> -       *(volatile long *)ret;
> +       *(volatile int *)ret;
>         *(volatile int *)&ret->f_mode;
>         bpf_for_each_map_elem(&test_array, test_cb, NULL, 0);
>         triggered++;
> --
> 2.47.1
>
Song Liu March 28, 2025, 5:56 p.m. UTC | #2
> On Mar 28, 2025, at 10:30 AM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote:
> 
> On Thu, Mar 27, 2025 at 11:55 AM Song Liu <song@kernel.org> wrote:
>> 
>> Change in struct file [1] moves f_ref to the 3rd cache line. This makes
>> deferencing file pointer as a 8-byte variable invalid, because
>> btf_struct_walk() will walk into f_lock, which is 4-byte long.
>> 
>> Fix the selftests to deference the file pointer as a 4-byte variable.
>> 
>> [1] commit e249056c91a2 ("fs: place f_ref to 3rd cache line in struct
>>                          file to resolve false sharing")
>> Reported-by: Jakub Kicinski <kuba@kernel.org>
>> Signed-off-by: Song Liu <song@kernel.org>
>> ---
>> tools/testing/selftests/bpf/progs/test_module_attach.c    | 2 +-
>> tools/testing/selftests/bpf/progs/test_subprogs_extable.c | 6 +++---
>> 2 files changed, 4 insertions(+), 4 deletions(-)
>> 
>> diff --git a/tools/testing/selftests/bpf/progs/test_module_attach.c b/tools/testing/selftests/bpf/progs/test_module_attach.c
>> index fb07f5773888..7f3c233943b3 100644
>> --- a/tools/testing/selftests/bpf/progs/test_module_attach.c
>> +++ b/tools/testing/selftests/bpf/progs/test_module_attach.c
>> @@ -117,7 +117,7 @@ int BPF_PROG(handle_fexit_ret, int arg, struct file *ret)
>> 
>>        bpf_probe_read_kernel(&buf, 8, ret);
>>        bpf_probe_read_kernel(&buf, 8, (char *)ret + 256);
>> -       *(volatile long long *)ret;
>> +       *(volatile int *)ret;
> 
> we already have `*(volatile int *)&ret->f_mode;` below, do we really
> need this int casting case?.. Maybe instead of guessing the size of
> file's first field, let's just remove `*(volatile long long *)ret;`
> altogether?

I was assuming the original test covers two cases:
  1) deref ret itself;
  2) deref a member of ret (ret->f_mode);

Therefore, instead of doing something like

   *(volatile long long *)&ret->f_ref;  /* first member of file */

I got current version. 

If we don't need the first case, we sure can remove it. 

Thanks,
Song

> 
>>        *(volatile int *)&ret->f_mode;
>>        return 0;
Alexei Starovoitov March 28, 2025, 6:45 p.m. UTC | #3
On Fri, Mar 28, 2025 at 10:57 AM Song Liu <songliubraving@meta.com> wrote:
>
>
>
> > On Mar 28, 2025, at 10:30 AM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote:
> >
> > On Thu, Mar 27, 2025 at 11:55 AM Song Liu <song@kernel.org> wrote:
> >>
> >> Change in struct file [1] moves f_ref to the 3rd cache line. This makes
> >> deferencing file pointer as a 8-byte variable invalid, because
> >> btf_struct_walk() will walk into f_lock, which is 4-byte long.
> >>
> >> Fix the selftests to deference the file pointer as a 4-byte variable.
> >>
> >> [1] commit e249056c91a2 ("fs: place f_ref to 3rd cache line in struct
> >>                          file to resolve false sharing")
> >> Reported-by: Jakub Kicinski <kuba@kernel.org>
> >> Signed-off-by: Song Liu <song@kernel.org>
> >> ---
> >> tools/testing/selftests/bpf/progs/test_module_attach.c    | 2 +-
> >> tools/testing/selftests/bpf/progs/test_subprogs_extable.c | 6 +++---
> >> 2 files changed, 4 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/tools/testing/selftests/bpf/progs/test_module_attach.c b/tools/testing/selftests/bpf/progs/test_module_attach.c
> >> index fb07f5773888..7f3c233943b3 100644
> >> --- a/tools/testing/selftests/bpf/progs/test_module_attach.c
> >> +++ b/tools/testing/selftests/bpf/progs/test_module_attach.c
> >> @@ -117,7 +117,7 @@ int BPF_PROG(handle_fexit_ret, int arg, struct file *ret)
> >>
> >>        bpf_probe_read_kernel(&buf, 8, ret);
> >>        bpf_probe_read_kernel(&buf, 8, (char *)ret + 256);
> >> -       *(volatile long long *)ret;
> >> +       *(volatile int *)ret;
> >
> > we already have `*(volatile int *)&ret->f_mode;` below, do we really
> > need this int casting case?.. Maybe instead of guessing the size of
> > file's first field, let's just remove `*(volatile long long *)ret;`
> > altogether?
>
> I was assuming the original test covers two cases:
>   1) deref ret itself;
>   2) deref a member of ret (ret->f_mode);
>
> Therefore, instead of doing something like
>
>    *(volatile long long *)&ret->f_ref;  /* first member of file */
>
> I got current version.
>
> If we don't need the first case, we sure can remove it.

The idea of the patch was to test the load from the address
returned from bpf_testmod_return_ptr() twice.
Once as that exact value and another with some offset,
since JIT processing logic is different whether insn->off is zero.
Doing &ret->f_lock /* first member of file */
sort-of works, but the comment will be stale eventually.
I think the current fix is the best:
-       *(volatile long long *)ret;
+       *(volatile int *)ret;

This way the load will have guaranteed insn->off == 0,
and when file layout changes we will notice the breakage right away.
Like happened this time.

So I'm thinking of applying this patch as-is when bpf-next is ready.
patchwork-bot+netdevbpf@kernel.org March 30, 2025, 11:20 p.m. UTC | #4
Hello:

This patch was applied to bpf/bpf.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Thu, 27 Mar 2025 11:55:28 -0700 you wrote:
> Change in struct file [1] moves f_ref to the 3rd cache line. This makes
> deferencing file pointer as a 8-byte variable invalid, because
> btf_struct_walk() will walk into f_lock, which is 4-byte long.
> 
> Fix the selftests to deference the file pointer as a 4-byte variable.
> 
> [1] commit e249056c91a2 ("fs: place f_ref to 3rd cache line in struct
>                           file to resolve false sharing")
> Reported-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Song Liu <song@kernel.org>
> 
> [...]

Here is the summary with links:
  - [bpf-next] selftests/bpf: Fix tests after change in struct file
    https://git.kernel.org/bpf/bpf/c/bd06a13f44e1

You are awesome, thank you!
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/progs/test_module_attach.c b/tools/testing/selftests/bpf/progs/test_module_attach.c
index fb07f5773888..7f3c233943b3 100644
--- a/tools/testing/selftests/bpf/progs/test_module_attach.c
+++ b/tools/testing/selftests/bpf/progs/test_module_attach.c
@@ -117,7 +117,7 @@  int BPF_PROG(handle_fexit_ret, int arg, struct file *ret)
 
 	bpf_probe_read_kernel(&buf, 8, ret);
 	bpf_probe_read_kernel(&buf, 8, (char *)ret + 256);
-	*(volatile long long *)ret;
+	*(volatile int *)ret;
 	*(volatile int *)&ret->f_mode;
 	return 0;
 }
diff --git a/tools/testing/selftests/bpf/progs/test_subprogs_extable.c b/tools/testing/selftests/bpf/progs/test_subprogs_extable.c
index e2a21fbd4e44..dcac69f5928a 100644
--- a/tools/testing/selftests/bpf/progs/test_subprogs_extable.c
+++ b/tools/testing/selftests/bpf/progs/test_subprogs_extable.c
@@ -21,7 +21,7 @@  static __u64 test_cb(struct bpf_map *map, __u32 *key, __u64 *val, void *data)
 SEC("fexit/bpf_testmod_return_ptr")
 int BPF_PROG(handle_fexit_ret_subprogs, int arg, struct file *ret)
 {
-	*(volatile long *)ret;
+	*(volatile int *)ret;
 	*(volatile int *)&ret->f_mode;
 	bpf_for_each_map_elem(&test_array, test_cb, NULL, 0);
 	triggered++;
@@ -31,7 +31,7 @@  int BPF_PROG(handle_fexit_ret_subprogs, int arg, struct file *ret)
 SEC("fexit/bpf_testmod_return_ptr")
 int BPF_PROG(handle_fexit_ret_subprogs2, int arg, struct file *ret)
 {
-	*(volatile long *)ret;
+	*(volatile int *)ret;
 	*(volatile int *)&ret->f_mode;
 	bpf_for_each_map_elem(&test_array, test_cb, NULL, 0);
 	triggered++;
@@ -41,7 +41,7 @@  int BPF_PROG(handle_fexit_ret_subprogs2, int arg, struct file *ret)
 SEC("fexit/bpf_testmod_return_ptr")
 int BPF_PROG(handle_fexit_ret_subprogs3, int arg, struct file *ret)
 {
-	*(volatile long *)ret;
+	*(volatile int *)ret;
 	*(volatile int *)&ret->f_mode;
 	bpf_for_each_map_elem(&test_array, test_cb, NULL, 0);
 	triggered++;