Skip to content

Commit 3acf8ac

Browse files
olsajirianakryiko
authored andcommitted
bpf: Add missed value to kprobe perf link info
Add missed value to kprobe attached through perf link info to hold the stats of missed kprobe handler execution. The kprobe's missed counter gets incremented when kprobe handler is not executed due to another kprobe running on the same cpu. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20230920213145.1941596-4-jolsa@kernel.org
1 parent e2b2cd5 commit 3acf8ac

6 files changed

Lines changed: 28 additions & 13 deletions

File tree

include/linux/trace_events.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,8 @@ struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name);
761761
void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp);
762762
int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
763763
u32 *fd_type, const char **buf,
764-
u64 *probe_offset, u64 *probe_addr);
764+
u64 *probe_offset, u64 *probe_addr,
765+
unsigned long *missed);
765766
int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
766767
int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
767768
#else
@@ -801,7 +802,7 @@ static inline void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp)
801802
static inline int bpf_get_perf_event_info(const struct perf_event *event,
802803
u32 *prog_id, u32 *fd_type,
803804
const char **buf, u64 *probe_offset,
804-
u64 *probe_addr)
805+
u64 *probe_addr, unsigned long *missed)
805806
{
806807
return -EOPNOTSUPP;
807808
}
@@ -877,6 +878,7 @@ extern void perf_kprobe_destroy(struct perf_event *event);
877878
extern int bpf_get_kprobe_info(const struct perf_event *event,
878879
u32 *fd_type, const char **symbol,
879880
u64 *probe_offset, u64 *probe_addr,
881+
unsigned long *missed,
880882
bool perf_type_tracepoint);
881883
#endif
882884
#ifdef CONFIG_UPROBE_EVENTS

include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6548,6 +6548,7 @@ struct bpf_link_info {
65486548
__u32 name_len;
65496549
__u32 offset; /* offset from func_name */
65506550
__u64 addr;
6551+
__u64 missed;
65516552
} kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */
65526553
struct {
65536554
__aligned_u64 tp_name; /* in/out */

kernel/bpf/syscall.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,7 +3374,7 @@ static void bpf_perf_link_dealloc(struct bpf_link *link)
33743374
static int bpf_perf_link_fill_common(const struct perf_event *event,
33753375
char __user *uname, u32 ulen,
33763376
u64 *probe_offset, u64 *probe_addr,
3377-
u32 *fd_type)
3377+
u32 *fd_type, unsigned long *missed)
33783378
{
33793379
const char *buf;
33803380
u32 prog_id;
@@ -3385,7 +3385,7 @@ static int bpf_perf_link_fill_common(const struct perf_event *event,
33853385
return -EINVAL;
33863386

33873387
err = bpf_get_perf_event_info(event, &prog_id, fd_type, &buf,
3388-
probe_offset, probe_addr);
3388+
probe_offset, probe_addr, missed);
33893389
if (err)
33903390
return err;
33913391
if (!uname)
@@ -3408,6 +3408,7 @@ static int bpf_perf_link_fill_common(const struct perf_event *event,
34083408
static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
34093409
struct bpf_link_info *info)
34103410
{
3411+
unsigned long missed;
34113412
char __user *uname;
34123413
u64 addr, offset;
34133414
u32 ulen, type;
@@ -3416,7 +3417,7 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
34163417
uname = u64_to_user_ptr(info->perf_event.kprobe.func_name);
34173418
ulen = info->perf_event.kprobe.name_len;
34183419
err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr,
3419-
&type);
3420+
&type, &missed);
34203421
if (err)
34213422
return err;
34223423
if (type == BPF_FD_TYPE_KRETPROBE)
@@ -3425,6 +3426,7 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
34253426
info->perf_event.type = BPF_PERF_EVENT_KPROBE;
34263427

34273428
info->perf_event.kprobe.offset = offset;
3429+
info->perf_event.kprobe.missed = missed;
34283430
if (!kallsyms_show_value(current_cred()))
34293431
addr = 0;
34303432
info->perf_event.kprobe.addr = addr;
@@ -3444,7 +3446,7 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,
34443446
uname = u64_to_user_ptr(info->perf_event.uprobe.file_name);
34453447
ulen = info->perf_event.uprobe.name_len;
34463448
err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr,
3447-
&type);
3449+
&type, NULL);
34483450
if (err)
34493451
return err;
34503452

