[DTrace-devel] [PATCH 2/2] Pass load-time constants to BPF programs in a consistent way
eugene.loh at oracle.com
eugene.loh at oracle.com
Thu Feb 17 20:45:31 UTC 2022
From: Eugene Loh <eugene.loh at oracle.com>
In bpf/, there are .c and .S programs that are cross-compiled at
build time, but they sometimes rely on constants that are not known
until the programs are loaded. Two ways were being used to provide
those constants. One was to put them in the state map. Another was
to set the values during relocation.
Use one consistent method for providing these constants.
Specifically, set the constants during relocation rather than using
the state map:
*) These constants do not change during execution.
*) Avoiding a map lookup saves a function call, saving BPF
instructions, simplifying BPF programming, and reducing
register pressure.
*) The constants' values are made known to the BPF verifier.
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
bpf/get_bvar.c | 41 ++++++++---------------------------------
libdtrace/dt_bpf.c | 30 ------------------------------
libdtrace/dt_bpf.h | 6 ++++--
libdtrace/dt_cc.c | 35 ++++++++++++++++++++---------------
libdtrace/dt_dlibs.c | 4 +++-
libdtrace/dt_state.h | 7 -------
6 files changed, 35 insertions(+), 88 deletions(-)
diff --git a/bpf/get_bvar.c b/bpf/get_bvar.c
index c04822e4..0da4b35a 100644
--- a/bpf/get_bvar.c
+++ b/bpf/get_bvar.c
@@ -135,58 +135,33 @@ noinline uint64_t dt_get_bvar(const dt_dctx_t *dctx, uint32_t id)
}
case DIF_VAR_EXECNAME: {
uint64_t ptr;
- uint32_t key;
- uint32_t *comm_off;
-
- /*
- * In the "state" map, look up the "struct task_struct" offset
- * of "comm".
- */
- key = DT_STATE_TASK_COMM_OFF;
- comm_off = bpf_map_lookup_elem(&state, &key);
- if (comm_off == NULL)
- return error(dctx, DTRACEFLT_ILLOP, 0);
+ extern uint64_t TASK_COMM;
/* &(current->comm) */
ptr = bpf_get_current_task();
if (ptr == 0)
return error(dctx, DTRACEFLT_BADADDR, ptr);
- return (uint64_t)ptr + *comm_off;
+ return (uint64_t)ptr + (uint64_t)&TASK_COMM;
}
case DIF_VAR_WALLTIMESTAMP:
return bpf_ktime_get_ns() + ((uint64_t)&BOOTTM);
case DIF_VAR_PPID: {
uint64_t ptr;
int32_t val = -1;
- uint32_t key;
- uint32_t *parent_off;
- uint32_t *tgid_off;
-
- /*
- * In the "state" map, look up the "struct task_struct" offsets
- * of real_parent and tgid.
- */
- key = DT_STATE_TASK_PARENT_OFF;
- parent_off = bpf_map_lookup_elem(&state, &key);
- if (parent_off == NULL)
- return -1;
-
- key = DT_STATE_TASK_TGID_OFF;
- tgid_off = bpf_map_lookup_elem(&state, &key);
- if (tgid_off == NULL)
- return -1;
+ extern uint64_t TASK_REAL_PARENT;
+ extern uint64_t TASK_TGID;
/* Chase pointers val = current->real_parent->tgid. */
ptr = bpf_get_current_task();
if (ptr == 0)
return error(dctx, DTRACEFLT_BADADDR, ptr);
if (bpf_probe_read((void *)&ptr, 8,
- (const void *)(ptr + *parent_off)))
- return error(dctx, DTRACEFLT_BADADDR, ptr + *parent_off);
+ (const void *)(ptr + (uint64_t)&TASK_REAL_PARENT)))
+ return error(dctx, DTRACEFLT_BADADDR, ptr + (uint64_t)&TASK_REAL_PARENT);
if (bpf_probe_read((void *)&val, 4,
- (const void *)(ptr + *tgid_off)))
- return error(dctx, DTRACEFLT_BADADDR, ptr + *tgid_off);
+ (const void *)(ptr + (uint64_t)&TASK_TGID)))
+ return error(dctx, DTRACEFLT_BADADDR, ptr + (uint64_t)&TASK_TGID);
return (uint64_t)val;
}
diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index 635c74cb..a597ca1c 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -134,32 +134,6 @@ create_gmap(dtrace_hdl_t *dtp, const char *name, enum bpf_map_type type,
return fd;
}
-static int
-set_task_offsets(dtrace_hdl_t *dtp)
-{
- ctf_id_t type;
- ctf_membinfo_t ctm;
- ctf_file_t *cfp = dtp->dt_shared_ctf;
-
- type = ctf_lookup_by_name(cfp, "struct task_struct");
- if (type == CTF_ERR)
- return -1;
-
- if (ctf_member_info(cfp, type, "real_parent", &ctm) == CTF_ERR)
- return -1;
- dt_state_set_offparent(dtp, ctm.ctm_offset / NBBY);
-
- if (ctf_member_info(cfp, type, "tgid", &ctm) == CTF_ERR)
- return -1;
- dt_state_set_offtgid(dtp, ctm.ctm_offset / NBBY);
-
- if (ctf_member_info(cfp, type, "comm", &ctm) == CTF_ERR)
- return -1;
- dt_state_set_offcomm(dtp, ctm.ctm_offset / NBBY);
-
- return 0;
-}
-
static void
populate_probes_map(dtrace_hdl_t *dtp, int fd)
{
@@ -375,10 +349,6 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
/* Populate the 'probes' map. */
populate_probes_map(dtp, pr_mapfd);
- /* Set some task_struct offsets in state. */
- if (set_task_offsets(dtp))
- return dt_set_errno(dtp, EDT_CTF);
-
return 0;
}
diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
index e361d103..957d593e 100644
--- a/libdtrace/dt_bpf.h
+++ b/libdtrace/dt_bpf.h
@@ -28,8 +28,10 @@ extern "C" {
#define DT_CONST_BOOTTM 8
#define DT_CONST_NSPEC 9
#define DT_CONST_NCPUS 10
-#define DT_CONST_TASK_REAL_PARENT 11
-#define DT_CONST_TASK_PID 12
+#define DT_CONST_TASK_PID 11
+#define DT_CONST_TASK_TGID 12
+#define DT_CONST_TASK_REAL_PARENT 13
+#define DT_CONST_TASK_COMM 14
extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
int group_fd, unsigned long flags);
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index f5b59109..b73789a2 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -2367,28 +2367,33 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
return -1;
nrp->dofr_data = boottime;
continue;
- case DT_CONST_TASK_REAL_PARENT: {
+ case DT_CONST_TASK_PID:
+ case DT_CONST_TASK_TGID:
+ case DT_CONST_TASK_REAL_PARENT:
+ case DT_CONST_TASK_COMM: {
ctf_file_t *cfp = dtp->dt_shared_ctf;
ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
ctf_membinfo_t ctm;
+ int rc;
if (type == CTF_ERR)
return -1;
- if (ctf_member_info(cfp, type, "real_parent", &ctm) == CTF_ERR)
- return -1;
- nrp->dofr_data = ctm.ctm_offset / NBBY;
- continue;
- }
- case DT_CONST_TASK_PID: {
- ctf_file_t *cfp = dtp->dt_shared_ctf;
- ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
- ctf_membinfo_t ctm;
-
- if (type == CTF_ERR)
- return -1;
-
- if (ctf_member_info(cfp, type, "pid", &ctm) == CTF_ERR)
+ switch (idp->di_id) {
+ case DT_CONST_TASK_PID:
+ rc = ctf_member_info(cfp, type, "pid", &ctm);
+ break;
+ case DT_CONST_TASK_TGID:
+ rc = ctf_member_info(cfp, type, "tgid", &ctm);
+ break;
+ case DT_CONST_TASK_REAL_PARENT:
+ rc = ctf_member_info(cfp, type, "real_parent", &ctm);
+ break;
+ case DT_CONST_TASK_COMM:
+ rc = ctf_member_info(cfp, type, "comm", &ctm);
+ break;
+ }
+ if (rc == CTF_ERR)
return -1;
nrp->dofr_data = ctm.ctm_offset / NBBY;
continue;
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index a8d112d4..efbd3261 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -79,8 +79,10 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL_ID(BOOTTM, DT_IDENT_SCALAR, DT_CONST_BOOTTM),
DT_BPF_SYMBOL_ID(NSPEC, DT_IDENT_SCALAR, DT_CONST_NSPEC),
DT_BPF_SYMBOL_ID(NCPUS, DT_IDENT_SCALAR, DT_CONST_NCPUS),
- DT_BPF_SYMBOL_ID(TASK_REAL_PARENT, DT_IDENT_SCALAR, DT_CONST_TASK_REAL_PARENT),
DT_BPF_SYMBOL_ID(TASK_PID, DT_IDENT_SCALAR, DT_CONST_TASK_PID),
+ DT_BPF_SYMBOL_ID(TASK_TGID, DT_IDENT_SCALAR, DT_CONST_TASK_TGID),
+ DT_BPF_SYMBOL_ID(TASK_REAL_PARENT, DT_IDENT_SCALAR, DT_CONST_TASK_REAL_PARENT),
+ DT_BPF_SYMBOL_ID(TASK_COMM, DT_IDENT_SCALAR, DT_CONST_TASK_COMM),
/* End-of-list marker */
{ NULL, }
diff --git a/libdtrace/dt_state.h b/libdtrace/dt_state.h
index 6c743b8e..9a82f994 100644
--- a/libdtrace/dt_state.h
+++ b/libdtrace/dt_state.h
@@ -21,9 +21,6 @@ typedef enum dt_state_elem {
DT_STATE_ACTIVITY = 0, /* activity state of the session */
DT_STATE_BEGANON, /* cpu BEGIN probe executed on */
DT_STATE_ENDEDON, /* cpu END probe executed on */
- DT_STATE_TASK_PARENT_OFF, /* offsetof(struct task_struct, real_parent) */
- DT_STATE_TASK_TGID_OFF, /* offsetof(struct task_struct, tgid) */
- DT_STATE_TASK_COMM_OFF, /* offsetof(struct task_struct, comm) */
DT_STATE_NUM_ELEMS
} dt_state_elem_t;
@@ -64,10 +61,6 @@ dt_state_set(dtrace_hdl_t *dtp, uint32_t key, uint32_t val)
# define dt_state_get_beganon(dtp) dt_state_get(dtp, DT_STATE_BEGANON)
# define dt_state_get_endedon(dtp) dt_state_get(dtp, DT_STATE_ENDEDON)
-
-# define dt_state_set_offparent(dtp, x) dt_state_set(dtp, DT_STATE_TASK_PARENT_OFF, (x))
-# define dt_state_set_offtgid(dtp, x) dt_state_set(dtp, DT_STATE_TASK_TGID_OFF, (x))
-# define dt_state_set_offcomm(dtp, x) dt_state_set(dtp, DT_STATE_TASK_COMM_OFF, (x))
#endif
#endif /* _DT_STATE_H */
--
2.18.4
More information about the DTrace-devel
mailing list