diff mbox series

[bpf-next,2/2] selftests/bpf: Add a test for arena range tree algorithm

Message ID 20241108025616.17625-3-alexei.starovoitov@gmail.com (mailing list archive)
State Accepted
Commit e58358afa84e8e271a296459d35d1715c7572013
Delegated to: BPF
Headers show
Series bpf: range_tree for bpf arena | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
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: 5 this patch: 5
netdev/build_tools success Errors and warnings before: 0 (+0) this patch: 0 (+0)
netdev/cc_maintainers warning 11 maintainers not CCed: mykolal@fb.com kpsingh@kernel.org martin.lau@linux.dev shuah@kernel.org sdf@fomichev.me linux-kselftest@vger.kernel.org john.fastabend@gmail.com song@kernel.org jolsa@kernel.org haoluo@google.com yonghong.song@linux.dev
netdev/build_clang success Errors and warnings before: 3 this patch: 3
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: 3 this patch: 3
netdev/checkpatch warning CHECK: Alignment should match open parenthesis
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-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-30 success 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-31 success 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-36 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-22 success 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-29 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-25 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-32 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-39 success 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-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-23 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-40 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-38 success 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-21 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 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-20 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success 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-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-13 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-15 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 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-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-17 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-18 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-next-VM_Test-27 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-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-net-PR success PR summary
bpf/vmtest-bpf-net-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-net-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-net-VM_Test-4 pending Logs for set-matrix
bpf/vmtest-bpf-net-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-net-VM_Test-2 success Logs for Unittests

Commit Message

Alexei Starovoitov Nov. 8, 2024, 2:56 a.m. UTC
From: Alexei Starovoitov <ast@kernel.org>

Add a test that verifies specific behavior of arena range tree
algorithm and just existing bif_alloc1 test due to use
of global data in arena.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 .../bpf/progs/verifier_arena_large.c          | 110 +++++++++++++++++-
 1 file changed, 108 insertions(+), 2 deletions(-)

Comments