@@ -3480,7 +3482,7 @@ static int bpf_perf_link_fill_tracepoint(const struct perf_event *event,
34803482
uname = u64_to_user_ptr(info->perf_event.tracepoint.tp_name);
34813483
ulen = info->perf_event.tracepoint.name_len;
34823484
info->perf_event.type = BPF_PERF_EVENT_TRACEPOINT;
3483-
return bpf_perf_link_fill_common(event, uname, ulen, NULL, NULL, NULL);
3485+
return bpf_perf_link_fill_common(event, uname, ulen, NULL, NULL, NULL, NULL);
34843486
}
34853487

34863488
static int bpf_perf_link_fill_perf_event(const struct perf_event *event,
@@ -4813,7 +4815,7 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
48134815

48144816
err = bpf_get_perf_event_info(event, &prog_id, &fd_type,
48154817
&buf, &probe_offset,
4816-
&probe_addr);
4818+
&probe_addr, NULL);
48174819
if (!err)
48184820
err = bpf_task_fd_query_copy(attr, uattr, prog_id,
48194821
fd_type, buf,

kernel/trace/bpf_trace.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,7 +2384,8 @@ int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
23842384

23852385
int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
23862386
u32 *fd_type, const char **buf,
2387-
u64 *probe_offset, u64 *probe_addr)
2387+
u64 *probe_offset, u64 *probe_addr,
2388+
unsigned long *missed)
23882389
{
23892390
bool is_tracepoint, is_syscall_tp;
23902391
struct bpf_prog *prog;
@@ -2419,7 +2420,7 @@ int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
24192420
#ifdef CONFIG_KPROBE_EVENTS
24202421
if (flags & TRACE_EVENT_FL_KPROBE)
24212422
err = bpf_get_kprobe_info(event, fd_type, buf,
2422-
probe_offset, probe_addr,
2423+
probe_offset, probe_addr, missed,
24232424
event->attr.type == PERF_TYPE_TRACEPOINT);
24242425
#endif
24252426
#ifdef CONFIG_UPROBE_EVENTS

kernel/trace/trace_kprobe.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,12 @@ static const struct file_operations kprobe_events_ops = {
11891189
.write = probes_write,
11901190
};
11911191

1192+
static unsigned long trace_kprobe_missed(struct trace_kprobe *tk)
1193+
{
1194+
return trace_kprobe_is_return(tk) ?
1195+
tk->rp.kp.nmissed + tk->rp.nmissed : tk->rp.kp.nmissed;
1196+
}
1197+
11921198
/* Probes profiling interfaces */
11931199
static int probes_profile_seq_show(struct seq_file *m, void *v)
11941200
{
@@ -1200,8 +1206,7 @@ static int probes_profile_seq_show(struct seq_file *m, void *v)
12001206
return 0;
12011207

12021208
tk = to_trace_kprobe(ev);
1203-
nmissed = trace_kprobe_is_return(tk) ?
1204-
tk->rp.kp.nmissed + tk->rp.nmissed : tk->rp.kp.nmissed;
1209+
nmissed = trace_kprobe_missed(tk);
12051210
seq_printf(m, " %-44s %15lu %15lu\n",
12061211
trace_probe_name(&tk->tp),
12071212
trace_kprobe_nhit(tk),
@@ -1547,7 +1552,8 @@ NOKPROBE_SYMBOL(kretprobe_perf_func);
15471552

15481553
int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
15491554
const char **symbol, u64 *probe_offset,
1550-
u64 *probe_addr, bool perf_type_tracepoint)
1555+
u64 *probe_addr, unsigned long *missed,
1556+
bool perf_type_tracepoint)
15511557
{
15521558
const char *pevent = trace_event_name(event->tp_event);
15531559
const char *group = event->tp_event->class->system;
@@ -1566,6 +1572,8 @@ int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
15661572
*probe_addr = kallsyms_show_value(current_cred()) ?
15671573
(unsigned long)tk->rp.kp.addr : 0;
15681574
*symbol = tk->symbol;
1575+
if (missed)
1576+
*missed = trace_kprobe_missed(tk);
15691577
return 0;
15701578
}
15711579
#endif /* CONFIG_PERF_EVENTS */

tools/include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6548,6 +6548,7 @@ struct bpf_link_info {
65486548
__u32 name_len;
65496549
__u32 offset; /* offset from func_name */
65506550
__u64 addr;
6551+
__u64 missed;
65516552
} kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */
65526553
struct {
65536554
__aligned_u64 tp_name; /* in/out */

0 commit comments

Comments
 (0)