[PATCH v5 03/11] libdtrace: avoid BTF probes for ranged built-in modules
Alan Maguire <[email protected]>
| Newsgroups | dev.linux.lists.dtrace |
|---|---|
| Message-ID | <[email protected]> |
When /proc/kallsyms is used with modules.builtin.ranges, libdtrace can attribute symbols linked into vmlinux to their individual built-in objects, such as bitrev or atomic64_test. This creates module objects for those names. These objects have no per-module BTF file under /sys/kernel/btf. Avoid probing for one when modules.builtin.ranges has identified the module as built in, and use the shared vmlinux BTF directly instead. Keep the existing lookup path for loadable modules and for an explicitly configured BTF directory. Signed-off-by: Alan Maguire <[email protected]> --- libdtrace/dt_btf.c | 8 ++++++-- libdtrace/dt_impl.h | 1 + libdtrace/dt_module.c | 20 +++++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/libdtrace/dt_btf.c b/libdtrace/dt_btf.c index e7980969..93ecf5cd 100644 --- a/libdtrace/dt_btf.c +++ b/libdtrace/dt_btf.c @@ -915,8 +915,12 @@ dt_btf_module_ctf(dtrace_hdl_t *dtp, dt_module_t *dmp) if (!dtp->dt_shared_ctf && dtp->dt_shared_btf && btf == dtp->dt_shared_btf) dtp->dt_shared_ctf = ctf; - dt_dprintf("Generated %s CTF from BTF (%d types).\n", dmp->dm_name, - btf->type_cnt); + if (btf == dtp->dt_shared_btf && strcmp(dmp->dm_name, "vmlinux") != 0) + dt_dprintf("Created %s CTF import from shared vmlinux BTF.\n", + dmp->dm_name); + else + dt_dprintf("Generated %s CTF from BTF (%d types).\n", dmp->dm_name, + btf->type_cnt); #endif return ctf; diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h index 7ccdc271..38c5ff0b 100644 --- a/libdtrace/dt_impl.h +++ b/libdtrace/dt_impl.h @@ -201,6 +201,7 @@ typedef struct dt_kern_path { #define DT_DM_KERNEL 0x2 /* module is associated with a kernel object */ #define DT_DM_CTF_ARCHIVED 0x4 /* module found in a CTF archive */ #define DT_DM_KERN_UNLOADED 0x8 /* module not loaded into the kernel */ +#define DT_DM_KERN_BUILTIN 0x10 /* module is linked into vmlinux */ /* * Why do we need (only) 4 slots? The maximum amount of string arguments to diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c index 00978911..ea6d56c3 100644 --- a/libdtrace/dt_module.c +++ b/libdtrace/dt_module.c @@ -871,6 +871,19 @@ dt_kern_module_find_btf(dtrace_hdl_t *dtp, dt_module_t *dmp) if (dtp->dt_shared_btf == NULL && strcmp(dmp->dm_name, "vmlinux") != 0) return; + /* + * modules.builtin.ranges identifies this object as linked into vmlinux. + * Such objects cannot have a per-module BTF object, so use the shared + * vmlinux BTF directly. Retain the usual lookup for an explicitly + * configured BTF directory and every other module. + */ + if (dtp->dt_btf_path == NULL && (dmp->dm_flags & DT_DM_KERN_BUILTIN)) { + dmp->dm_btf = dtp->dt_shared_btf; + dt_dprintf("Using shared vmlinux BTF for built-in module %s.\n", + dmp->dm_name); + return; + } + dt_dprintf("Loading BTF for module %s.\n", dmp->dm_name); /* @@ -1405,6 +1418,7 @@ dt_modsym_update(dtrace_hdl_t *dtp, const char *line, dt_kasstate_t *state) { dt_kallsym_t sym; char *modname; + int builtin = 0; if ((line[0] == '\n') || (line[0] == 0)) return 0; @@ -1440,8 +1454,10 @@ dt_modsym_update(dtrace_hdl_t *dtp, const char *line, dt_kasstate_t *state) char *s; s = dt_kasstate_modname(state, sym.addr, sym.name); - if (s != NULL) + if (s != NULL) { strncpy(sym.mod, s, PATH_MAX); + builtin = 1; + } } } @@ -1511,6 +1527,8 @@ dt_modsym_update(dtrace_hdl_t *dtp, const char *line, dt_kasstate_t *state) if (err != 0) return err; } + if (builtin) + dmp->dm_flags |= DT_DM_KERN_BUILTIN; err = dt_modsym_addsym(dtp, dmp, &sym, state); if (err != 0) -- 2.43.5