Kumar Kartikeya Dwivedi Nov. 13, 2024, 4:04 p.m. UTC | #1
On Fri, 8 Nov 2024 at 03:56, Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> From: Alexei Starovoitov <ast@kernel.org>
>
> Add a test that verifies specific behavior of arena range tree
> algorithm and just existing bif_alloc1 test due to use
> of global data in arena.
>
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> ---

Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Jiri Olsa Nov. 15, 2024, 12:20 p.m. UTC | #2
On Thu, Nov 07, 2024 at 06:56:16PM -0800, Alexei Starovoitov wrote:
> From: Alexei Starovoitov <ast@kernel.org>
> 
> Add a test that verifies specific behavior of arena range tree
> algorithm and just existing bif_alloc1 test due to use
> of global data in arena.
> 
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> ---
>  .../bpf/progs/verifier_arena_large.c          | 110 +++++++++++++++++-
>  1 file changed, 108 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> index 6065f862d964..8a9af79db884 100644
> --- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> +++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> @@ -29,12 +29,12 @@ int big_alloc1(void *ctx)
>  	if (!page1)
>  		return 1;
>  	*page1 = 1;
> -	page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
> +	page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE * 2,
>  				      1, NUMA_NO_NODE, 0);
>  	if (!page2)
>  		return 2;
>  	*page2 = 2;
> -	no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE,
> +	no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
>  					1, NUMA_NO_NODE, 0);
>  	if (no_page)
>  		return 3;
> @@ -66,4 +66,110 @@ int big_alloc1(void *ctx)
>  #endif
>  	return 0;
>  }
> +
> +#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
> +#define PAGE_CNT 100
> +__u8 __arena * __arena page[PAGE_CNT]; /* occupies the first page */
> +__u8 __arena *base;
> +
> +/*
> + * Check that arena's range_tree algorithm allocates pages sequentially
> + * on the first pass and then fills in all gaps on the second pass.
> + */
> +__noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
> +		int max_idx, int step)
> +{
> +	__u8 __arena *pg;
> +	int i, pg_idx;
> +
> +	for (i = 0; i < page_cnt; i++) {
> +		pg = bpf_arena_alloc_pages(&arena, NULL, pages_atonce,
> +					   NUMA_NO_NODE, 0);
> +		if (!pg)
> +			return step;
> +		pg_idx = (pg - base) / PAGE_SIZE;

hi,
I'm getting compile error below with clang 20.0.0:

      CLNG-BPF [test_progs] verifier_arena_large.bpf.o
    progs/verifier_arena_large.c:90:24: error: unsupported signed division, please convert to unsigned div/mod.
       90 |                 pg_idx = (pg - base) / PAGE_SIZE;

should we just convert it to unsigned div like below?

also I saw recent llvm change [1] that might help, I'll give it a try

jirka


[1] 38a8000f30aa [BPF] Use mul for certain div/mod operations (#110712)
---
diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
index 8a9af79db884..e743d008697e 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
@@ -87,7 +87,7 @@ __noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
 					   NUMA_NO_NODE, 0);
 		if (!pg)
 			return step;
-		pg_idx = (pg - base) / PAGE_SIZE;
+		pg_idx = (unsigned int) (pg - base) / PAGE_SIZE;
 		if (first_pass) {
 			/* Pages must be allocated sequentially */
 			if (pg_idx != i)
Yonghong Song Nov. 15, 2024, 4:30 p.m. UTC | #3
On 11/15/24 4:20 AM, Jiri Olsa wrote:
> On Thu, Nov 07, 2024 at 06:56:16PM -0800, Alexei Starovoitov wrote:
>> From: Alexei Starovoitov <ast@kernel.org>
>>
>> Add a test that verifies specific behavior of arena range tree
>> algorithm and just existing bif_alloc1 test due to use
>> of global data in arena.
>>
>> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
>> ---
>>   .../bpf/progs/verifier_arena_large.c          | 110 +++++++++++++++++-
>>   1 file changed, 108 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
>> index 6065f862d964..8a9af79db884 100644
>> --- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
>> +++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
>> @@ -29,12 +29,12 @@ int big_alloc1(void *ctx)
>>   	if (!page1)
>>   		return 1;
>>   	*page1 = 1;
>> -	page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
>> +	page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE * 2,
>>   				      1, NUMA_NO_NODE, 0);
>>   	if (!page2)
>>   		return 2;
>>   	*page2 = 2;
>> -	no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE,
>> +	no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
>>   					1, NUMA_NO_NODE, 0);
>>   	if (no_page)
>>   		return 3;
>> @@ -66,4 +66,110 @@ int big_alloc1(void *ctx)
>>   #endif
>>   	return 0;
>>   }
>> +
>> +#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
>> +#define PAGE_CNT 100
>> +__u8 __arena * __arena page[PAGE_CNT]; /* occupies the first page */
>> +__u8 __arena *base;
>> +
>> +/*
>> + * Check that arena's range_tree algorithm allocates pages sequentially
>> + * on the first pass and then fills in all gaps on the second pass.
>> + */
>> +__noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
>> +		int max_idx, int step)
>> +{
>> +	__u8 __arena *pg;
>> +	int i, pg_idx;
>> +
>> +	for (i = 0; i < page_cnt; i++) {
>> +		pg = bpf_arena_alloc_pages(&arena, NULL, pages_atonce,
>> +					   NUMA_NO_NODE, 0);
>> +		if (!pg)
>> +			return step;
>> +		pg_idx = (pg - base) / PAGE_SIZE;
> hi,
> I'm getting compile error below with clang 20.0.0:
>
>        CLNG-BPF [test_progs] verifier_arena_large.bpf.o
>      progs/verifier_arena_large.c:90:24: error: unsupported signed division, please convert to unsigned div/mod.
>         90 |                 pg_idx = (pg - base) / PAGE_SIZE;
>
> should we just convert it to unsigned div like below?
>
> also I saw recent llvm change [1] that might help, I'll give it a try

I am using latest clang 20 and compilation is successful due to the llvm change [1].

>
> jirka
>
>
> [1] 38a8000f30aa [BPF] Use mul for certain div/mod operations (#110712)
> ---
> diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> index 8a9af79db884..e743d008697e 100644
> --- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> +++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> @@ -87,7 +87,7 @@ __noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
>   					   NUMA_NO_NODE, 0);
>   		if (!pg)
>   			return step;
> -		pg_idx = (pg - base) / PAGE_SIZE;
> +		pg_idx = (unsigned int) (pg - base) / PAGE_SIZE;
>   		if (first_pass) {
>   			/* Pages must be allocated sequentially */
>   			if (pg_idx != i)

I think this patch is still good.
Compiling the current verifier_arena_large.c will be okay for llvm <= 18 and >= 20.
But llvm19 will have compilation failure as you mentioned in the above.

So once bpf ci upgrades compiler to llvm19 we will see the above compilation failure.

Please verifify it as well. If this is the case in your side, please submit a patch.
Thanks!
Alexei Starovoitov Nov. 16, 2024, 7 p.m. UTC | #4
On Fri, Nov 15, 2024 at 8:30 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>
>
>
>
> On 11/15/24 4:20 AM, Jiri Olsa wrote:
> > On Thu, Nov 07, 2024 at 06:56:16PM -0800, Alexei Starovoitov wrote:
> >> From: Alexei Starovoitov <ast@kernel.org>
> >>
> >> Add a test that verifies specific behavior of arena range tree
> >> algorithm and just existing bif_alloc1 test due to use
> >> of global data in arena.
> >>
> >> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> >> ---
> >>   .../bpf/progs/verifier_arena_large.c          | 110 +++++++++++++++++-
> >>   1 file changed, 108 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> >> index 6065f862d964..8a9af79db884 100644
> >> --- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> >> +++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> >> @@ -29,12 +29,12 @@ int big_alloc1(void *ctx)
> >>      if (!page1)
> >>              return 1;
> >>      *page1 = 1;
> >> -    page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
> >> +    page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE * 2,
> >>                                    1, NUMA_NO_NODE, 0);
> >>      if (!page2)
> >>              return 2;
> >>      *page2 = 2;
> >> -    no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE,
> >> +    no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
> >>                                      1, NUMA_NO_NODE, 0);
> >>      if (no_page)
> >>              return 3;
> >> @@ -66,4 +66,110 @@ int big_alloc1(void *ctx)
> >>   #endif
> >>      return 0;
> >>   }
> >> +
> >> +#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
> >> +#define PAGE_CNT 100
> >> +__u8 __arena * __arena page[PAGE_CNT]; /* occupies the first page */
> >> +__u8 __arena *base;
> >> +
> >> +/*
> >> + * Check that arena's range_tree algorithm allocates pages sequentially
> >> + * on the first pass and then fills in all gaps on the second pass.
> >> + */
> >> +__noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
> >> +            int max_idx, int step)
> >> +{
> >> +    __u8 __arena *pg;
> >> +    int i, pg_idx;
> >> +
> >> +    for (i = 0; i < page_cnt; i++) {
> >> +            pg = bpf_arena_alloc_pages(&arena, NULL, pages_atonce,
> >> +                                       NUMA_NO_NODE, 0);
> >> +            if (!pg)
> >> +                    return step;
> >> +            pg_idx = (pg - base) / PAGE_SIZE;
> > hi,
> > I'm getting compile error below with clang 20.0.0:
> >
> >        CLNG-BPF [test_progs] verifier_arena_large.bpf.o
> >      progs/verifier_arena_large.c:90:24: error: unsupported signed division, please convert to unsigned div/mod.
> >         90 |                 pg_idx = (pg - base) / PAGE_SIZE;
> >
> > should we just convert it to unsigned div like below?
> >
> > also I saw recent llvm change [1] that might help, I'll give it a try
>
> I am using latest clang 20 and compilation is successful due to the llvm change [1].
>
> >
> > jirka
> >
> >
> > [1] 38a8000f30aa [BPF] Use mul for certain div/mod operations (#110712)
> > ---
> > diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > index 8a9af79db884..e743d008697e 100644
> > --- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > +++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > @@ -87,7 +87,7 @@ __noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
> >                                          NUMA_NO_NODE, 0);
> >               if (!pg)
> >                       return step;
> > -             pg_idx = (pg - base) / PAGE_SIZE;
> > +             pg_idx = (unsigned int) (pg - base) / PAGE_SIZE;
> >               if (first_pass) {
> >                       /* Pages must be allocated sequentially */
> >                       if (pg_idx != i)
>
> I think this patch is still good.
> Compiling the current verifier_arena_large.c will be okay for llvm <= 18 and >= 20.
> But llvm19 will have compilation failure as you mentioned in the above.
>
> So once bpf ci upgrades compiler to llvm19 we will see the above compilation failure.
>
> Please verifify it as well. If this is the case in your side, please submit a patch.

The merge window is about to open, so I pushed the fix myself.
Jiri Olsa Nov. 16, 2024, 8:35 p.m. UTC | #5
On Sat, Nov 16, 2024 at 11:00:21AM -0800, Alexei Starovoitov wrote:
> On Fri, Nov 15, 2024 at 8:30 AM Yonghong Song <yonghong.song@linux.dev> wrote:
> >
> >
> >
> >
> > On 11/15/24 4:20 AM, Jiri Olsa wrote:
> > > On Thu, Nov 07, 2024 at 06:56:16PM -0800, Alexei Starovoitov wrote:
> > >> From: Alexei Starovoitov <ast@kernel.org>
> > >>
> > >> Add a test that verifies specific behavior of arena range tree
> > >> algorithm and just existing bif_alloc1 test due to use
> > >> of global data in arena.
> > >>
> > >> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> > >> ---
> > >>   .../bpf/progs/verifier_arena_large.c          | 110 +++++++++++++++++-
> > >>   1 file changed, 108 insertions(+), 2 deletions(-)
> > >>
> > >> diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > >> index 6065f862d964..8a9af79db884 100644
> > >> --- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > >> +++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > >> @@ -29,12 +29,12 @@ int big_alloc1(void *ctx)
> > >>      if (!page1)
> > >>              return 1;
> > >>      *page1 = 1;
> > >> -    page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
> > >> +    page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE * 2,
> > >>                                    1, NUMA_NO_NODE, 0);
> > >>      if (!page2)
> > >>              return 2;
> > >>      *page2 = 2;
> > >> -    no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE,
> > >> +    no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
> > >>                                      1, NUMA_NO_NODE, 0);
> > >>      if (no_page)
> > >>              return 3;
> > >> @@ -66,4 +66,110 @@ int big_alloc1(void *ctx)
> > >>   #endif
> > >>      return 0;
> > >>   }
> > >> +
> > >> +#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
> > >> +#define PAGE_CNT 100
> > >> +__u8 __arena * __arena page[PAGE_CNT]; /* occupies the first page */
> > >> +__u8 __arena *base;
> > >> +
> > >> +/*
> > >> + * Check that arena's range_tree algorithm allocates pages sequentially
> > >> + * on the first pass and then fills in all gaps on the second pass.
> > >> + */
> > >> +__noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
> > >> +            int max_idx, int step)
> > >> +{
> > >> +    __u8 __arena *pg;
> > >> +    int i, pg_idx;
> > >> +
> > >> +    for (i = 0; i < page_cnt; i++) {
> > >> +            pg = bpf_arena_alloc_pages(&arena, NULL, pages_atonce,
> > >> +                                       NUMA_NO_NODE, 0);
> > >> +            if (!pg)
> > >> +                    return step;
> > >> +            pg_idx = (pg - base) / PAGE_SIZE;
> > > hi,
> > > I'm getting compile error below with clang 20.0.0:
> > >
> > >        CLNG-BPF [test_progs] verifier_arena_large.bpf.o
> > >      progs/verifier_arena_large.c:90:24: error: unsupported signed division, please convert to unsigned div/mod.
> > >         90 |                 pg_idx = (pg - base) / PAGE_SIZE;
> > >
> > > should we just convert it to unsigned div like below?
> > >
> > > also I saw recent llvm change [1] that might help, I'll give it a try
> >
> > I am using latest clang 20 and compilation is successful due to the llvm change [1].
> >
> > >
> > > jirka
> > >
> > >
> > > [1] 38a8000f30aa [BPF] Use mul for certain div/mod operations (#110712)
> > > ---
> > > diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > > index 8a9af79db884..e743d008697e 100644
> > > --- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > > +++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
> > > @@ -87,7 +87,7 @@ __noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
> > >                                          NUMA_NO_NODE, 0);
> > >               if (!pg)
> > >                       return step;
> > > -             pg_idx = (pg - base) / PAGE_SIZE;
> > > +             pg_idx = (unsigned int) (pg - base) / PAGE_SIZE;
> > >               if (first_pass) {
> > >                       /* Pages must be allocated sequentially */
> > >                       if (pg_idx != i)
> >
> > I think this patch is still good.
> > Compiling the current verifier_arena_large.c will be okay for llvm <= 18 and >= 20.
> > But llvm19 will have compilation failure as you mentioned in the above.
> >
> > So once bpf ci upgrades compiler to llvm19 we will see the above compilation failure.
> >
> > Please verifify it as well. If this is the case in your side, please submit a patch.
> 
> The merge window is about to open, so I pushed the fix myself.

thanks, also the [1] llvm change fixes the build for me

jirka
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
index 6065f862d964..8a9af79db884 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
@@ -29,12 +29,12 @@  int big_alloc1(void *ctx)
 	if (!page1)
 		return 1;
 	*page1 = 1;
-	page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
+	page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE * 2,
 				      1, NUMA_NO_NODE, 0);
 	if (!page2)
 		return 2;
 	*page2 = 2;
-	no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE,
+	no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE,
 					1, NUMA_NO_NODE, 0);
 	if (no_page)
 		return 3;
@@ -66,4 +66,110 @@  int big_alloc1(void *ctx)
 #endif
 	return 0;
 }
