On 12/12, Stanislav Fomichev wrote:
> On 12/12, Alexei Starovoitov wrote:
> > On Wed, Dec 12, 2018 at 10:59:13AM -0800, Stanislav Fomichev wrote:
> > > On 12/12, Alexei Starovoitov wrote:
> > > > On Wed, Dec 12, 2018 at 10:27:24AM -0800, Stanislav Fomichev wrote:
> > > > > The following prog types don't make sense without bpf cgroup:
> > > > > * BPF_PROG_TYPE_CGROUP_SKB
> > > > > * BPF_PROG_TYPE_CGROUP_SOCK
> > > > > * BPF_PROG_TYPE_CGROUP_SOCK_ADDR
> > > > > 
> > > > > Skip running verifier tests that exercise these prog types if
> > > > > kernel is built without proper support.
> > > > > 
> > > > > See commit e5c504858a18 ("selftests/bpf: skip verifier sockmap tests
> > > > > on kernels without support") for original motivation.
> > > > > 
> > > > > Signed-off-by: Stanislav Fomichev <s...@google.com>
> > > > > ---
> > > > >  tools/testing/selftests/bpf/test_verifier.c | 35 
> > > > > +++++++++++++++++++++
> > > > >  1 file changed, 35 insertions(+)
> > > > > 
> > > > > diff --git a/tools/testing/selftests/bpf/test_verifier.c 
> > > > > b/tools/testing/selftests/bpf/test_verifier.c
> > > > > index f5015566ae1b..b5470a399996 100644
> > > > > --- a/tools/testing/selftests/bpf/test_verifier.c
> > > > > +++ b/tools/testing/selftests/bpf/test_verifier.c
> > > > > @@ -44,6 +44,7 @@
> > > > >  /* fallback to all features enabled */
> > > > >  # define CONFIG_BPF_STREAM_PARSER 1
> > > > >  # define CONFIG_XDP_SOCKETS 1
> > > > > +# define CONFIG_CGROUP_BPF 1
> > > > 
> > > > I really don't like where these is going.
> > > > I think previous set should be reverted.
> > > > This is not a scalable approach.
> > > > Use libbpf probing approach to check whether feature is present instead.
> > > I can probably add runtime probing instead of depending on compile-time
> > > config, but I think that we would still need some per-test mechanism
> > > to say that it depends on feature X (per-test .config_disabled or
> > > similar).
> > > Will moving these checks to runtime address your concern? (there is sill a
> > > scalability issue though)
> > 
> > you said it youself. config_disabled doesn't scale.
> > hence it's not a solution regardless of macro or runtime probing.
> Let me see if I can use per-test prog_type for this type of probing.
> Load 'return 0' program per-prog_type and use it as an indication of
> runtime support. This should probably work in the majority of the cases.
> I'll get back to you shortly.

How about doing something like the (very work-in-progress) patch below?
It mostly gets the job done, I think I need to do similar probing for maps
and skip the tests that have fixup_map_{sockmap,sockhash,xskmap,stacktrace} in
case appropriate map type is not supported.

---

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index aa582cd5bfcf..e55c116ff971 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -157,8 +157,11 @@ enum bpf_prog_type {
        BPF_PROG_TYPE_LIRC_MODE2,
        BPF_PROG_TYPE_SK_REUSEPORT,
        BPF_PROG_TYPE_FLOW_DISSECTOR,
+       __MAX_BPF_PROG_TYPE
 };
 
+#define MAX_BPF_PROG_TYPE __MAX_BPF_PROG_TYPE
+
 enum bpf_attach_type {
        BPF_CGROUP_INET_INGRESS,
        BPF_CGROUP_INET_EGRESS,
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index aa582cd5bfcf..e55c116ff971 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -157,8 +157,11 @@ enum bpf_prog_type {
        BPF_PROG_TYPE_LIRC_MODE2,
        BPF_PROG_TYPE_SK_REUSEPORT,
        BPF_PROG_TYPE_FLOW_DISSECTOR,
+       __MAX_BPF_PROG_TYPE
 };
 
+#define MAX_BPF_PROG_TYPE __MAX_BPF_PROG_TYPE
+
 enum bpf_attach_type {
        BPF_CGROUP_INET_INGRESS,
        BPF_CGROUP_INET_EGRESS,
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e2bc75ee1614..40f26f50556d 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1726,6 +1726,7 @@ static bool bpf_prog_type__needs_kver(enum bpf_prog_type 
type)
        case BPF_PROG_TYPE_TRACEPOINT:
        case BPF_PROG_TYPE_RAW_TRACEPOINT:
        case BPF_PROG_TYPE_PERF_EVENT:
+       case __MAX_BPF_PROG_TYPE:
                return false;
        case BPF_PROG_TYPE_KPROBE:
        default:
diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index f5015566ae1b..e86a4e0ef921 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -93,6 +93,52 @@ struct bpf_test {
        bool config_disabled;
 };
 
+/* TODO: move this to probe_helpers.[ch] to be able to share with test_maps.c 
*/
+/* {{{ */
+static bool __bpf_proge_prog_type(enum bpf_prog_type prog_type)
+{
+       struct bpf_load_program_attr attr;
+       struct bpf_insn insns[] = {
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       };
+       int ret;
+
+       memset(&attr, 0, sizeof(attr));
+       attr.prog_type = prog_type;
+       attr.insns = insns;
+       attr.insns_cnt = ARRAY_SIZE(insns);
+       attr.license = "GPL";
+
+       ret = bpf_load_program_xattr(&attr, NULL, 0);
+       if (ret < 0)
+               return false;
+       close(ret);
+
+       return true;
+}
+
+static bool prog_type_supported[MAX_BPF_PROG_TYPE];
+
+void bpf_probe_prog_types()
+{
+       int i;
+
+       for (i = 0; i < MAX_BPF_PROG_TYPE; i++) {
+               if (i == (int)BPF_PROG_TYPE_UNSPEC)
+                       continue;
+               prog_type_supported[i] =
+                       __bpf_proge_prog_type((enum bpf_prog_type)i);
+       }
+}
+
+bool bpf_prog_type_supported(enum bpf_prog_type prog_type)
+{
+       return prog_type == BPF_PROG_TYPE_UNSPEC ||
+                   prog_type_supported[(int)prog_type];
+}
+/* }}} */
+
 /* Note we want this to be 64 bit aligned so that the end of our array is
  * actually the end of the structure.
  */
@@ -14545,8 +14591,8 @@ static int do_test(bool unpriv, unsigned int from, 
unsigned int to)
        for (i = from; i < to; i++) {
                struct bpf_test *test = &tests[i];
 
-               if (test->config_disabled) {
-                       printf("#%d/u %s SKIP (missing required config)\n",
+               if (!bpf_prog_type_supported(test->prog_type)) {
+                       printf("#%d/u %s SKIP (unsupported program type)\n",
                               i, test->descr);
                        skips++;
                        continue;
@@ -14611,5 +14657,6 @@ int main(int argc, char **argv)
        }
 
        bpf_semi_rand_init();
+       bpf_probe_prog_types();
        return do_test(unpriv, from, to);
 }

Reply via email to