diff mbox series

[v4,bpf-next,6/6] selftests/bpf: check that ->elem_count is non-zero for the hash map

Message ID 20230705160139.19967-7-aspsk@isovalent.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf: add percpu stats for bpf_map | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-31 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-6 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_progs on s390x with gcc
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
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: 8 this patch: 8
netdev/cc_maintainers warning 3 maintainers not CCed: mykolal@fb.com shuah@kernel.org linux-kselftest@vger.kernel.org
netdev/build_clang fail Errors and warnings before: 18 this patch: 18
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: 8 this patch: 8
netdev/checkpatch warning CHECK: Comparison to NULL could be written "map->elem_count"
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-8 success Logs for test_maps on s390x with gcc

Commit Message

Anton Protopopov July 5, 2023, 4:01 p.m. UTC
Previous commits populated the ->elem_count per-cpu pointer for hash maps.
Check that this pointer is non-NULL in an existing map.

Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
---
 tools/testing/selftests/bpf/progs/map_ptr_kern.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Alexei Starovoitov July 6, 2023, 1:26 a.m. UTC | #1
On Wed, Jul 5, 2023 at 9:00 AM Anton Protopopov <aspsk@isovalent.com> wrote:
>
> Previous commits populated the ->elem_count per-cpu pointer for hash maps.
> Check that this pointer is non-NULL in an existing map.
>
> Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
> ---
>  tools/testing/selftests/bpf/progs/map_ptr_kern.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/progs/map_ptr_kern.c b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> index db388f593d0a..d6e234a37ccb 100644
> --- a/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> +++ b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> @@ -33,6 +33,7 @@ struct bpf_map {
>         __u32 value_size;
>         __u32 max_entries;
>         __u32 id;
> +       __s64 *elem_count;
>  } __attribute__((preserve_access_index));
>
>  static inline int check_bpf_map_fields(struct bpf_map *map, __u32 key_size,
> @@ -111,6 +112,8 @@ static inline int check_hash(void)
>
>         VERIFY(check_default_noinline(&hash->map, map));
>
> +       VERIFY(map->elem_count != NULL);
> +

imo that's worse than no test.
Just use kfunc here and get the real count?
Anton Protopopov July 6, 2023, 5:44 a.m. UTC | #2
On Wed, Jul 05, 2023 at 06:26:25PM -0700, Alexei Starovoitov wrote:
> On Wed, Jul 5, 2023 at 9:00 AM Anton Protopopov <aspsk@isovalent.com> wrote:
> >
> > Previous commits populated the ->elem_count per-cpu pointer for hash maps.
> > Check that this pointer is non-NULL in an existing map.
> >
> > Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
> > ---
> >  tools/testing/selftests/bpf/progs/map_ptr_kern.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/tools/testing/selftests/bpf/progs/map_ptr_kern.c b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > index db388f593d0a..d6e234a37ccb 100644
> > --- a/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > +++ b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > @@ -33,6 +33,7 @@ struct bpf_map {
> >         __u32 value_size;
> >         __u32 max_entries;
> >         __u32 id;
> > +       __s64 *elem_count;
> >  } __attribute__((preserve_access_index));
> >
> >  static inline int check_bpf_map_fields(struct bpf_map *map, __u32 key_size,
> > @@ -111,6 +112,8 @@ static inline int check_hash(void)
> >
> >         VERIFY(check_default_noinline(&hash->map, map));
> >
> > +       VERIFY(map->elem_count != NULL);
> > +
> 
> imo that's worse than no test.
> Just use kfunc here and get the real count?

Then, as I mentioned in the previous version, I will have to teach kfuncs to
recognize const_ptr_to_map args just for the sake of this selftest, while we
already testing all functionality in the new selftest for test_maps. So I would
just omit this one. Or am I missing something?
Alexei Starovoitov July 6, 2023, 5:03 p.m. UTC | #3
On Wed, Jul 5, 2023 at 10:42 PM Anton Protopopov <aspsk@isovalent.com> wrote:
>
> On Wed, Jul 05, 2023 at 06:26:25PM -0700, Alexei Starovoitov wrote:
> > On Wed, Jul 5, 2023 at 9:00 AM Anton Protopopov <aspsk@isovalent.com> wrote:
> > >
> > > Previous commits populated the ->elem_count per-cpu pointer for hash maps.
> > > Check that this pointer is non-NULL in an existing map.
> > >
> > > Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
> > > ---
> > >  tools/testing/selftests/bpf/progs/map_ptr_kern.c | 3 +++
> > >  1 file changed, 3 insertions(+)
> > >
> > > diff --git a/tools/testing/selftests/bpf/progs/map_ptr_kern.c b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > > index db388f593d0a..d6e234a37ccb 100644
> > > --- a/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > > +++ b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > > @@ -33,6 +33,7 @@ struct bpf_map {
> > >         __u32 value_size;
> > >         __u32 max_entries;
> > >         __u32 id;
> > > +       __s64 *elem_count;
> > >  } __attribute__((preserve_access_index));
> > >
> > >  static inline int check_bpf_map_fields(struct bpf_map *map, __u32 key_size,
> > > @@ -111,6 +112,8 @@ static inline int check_hash(void)
> > >
> > >         VERIFY(check_default_noinline(&hash->map, map));
> > >
> > > +       VERIFY(map->elem_count != NULL);
> > > +
> >
> > imo that's worse than no test.
> > Just use kfunc here and get the real count?
>
> Then, as I mentioned in the previous version, I will have to teach kfuncs to
> recognize const_ptr_to_map args just for the sake of this selftest, while we
> already testing all functionality in the new selftest for test_maps. So I would
> just omit this one. Or am I missing something?


Don't you want to do:
 val = bpf_map_lookup_elem(map, ...);
 cnt = bpf_map_sum_elem_count(map);

and that's the main use case ?

So teaching the verifier to understand that const_ptr_to_map matches
BTF 'struct bpf_map *' is essential ?
Anton Protopopov July 6, 2023, 5:43 p.m. UTC | #4
On Thu, Jul 06, 2023 at 10:03:30AM -0700, Alexei Starovoitov wrote:
> On Wed, Jul 5, 2023 at 10:42 PM Anton Protopopov <aspsk@isovalent.com> wrote:
> >
> > On Wed, Jul 05, 2023 at 06:26:25PM -0700, Alexei Starovoitov wrote:
> > > On Wed, Jul 5, 2023 at 9:00 AM Anton Protopopov <aspsk@isovalent.com> wrote:
> > > >
> > > > Previous commits populated the ->elem_count per-cpu pointer for hash maps.
> > > > Check that this pointer is non-NULL in an existing map.
> > > >
> > > > Signed-off-by: Anton Protopopov <aspsk@isovalent.com>
> > > > ---
> > > >  tools/testing/selftests/bpf/progs/map_ptr_kern.c | 3 +++
> > > >  1 file changed, 3 insertions(+)
> > > >
> > > > diff --git a/tools/testing/selftests/bpf/progs/map_ptr_kern.c b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > > > index db388f593d0a..d6e234a37ccb 100644
> > > > --- a/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > > > +++ b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
> > > > @@ -33,6 +33,7 @@ struct bpf_map {
> > > >         __u32 value_size;
> > > >         __u32 max_entries;
> > > >         __u32 id;
> > > > +       __s64 *elem_count;
> > > >  } __attribute__((preserve_access_index));
> > > >
> > > >  static inline int check_bpf_map_fields(struct bpf_map *map, __u32 key_size,
> > > > @@ -111,6 +112,8 @@ static inline int check_hash(void)
> > > >
> > > >         VERIFY(check_default_noinline(&hash->map, map));
> > > >
> > > > +       VERIFY(map->elem_count != NULL);
> > > > +
> > >
> > > imo that's worse than no test.
> > > Just use kfunc here and get the real count?
> >
> > Then, as I mentioned in the previous version, I will have to teach kfuncs to
> > recognize const_ptr_to_map args just for the sake of this selftest, while we
> > already testing all functionality in the new selftest for test_maps. So I would
> > just omit this one. Or am I missing something?
> 
> 
> Don't you want to do:
>  val = bpf_map_lookup_elem(map, ...);
>  cnt = bpf_map_sum_elem_count(map);
> 
> and that's the main use case ?

Not sure I understand what this ^ use case is...

Our primary use case is to [periodically] get the number of elements from the
user space. We can do this using an iterator as you've suggested and what is
tested in the added selftest.

> So teaching the verifier to understand that const_ptr_to_map matches
> BTF 'struct bpf_map *' is essential ?
Alexei Starovoitov July 6, 2023, 5:48 p.m. UTC | #5
On Thu, Jul 6, 2023 at 10:42 AM Anton Protopopov <aspsk@isovalent.com> wrote:
>
> >
> > Don't you want to do:
> >  val = bpf_map_lookup_elem(map, ...);
> >  cnt = bpf_map_sum_elem_count(map);
> >
> > and that's the main use case ?
>
> Not sure I understand what this ^ use case is...
>
> Our primary use case is to [periodically] get the number of elements from the
> user space. We can do this using an iterator as you've suggested and what is
> tested in the added selftest.

Hmm. During the last office hours John explained that he needs to raise
alarm to user space when the map is close to full capacity.
Currently he's doing it with his own per-map counters implemented
in a bpf prog.
I'd expect the alarm to be done inline with updates to the counters.
If you scan maps from user space every second or so there is a chance
the spike in usage will be missed.

If we're adding map counters they should be usable not only via iterators.

John,
did I describe your use case correctly?
Anton Protopopov July 6, 2023, 6:35 p.m. UTC | #6
On Thu, Jul 06, 2023 at 10:48:16AM -0700, Alexei Starovoitov wrote:
> On Thu, Jul 6, 2023 at 10:42 AM Anton Protopopov <aspsk@isovalent.com> wrote:
> >
> > >
> > > Don't you want to do:
> > >  val = bpf_map_lookup_elem(map, ...);
> > >  cnt = bpf_map_sum_elem_count(map);
> > >
> > > and that's the main use case ?
> >
> > Not sure I understand what this ^ use case is...
> >
> > Our primary use case is to [periodically] get the number of elements from the
> > user space. We can do this using an iterator as you've suggested and what is
> > tested in the added selftest.
> 
> Hmm. During the last office hours John explained that he needs to raise
> alarm to user space when the map is close to full capacity.
> Currently he's doing it with his own per-map counters implemented
> in a bpf prog.
> I'd expect the alarm to be done inline with updates to the counters.
> If you scan maps from user space every second or so there is a chance
> the spike in usage will be missed.
>
> If we're adding map counters they should be usable not only via iterators.

In some use cases this is ok to miss a spike in favour of not checking counters
too often. But yes, for other use cases this makes sense to add support for
const map ptr, so I will do this.

> 
> John,
> did I describe your use case correctly?
Alexei Starovoitov July 6, 2023, 8:33 p.m. UTC | #7
On Thu, Jul 6, 2023 at 11:34 AM Anton Protopopov <aspsk@isovalent.com> wrote:
>
> On Thu, Jul 06, 2023 at 10:48:16AM -0700, Alexei Starovoitov wrote:
> > On Thu, Jul 6, 2023 at 10:42 AM Anton Protopopov <aspsk@isovalent.com> wrote:
> > >
> > > >
> > > > Don't you want to do:
> > > >  val = bpf_map_lookup_elem(map, ...);
> > > >  cnt = bpf_map_sum_elem_count(map);
> > > >
> > > > and that's the main use case ?
> > >
> > > Not sure I understand what this ^ use case is...
> > >
> > > Our primary use case is to [periodically] get the number of elements from the
> > > user space. We can do this using an iterator as you've suggested and what is
> > > tested in the added selftest.
> >
> > Hmm. During the last office hours John explained that he needs to raise
> > alarm to user space when the map is close to full capacity.
> > Currently he's doing it with his own per-map counters implemented
> > in a bpf prog.
> > I'd expect the alarm to be done inline with updates to the counters.
> > If you scan maps from user space every second or so there is a chance
> > the spike in usage will be missed.
> >
> > If we're adding map counters they should be usable not only via iterators.
>
> In some use cases this is ok to miss a spike in favour of not checking counters
> too often. But yes, for other use cases this makes sense to add support for
> const map ptr, so I will do this.

Great. Please send a follow up.
I've applied the current set.
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/progs/map_ptr_kern.c b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
index db388f593d0a..d6e234a37ccb 100644
--- a/tools/testing/selftests/bpf/progs/map_ptr_kern.c
+++ b/tools/testing/selftests/bpf/progs/map_ptr_kern.c
@@ -33,6 +33,7 @@  struct bpf_map {
 	__u32 value_size;
 	__u32 max_entries;
 	__u32 id;
+	__s64 *elem_count;
 } __attribute__((preserve_access_index));
 
 static inline int check_bpf_map_fields(struct bpf_map *map, __u32 key_size,
@@ -111,6 +112,8 @@  static inline int check_hash(void)
 
 	VERIFY(check_default_noinline(&hash->map, map));
 
+	VERIFY(map->elem_count != NULL);
+
 	VERIFY(hash->n_buckets == MAX_ENTRIES);
 	VERIFY(hash->elem_size == 64);