[DTrace-devel] [PATCH 4/8] bpf: add feature checking for BPF program type / attach type

Eugene Loh eugene.loh at oracle.com
Thu Apr 4 21:31:55 UTC 2024


Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
but if Nick also wants to take a look that's fine by me.

On 4/3/24 11:26, Kris Van Hees via DTrace-devel wrote:
> Newer provider implementations want to use program type / attach type
> combinations that may not be supported in older kernels.  Support is
> added for testing whether the runtime kernel supports the program type
> and attach type combination.
>
> This patch includes a test for TRACING / FENTRY (which also covers the
> FEXIT attach type).
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>   libdtrace/Build     |  1 +
>   libdtrace/dt_bpf.c  | 48 ++++++++++++++++++++++++++++++++++++++++++++-
>   libdtrace/dt_bpf.h  | 13 +++++++++++-
>   libdtrace/dt_btf.h  |  3 +++
>   libdtrace/dt_impl.h |  1 +
>   libdtrace/dt_open.c |  2 +-
>   6 files changed, 65 insertions(+), 3 deletions(-)
>
> diff --git a/libdtrace/Build b/libdtrace/Build
> index 9733a17b..87152734 100644
> --- a/libdtrace/Build
> +++ b/libdtrace/Build
> @@ -96,6 +96,7 @@ libdtrace_LIBS += -lopcodes
>   endif
>   
>   # Disable certain warnings for these files
> +dt_bpf.c_CFLAGS := -Wno-pedantic
>   dt_btf.c_CFLAGS := -Wno-pedantic
>   dt_consume.c_CFLAGS := -Wno-pedantic
>   dt_debug.c_CFLAGS := -Wno-prio-ctor-dtor
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> index 14ef12fc..a967335a 100644
> --- a/libdtrace/dt_bpf.c
> +++ b/libdtrace/dt_bpf.c
> @@ -21,6 +21,8 @@
>   #include <dt_strtab.h>
>   #include <dt_bpf.h>
>   #include <dt_bpf_maps.h>
> +#include <linux/btf.h>
> +#include <dt_btf.h>
>   #include <port.h>
>   
>   static boolean_t	dt_gmap_done = 0;
> @@ -378,7 +380,7 @@ have_helper(uint32_t func_id)
>   	       strstr(ptr, "unknown func") == NULL;
>   }
>   
> -void
> +static void
>   dt_bpf_init_helpers(dtrace_hdl_t *dtp)
>   {
>   	uint32_t	i;
> @@ -401,6 +403,50 @@ dt_bpf_init_helpers(dtrace_hdl_t *dtp)
>   #undef BPF_HELPER_MAP
>   }
>   
> +static int
> +have_attach_type(enum bpf_prog_type ptype, enum bpf_attach_type atype,
> +		 uint32_t btf_id)
> +{
> +	struct bpf_insn	insns[] = {
> +				BPF_MOV_IMM(BPF_REG_0, 0),
> +				BPF_RETURN()
> +			};
> +	dtrace_difo_t	dp;
> +	int		fd;
> +
> +	dp.dtdo_buf = insns;
> +	dp.dtdo_len = ARRAY_SIZE(insns);
> +
> +	fd = dt_bpf_prog_attach(ptype, atype, btf_id, &dp, 0, NULL, 0);
> +	/* If the program loads, we can use the attach type. */
> +	if (fd > 0) {
> +		close(fd);
> +		return 1;
> +	}
> +
> +	/* Failed -> attach type not available to us */
> +	return 0;
> +}
> +
> +static void
> +dt_bpf_init_features(dtrace_hdl_t *dtp)
> +{
> +	uint32_t	btf_id;
> +
> +	btf_id = dt_btf_lookup_name_kind(dtp, dtp->dt_shared_btf, "bpf_check",
> +					 BTF_KIND_FUNC);
> +	if (btf_id >= 0 &&
> +	    have_attach_type(BPF_PROG_TYPE_TRACING, BPF_TRACE_FENTRY, btf_id))
> +		BPF_SET_FEATURE(dtp, BPF_FEAT_FENTRY);
> +}
> +
> +void
> +dt_bpf_init(dtrace_hdl_t *dtp)
> +{
> +	dt_bpf_init_helpers(dtp);
> +	dt_bpf_init_features(dtp);
> +}
> +
>   static int
>   map_create_error(dtrace_hdl_t *dtp, const char *name, int err)
>   {
> diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
> index 63df043a..b830d4af 100644
> --- a/libdtrace/dt_bpf.h
> +++ b/libdtrace/dt_bpf.h
> @@ -20,6 +20,17 @@ struct dtrace_hdl;
>   extern "C" {
>   #endif
>   
> +/*
> + * BPF features.
> + */
> +#define BPF_FEAT_FENTRY			0x1	/* fentry/fexit support */
> +
> +#define BPF_HAS(dtp, feat)	((dtp)->dt_bpffeatures & (feat))
> +#define BPF_SET_FEATURE(dtp, feat) \
> +				do { \
> +					(dtp)->dt_bpffeatures |= (feat); \
> +				} while (0)
> +
>   #define DT_CONST_EPID			1
>   #define DT_CONST_PRID			2
>   #define DT_CONST_CLID			3
> @@ -74,7 +85,7 @@ extern int dt_bpf_prog_load(enum bpf_prog_type prog_type,
>   extern int dt_bpf_raw_tracepoint_open(const void *tp, int fd);
>   extern int dt_bpf_make_progs(struct dtrace_hdl *, uint_t);
>   extern int dt_bpf_load_progs(struct dtrace_hdl *, uint_t);
> -extern void dt_bpf_init_helpers(struct dtrace_hdl *dtp);
> +extern void dt_bpf_init(struct dtrace_hdl *dtp);
>   
>   #ifdef	__cplusplus
>   }
> diff --git a/libdtrace/dt_btf.h b/libdtrace/dt_btf.h
> index 85ae315e..85c8f1b4 100644
> --- a/libdtrace/dt_btf.h
> +++ b/libdtrace/dt_btf.h
> @@ -8,6 +8,7 @@
>   #ifndef	_DT_BTF_H
>   #define	_DT_BTF_H
>   
> +/* #include <linux/btf.h> */
>   #include <dt_impl.h>
>   
>   #ifdef	__cplusplus
> @@ -20,6 +21,8 @@ extern const char *dt_btf_errmsg(int);
>   extern dt_btf_t *dt_btf_load_module(dtrace_hdl_t *, dt_module_t *);
>   extern ctf_dict_t *dt_btf_module_ctf(dtrace_hdl_t *, dt_module_t *);
>   extern const char *dt_btf_get_string(dtrace_hdl_t *, dt_btf_t *, uint32_t);
> +extern int32_t dt_btf_lookup_name_kind(dtrace_hdl_t *, dt_btf_t *,
> +				       const char *, uint32_t);
>   
>   #ifdef	__cplusplus
>   }
> diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
> index 3f258376..7cf71060 100644
> --- a/libdtrace/dt_impl.h
> +++ b/libdtrace/dt_impl.h
> @@ -422,6 +422,7 @@ struct dtrace_hdl {
>   	uint_t dt_disasm;	/* dtrace disassembler bitmap (see below) */
>   	uint64_t dt_options[DTRACEOPT_MAX]; /* dtrace run-time options */
>   	uint32_t dt_bpfhelper[__BPF_FUNC_MAX_ID]; /* BPF helper mapping */
> +	uint32_t dt_bpffeatures;/* BPF features */
>   	int dt_version;		/* library version requested by client */
>   	int dt_btferr;		/* error resulting from last BTF failure */
>   	int dt_ctferr;		/* error resulting from last CTF failure */
> diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
> index 53db0d6d..06a932be 100644
> --- a/libdtrace/dt_open.c
> +++ b/libdtrace/dt_open.c
> @@ -1153,7 +1153,7 @@ dt_vopen(int version, int flags, int *errp,
>   	if (dtrace_setopt(dtp, "libdir", _dtrace_libdir) != 0)
>   		return set_open_errno(dtp, errp, dtp->dt_errno);
>   
> -	dt_bpf_init_helpers(dtp);
> +	dt_bpf_init(dtp);
>   
>   	return dtp;
>   }



More information about the DTrace-devel mailing list