libbpf: Detect minimal BTF support and skip BTF loading, if missing
authorAndrii Nakryiko <andriin@fb.com>
Tue, 18 Aug 2020 21:33:56 +0000 (14:33 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 19 Aug 2020 00:16:15 +0000 (17:16 -0700)
Detect whether a kernel supports any BTF at all, and if not, don't even
attempt loading BTF to avoid unnecessary log messages like:

  libbpf: Error loading BTF: Invalid argument(22)
  libbpf: Error loading .BTF into kernel: -22. BTF is optional, ignoring.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200818213356.2629020-8-andriin@fb.com
tools/lib/bpf/libbpf.c

index e3ab1794d2c3c93f911235109ea3e9c006775d01..775fa6317483e1d564b988305ec158710efe67cb 100644 (file)
@@ -170,6 +170,8 @@ enum kern_feature_id {
        FEAT_PROG_NAME,
        /* v5.2: kernel support for global data sections. */
        FEAT_GLOBAL_DATA,
+       /* BTF support */
+       FEAT_BTF,
        /* BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO support */
        FEAT_BTF_FUNC,
        /* BTF_KIND_VAR and BTF_KIND_DATASEC support */
@@ -2533,6 +2535,15 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)
        if (!obj->btf)
                return 0;
 
+       if (!kernel_supports(FEAT_BTF)) {
+               if (kernel_needs_btf(obj)) {
+                       err = -EOPNOTSUPP;
+                       goto report;
+               }
+               pr_debug("Kernel doesn't support BTF, skipping uploading it.\n");
+               return 0;
+       }
+
        sanitize = btf_needs_sanitization(obj);
        if (sanitize) {
                const void *raw_data;
@@ -2558,6 +2569,7 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)
                }
                btf__free(kern_btf);
        }
+report:
        if (err) {
                btf_mandatory = kernel_needs_btf(obj);
                pr_warn("Error loading .BTF into kernel: %d. %s\n", err,
@@ -3502,6 +3514,18 @@ static int probe_kern_global_data(void)
        return probe_fd(ret);
 }
 
+static int probe_kern_btf(void)
+{
+       static const char strs[] = "\0int";
+       __u32 types[] = {
+               /* int */
+               BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4),
+       };
+
+       return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
+                                            strs, sizeof(strs)));
+}
+
 static int probe_kern_btf_func(void)
 {
        static const char strs[] = "\0int\0x\0a";
@@ -3633,6 +3657,9 @@ static struct kern_feature_desc {
        [FEAT_GLOBAL_DATA] = {
                "global variables", probe_kern_global_data,
        },
+       [FEAT_BTF] = {
+               "minimal BTF", probe_kern_btf,
+       },
        [FEAT_BTF_FUNC] = {
                "BTF functions", probe_kern_btf_func,
        },