+
+#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
+#define PAGE_CNT 100
+__u8 __arena * __arena page[PAGE_CNT]; /* occupies the first page */
+__u8 __arena *base;
+
+/*
+ * Check that arena's range_tree algorithm allocates pages sequentially
+ * on the first pass and then fills in all gaps on the second pass.
+ */
+__noinline int alloc_pages(int page_cnt, int pages_atonce, bool first_pass,
+		int max_idx, int step)
+{
+	__u8 __arena *pg;
+	int i, pg_idx;
+
+	for (i = 0; i < page_cnt; i++) {
+		pg = bpf_arena_alloc_pages(&arena, NULL, pages_atonce,
+					   NUMA_NO_NODE, 0);
+		if (!pg)
+			return step;
+		pg_idx = (pg - base) / PAGE_SIZE;
+		if (first_pass) {
+			/* Pages must be allocated sequentially */
+			if (pg_idx != i)
+				return step + 100;
+		} else {
+			/* Allocator must fill into gaps */
+			if (pg_idx >= max_idx || (pg_idx & 1))
+				return step + 200;
+		}
+		*pg = pg_idx;
+		page[pg_idx] = pg;
+		cond_break;
+	}
+	return 0;
+}
+
+SEC("syscall")
+__success __retval(0)
+int big_alloc2(void *ctx)
+{
+	__u8 __arena *pg;
+	int i, err;
+
+	base = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+	if (!base)
+		return 1;
+	bpf_arena_free_pages(&arena, (void __arena *)base, 1);
+
+	err = alloc_pages(PAGE_CNT, 1, true, PAGE_CNT, 2);
+	if (err)
+		return err;
+
+	/* Clear all even pages */
+	for (i = 0; i < PAGE_CNT; i += 2) {
+		pg = page[i];
+		if (*pg != i)
+			return 3;
+		bpf_arena_free_pages(&arena, (void __arena *)pg, 1);
+		page[i] = NULL;
+		cond_break;
+	}
+
+	/* Allocate into freed gaps */
+	err = alloc_pages(PAGE_CNT / 2, 1, false, PAGE_CNT, 4);
+	if (err)
+		return err;
+
+	/* Free pairs of pages */
+	for (i = 0; i < PAGE_CNT; i += 4) {
+		pg = page[i];
+		if (*pg != i)
+			return 5;
+		bpf_arena_free_pages(&arena, (void __arena *)pg, 2);
+		page[i] = NULL;
+		page[i + 1] = NULL;
+		cond_break;
+	}
+
+	/* Allocate 2 pages at a time into freed gaps */
+	err = alloc_pages(PAGE_CNT / 4, 2, false, PAGE_CNT, 6);
+	if (err)
+		return err;
+
+	/* Check pages without freeing */
+	for (i = 0; i < PAGE_CNT; i += 2) {
+		pg = page[i];
+		if (*pg != i)
+			return 7;
+		cond_break;
+	}
+
+	pg = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+
+	if (!pg)
+		return 8;
+	/*
+	 * The first PAGE_CNT pages are occupied. The new page
+	 * must be above.
+	 */
+	if ((pg - base) / PAGE_SIZE < PAGE_CNT)
+		return 9;
+	return 0;
+}
+#endif
 char _license[] SEC("license") = "GPL";