[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