libbpf-tools: optimize fentry_exists helper
authorHengqi Chen <chenhengqi@outlook.com>
Wed, 9 Jun 2021 05:42:54 +0000 (13:42 +0800)
committeryonghong-song <ys114321@gmail.com>
Thu, 10 Jun 2021 16:29:27 +0000 (09:29 -0700)
The previous implementation checks fentry support either in vmlinux
or module BTF. So we need two calls to fentry_exists to verify that
whether a symbol exists. This commit updates this behavior to use
the module name provided as a hint, and fallback to vmlinux if module
BTF is not available.

Signed-off-by: Hengqi Chen <chenhengqi@outlook.com>
libbpf-tools/fsdist.c
libbpf-tools/fsslower.c
libbpf-tools/trace_helpers.c
libbpf-tools/trace_helpers.h

index c8b6e24888e639ac375c8188f4fd55eb6d3c17ae..304158b8389785329873ddd4f247564ca9583531 100644 (file)
@@ -230,8 +230,7 @@ static bool check_fentry()
        for (i = 0; i < MAX_OP; i++) {
                fn_name = fs_configs[fs_type].op_funcs[i];
                module = fs_configs[fs_type].fs;
-               if (fn_name && !fentry_exists(fn_name, NULL)
-                   && !fentry_exists(fn_name, module)) {
+               if (fn_name && !fentry_exists(fn_name, module)) {
                        support_fentry = false;
                        break;
                }
index b21cd7f0bd89f65625c1e1a2c4d31bccd329766a..6ffefefc03238c0e299bf2dba2994142fb5e1535 100644 (file)
@@ -202,8 +202,7 @@ static bool check_fentry()
        for (i = 0; i < MAX_OP; i++) {
                fn_name = fs_configs[fs_type].op_funcs[i];
                module = fs_configs[fs_type].fs;
-               if (fn_name && !fentry_exists(fn_name, NULL)
-                   && !fentry_exists(fn_name, module)) {
+               if (fn_name && !fentry_exists(fn_name, module)) {
                        support_fentry = false;
                        break;
                }
index 04a7a0b92ef44c898cea0dc74fad30031a76a3da..0e9b01921afd7da1125c3409c4ca23c417e824ef 100644 (file)
@@ -1013,16 +1013,18 @@ bool fentry_exists(const char *name, const char *mod)
                        sysfs_vmlinux, strerror(-libbpf_get_error(base)));
                goto err_out;
        }
-       if (mod) {
+       if (mod && module_btf_exists(mod)) {
                snprintf(sysfs_mod, sizeof(sysfs_mod), "/sys/kernel/btf/%s", mod);
                btf = btf__parse_split(sysfs_mod, base);
                if (libbpf_get_error(btf)) {
                        fprintf(stderr, "failed to load BTF from %s: %s\n",
                                sysfs_mod, strerror(-libbpf_get_error(btf)));
-                       goto err_out;
+                       btf = base;
+                       base = NULL;
                }
        } else {
                btf = base;
+               base = NULL;
        }
 
        id = btf__find_by_name_kind(btf, "bpf_attach_type", BTF_KIND_ENUM);
@@ -1044,8 +1046,7 @@ bool fentry_exists(const char *name, const char *mod)
        }
 
 err_out:
-       if (mod)
-               btf__free(btf);
+       btf__free(btf);
        btf__free(base);
        return id > 0;
 }
index 019380af35311e629eb5aa7eaed42fdc284e476d..61cbe433784b0919e94d18b769147be26445b628 100644 (file)
@@ -75,8 +75,8 @@ bool is_kernel_module(const char *name);
  *
  * *name* is the name of a kernel function to be attached to, which can be
  * from vmlinux or a kernel module.
- * *mod* is the name of a kernel module, if NULL, it means *name*
- * belongs to vmlinux.
+ * *mod* is a hint that indicates the *name* may reside in module BTF,
+ * if NULL, it means *name* belongs to vmlinux.
  */
 bool fentry_exists(const char *name, const char *mod);