OSDN Git Service

selftests/bpf: add bpf_for_each(), bpf_for(), and bpf_repeat() macros
authorAndrii Nakryiko <andrii@kernel.org>
Wed, 8 Mar 2023 18:41:18 +0000 (10:41 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 9 Mar 2023 00:19:51 +0000 (16:19 -0800)
commit8c2b5e90505e474f36ecc3b7f3f8298b59d72e91
tree41b9e438a1f62246a5046dacbdb5f191bbf48aeb
parent6018e1f407cccf39b804d1f75ad4de7be4e6cc45
selftests/bpf: add bpf_for_each(), bpf_for(), and bpf_repeat() macros

Add bpf_for_each(), bpf_for(), and bpf_repeat() macros that make writing
open-coded iterator-based loops much more convenient and natural. These
macros utilize cleanup attribute to ensure proper destruction of the
iterator and thanks to that manage to provide the ergonomics that is
very close to C language's for() construct. Typical loop would look like:

  int i;
  int arr[N];

  bpf_for(i, 0, N) {
      /* verifier will know that i >= 0 && i < N, so could be used to
       * directly access array elements with no extra checks
       */
       arr[i] = i;
  }

bpf_repeat() is very similar, but it doesn't expose iteration number and
is meant as a simple "repeat action N times" loop:

  bpf_repeat(N) { /* whatever, N times */ }

Note that `break` and `continue` statements inside the {} block work as
expected.

bpf_for_each() is a generalization over any kind of BPF open-coded
iterator allowing to use for-each-like approach instead of calling
low-level bpf_iter_<type>_{new,next,destroy}() APIs explicitly. E.g.:

  struct cgroup *cg;

  bpf_for_each(cgroup, cg, some, input, args) {
      /* do something with each cg */
  }

would call (not-yet-implemented) bpf_iter_cgroup_{new,next,destroy}()
functions to form a loop over cgroups, where `some, input, args` are
passed verbatim into constructor as

  bpf_iter_cgroup_new(&it, some, input, args).

As a first demonstration, add pyperf variant based on the bpf_for() loop.

Also clean up a few tests that either included bpf_misc.h header
unnecessarily from the user-space, which is unsupported, or included it
before any common types are defined (and thus leading to unnecessary
compilation warnings, potentially).

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20230308184121.1165081-6-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c
tools/testing/selftests/bpf/prog_tests/uprobe_autoattach.c
tools/testing/selftests/bpf/progs/bpf_misc.h
tools/testing/selftests/bpf/progs/lsm.c
tools/testing/selftests/bpf/progs/pyperf.h
tools/testing/selftests/bpf/progs/pyperf600_iter.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/pyperf600_nounroll.c