[DTrace-devel] [PATCH v5 03/11] libdtrace: avoid BTF probes for ranged built-in modules

Kris Van Hees kris.van.hees at oracle.com
Wed Oct 7 10:20:49 UTC 2026


Some questions below.

On Fri, Aug 21, 2026 at 05:10:51PM +0100, Alan Maguire wrote:
> 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 <alan.maguire at oracle.com>
> ---
>  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;
> +	}

This does not look right to me, because if a dt_btf_path is specified, I
would expect the handle to still provided a handle-wide shared CTF and
BTF, even if it may be different from the system-wide shared CTF and
BTF.  In other words, I think that sharing should be based on:

System standard CTF and BTF -> dt_shared_ctf and dt_share_btf globals
Non-standard CTF or BTF -> dtp->dt_shared_ctf and dtp->dt_shared_btf

So dropping the dtp->dt_btf_path == NULL in the conditional clause above
should be fine, right?

> +
>  	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
> 



More information about the DTrace-devel mailing list