Skip to content

Commit

Permalink
uprobe: Add ref_cnt_offset arg to bpf_attach_uprobe
Browse files Browse the repository at this point in the history
This argument allows callers to tell the kernel to manage USDT semaphore
counts. It's better than fiddling with the counts in userspace b/c if
the userspace program crashes then the semaphore count does not get
decremented.

It's also better b/c the kernel can activate the semaphore for all
processes that have the target mapped into memory. Currently with bcc,
you have to provide the pid of each process you want to activate a
semaphore for and then bcc will go poke /proc/pid/mem at the right
offset.
  • Loading branch information
danobi committed Oct 19, 2020
1 parent ec3747e commit 50f2009
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
6 changes: 4 additions & 2 deletions src/cc/api/BPF.cc
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
const std::string& probe_func,
uint64_t symbol_addr,
bpf_probe_attach_type attach_type, pid_t pid,
uint64_t symbol_offset) {
uint64_t symbol_offset,
uint32_t ref_ctr_offset) {

if (symbol_addr != 0 && symbol_offset != 0)
return StatusTuple(-1,
Expand All @@ -245,7 +246,8 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
TRY2(load_func(probe_func, BPF_PROG_TYPE_KPROBE, probe_fd));

int res_fd = bpf_attach_uprobe(probe_fd, attach_type, probe_event.c_str(),
binary_path.c_str(), offset, pid);
binary_path.c_str(), offset, pid,
ref_ctr_offset);

if (res_fd < 0) {
TRY2(unload_func(probe_func));
Expand Down
3 changes: 2 additions & 1 deletion src/cc/api/BPF.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class BPF {
uint64_t symbol_addr = 0,
bpf_probe_attach_type attach_type = BPF_PROBE_ENTRY,
pid_t pid = -1,
uint64_t symbol_offset = 0);
uint64_t symbol_offset = 0,
uint32_t ref_ctr_offset = 0);
StatusTuple detach_uprobe(const std::string& binary_path,
const std::string& symbol, uint64_t symbol_addr = 0,
bpf_probe_attach_type attach_type = BPF_PROBE_ENTRY,
Expand Down
18 changes: 12 additions & 6 deletions src/cc/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@

#define UNUSED(expr) do { (void)(expr); } while (0)

#define PERF_UPROBE_REF_CTR_OFFSET_SHIFT 32

struct bpf_helper {
char *name;
char *required_version;
Expand Down Expand Up @@ -838,7 +840,8 @@ static int bpf_get_retprobe_bit(const char *event_type)
* the [k,u]probe. This function tries to create pfd with the perf_kprobe PMU.
*/
static int bpf_try_perf_event_open_with_probe(const char *name, uint64_t offs,
int pid, const char *event_type, int is_return)
int pid, const char *event_type, int is_return,
uint64_t ref_ctr_offset)
{
struct perf_event_attr attr = {};
int type = bpf_find_probe_type(event_type);
Expand All @@ -851,6 +854,7 @@ static int bpf_try_perf_event_open_with_probe(const char *name, uint64_t offs,
attr.wakeup_events = 1;
if (is_return)
attr.config |= 1 << is_return_bit;
attr.config |= (ref_ctr_offset << PERF_UPROBE_REF_CTR_OFFSET_SHIFT);

/*
* struct perf_event_attr in latest perf_event.h has the following
Expand Down Expand Up @@ -1019,7 +1023,8 @@ static int create_probe_event(char *buf, const char *ev_name,
// see bpf_try_perf_event_open_with_probe().
static int bpf_attach_probe(int progfd, enum bpf_probe_attach_type attach_type,
const char *ev_name, const char *config1, const char* event_type,
uint64_t offset, pid_t pid, int maxactive)
uint64_t offset, pid_t pid, int maxactive,
uint32_t ref_ctr_offset)
{
int kfd, pfd = -1;
char buf[PATH_MAX], fname[256];
Expand All @@ -1028,7 +1033,8 @@ static int bpf_attach_probe(int progfd, enum bpf_probe_attach_type attach_type,
if (maxactive <= 0)
// Try create the [k,u]probe Perf Event with perf_event_open API.
pfd = bpf_try_perf_event_open_with_probe(config1, offset, pid, event_type,
attach_type != BPF_PROBE_ENTRY);
attach_type != BPF_PROBE_ENTRY,
ref_ctr_offset);

// If failed, most likely Kernel doesn't support the perf_kprobe PMU
// (e12f03d "perf/core: Implement the 'perf_kprobe' PMU") yet.
Expand Down Expand Up @@ -1092,17 +1098,17 @@ int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
{
return bpf_attach_probe(progfd, attach_type,
ev_name, fn_name, "kprobe",
fn_offset, -1, maxactive);
fn_offset, -1, maxactive, 0);
}

int bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
const char *ev_name, const char *binary_path,
uint64_t offset, pid_t pid)
uint64_t offset, pid_t pid, uint32_t ref_ctr_offset)
{

return bpf_attach_probe(progfd, attach_type,
ev_name, binary_path, "uprobe",
offset, pid, -1);
offset, pid, -1, ref_ctr_offset);
}

static int bpf_detach_probe(const char *ev_name, const char *event_type)
Expand Down
2 changes: 1 addition & 1 deletion src/cc/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ int bpf_detach_kprobe(const char *ev_name);

int bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
const char *ev_name, const char *binary_path,
uint64_t offset, pid_t pid);
uint64_t offset, pid_t pid, uint32_t ref_ctr_offset);
int bpf_detach_uprobe(const char *ev_name);

int bpf_attach_tracepoint(int progfd, const char *tp_category,
Expand Down

0 comments on commit 50f2009

Please sign in to comment.