Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lbr improvements #61

Merged
merged 2 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/mass_attach.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

/* these two are defined by custom BPF code outside of mass_attacher */
extern int handle_func_entry(void *ctx, u32 func_id, u64 func_ip);
extern int handle_func_exit(void *ctx, u32 func_id, u64 func_ip, u64 ret);
Expand Down Expand Up @@ -63,7 +66,8 @@ static __always_inline void capture_lbrs(int cpu)
{
long lbr_sz;

if (!use_lbr)
/* prioritize straight path logic if LBR is requested */
if (unlikely(!use_lbr))
return;

lbr_sz = bpf_get_branch_snapshot(&lbrs[cpu & max_cpu_mask], sizeof(lbrs[0]), 0);
Expand Down Expand Up @@ -131,7 +135,7 @@ int kexit(struct pt_regs *ctx)
u32 id, cpu;
long ip;

if (!ready)
if (unlikely(!ready))
return 0;

cpu = bpf_get_smp_processor_id();
Expand Down Expand Up @@ -232,11 +236,11 @@ static __always_inline int handle_fexit(void *ctx, int arg_cnt, bool is_void_ret
long ip;
u64 res;

if (!ready)
if (unlikely(!ready))
return 0;

cpu = bpf_get_smp_processor_id();
if (!recur_enter(cpu))
if (unlikely(!recur_enter(cpu)))
return 0;

capture_lbrs(cpu);
Expand Down
35 changes: 18 additions & 17 deletions src/retsnoop.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ enum symb_mode {
enum debug_feat {
DEBUG_NONE = 0x00,
DEBUG_MULTI_KPROBE = 0x01,
DEBUG_FULL_LBR = 0x02,
};

static struct env {
Expand Down Expand Up @@ -200,7 +201,7 @@ static const struct argp_option opts[] = {
{ "stacks-map-size", OPT_STACKS_MAP_SIZE, "SIZE", 0,
"Stacks map size (default 4096)" },
{ "debug", OPT_DEBUG_FEAT, "FEATURE", 0,
"Enable selected debug features. Any set of: multi-kprobe." },
"Enable selected debug features. Any set of: multi-kprobe, full-lbr." },
{},
};

Expand Down Expand Up @@ -308,6 +309,7 @@ static enum debug_feat parse_debug_arg(const char *arg)
enum debug_feat value;
} table[] = {
{"multi-kprobe", DEBUG_MULTI_KPROBE},
{"full-lbr", DEBUG_FULL_LBR},
};

for (i = 0; i < ARRAY_SIZE(table); i++) {
Expand Down Expand Up @@ -1612,23 +1614,22 @@ static int handle_call_stack(struct ctx *dctx, const struct call_stack *s)
lbr_cnt = s->lbrs_sz / sizeof(struct perf_branch_entry);
lbr_from = lbr_cnt - 1;

if (!env.emit_full_stacks) {
/* Filter out last few irrelevant LBRs that captured
* internal BPF/kprobe/perf jumps. For that, find the
* first LBR record that overlaps with the last traced
* function. All the records after that are assumed
* relevant.
*/
for (i = 0, lbr_to = 0; i < lbr_cnt; i++, lbr_to++) {
if (lbr_matches(s->lbrs[i].from, start, end) ||
lbr_matches(s->lbrs[i].to, start, end)) {
found_useful_lbrs = true;
break;
}
/* Filter out last few irrelevant LBRs that captured
* internal BPF/kprobe/perf jumps. For that, find the
* first LBR record that overlaps with the last traced
* function. All the records after that are assumed
* relevant.
*/
for (i = 0, lbr_to = 0; i < lbr_cnt; i++, lbr_to++) {
if (lbr_matches(s->lbrs[i].from, start, end) ||
lbr_matches(s->lbrs[i].to, start, end)) {
found_useful_lbrs = true;
break;
}
if (!found_useful_lbrs)
lbr_to = 0;
}
if (!found_useful_lbrs ||
env.emit_full_stacks || (env.debug_feats & DEBUG_FULL_LBR))
lbr_to = 0;

if (env.lbr_max_cnt && lbr_from - lbr_to + 1 > env.lbr_max_cnt)
lbr_from = min(lbr_cnt - 1, lbr_to + env.lbr_max_cnt - 1);
Expand All @@ -1647,7 +1648,7 @@ static int handle_call_stack(struct ctx *dctx, const struct call_stack *s)
&stack_items1, rec_cnts1,
&stack_items2, rec_cnts2);

if (!env.emit_full_stacks && !found_useful_lbrs)
if (!found_useful_lbrs)
printf("[LBR] No relevant LBR data were captured, showing unfiltered LBR stack!\n");
}

Expand Down