Skip to content

Commit cde4cba

Browse files
committed
tetragon: Wire extra process event tail call
Split generic_[ku]probe_process_event into two separate tail calls so we have space (there's 4096 instructions limit on 4.19 kernels) for new features in processing event code. Before: generic_kprobe_process_event 4029 insns generic_uprobe_process_event 4029 insns Now: generic_uprobe_process_event 2795 insns generic_uprobe_process_event_2 3147 insns generic_kprobe_process_event 2795 insns generic_kprobe_process_event_2 3147 insns Signed-off-by: Jiri Olsa <jolsa@kernel.org>
1 parent 30e7b7c commit cde4cba

File tree

11 files changed

+130
-27
lines changed

11 files changed

+130
-27
lines changed

bpf/include/api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,4 +323,10 @@ static int BPF_FUNC(seq_write, struct seq_file *m, const void *data, uint32_t le
323323
# define lock_and(ptr, val) (*(ptr) &= val)
324324
#endif
325325

326+
enum {
327+
__READ_ARG_1,
328+
__READ_ARG_2,
329+
__READ_ARG_ALL,
330+
};
331+
326332
#endif /* __BPF_API__ */

bpf/process/bpf_generic_kprobe.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL";
1818

1919
int generic_kprobe_setup_event(void *ctx);
2020
int generic_kprobe_process_event(void *ctx);
21+
int generic_kprobe_process_event_2(void *ctx);
2122
int generic_kprobe_process_filter(void *ctx);
2223
int generic_kprobe_filter_arg(void *ctx);
2324
int generic_kprobe_actions(void *ctx);
@@ -39,6 +40,9 @@ struct {
3940
[TAIL_CALL_SEND] = (void *)&generic_kprobe_output,
4041
#ifndef __V61_BPF_PROG
4142
[TAIL_CALL_PATH] = (void *)&generic_kprobe_path,
43+
#endif
44+
#ifndef __LARGE_BPF_PROG
45+
[TAIL_CALL_PROCESS_2] = (void *)&generic_kprobe_process_event_2,
4246
#endif
4347
},
4448
};
@@ -91,12 +95,26 @@ generic_kprobe_setup_event(void *ctx)
9195
return generic_process_event_and_setup(ctx, (struct bpf_map_def *)&kprobe_calls);
9296
}
9397

98+
#ifdef __LARGE_BPF_PROG
99+
__attribute__((section(COMMON), used)) int
100+
generic_kprobe_process_event(void *ctx)
101+
{
102+
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls, __READ_ARG_ALL);
103+
}
104+
#else
94105
__attribute__((section(COMMON), used)) int
95106
generic_kprobe_process_event(void *ctx)
96107
{
97-
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls);
108+
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls, __READ_ARG_1);
98109
}
99110

111+
__attribute__((section(COMMON), used)) int
112+
generic_kprobe_process_event_2(void *ctx)
113+
{
114+
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls, __READ_ARG_2);
115+
}
116+
#endif
117+
100118
__attribute__((section(COMMON), used)) int
101119
generic_kprobe_process_filter(void *ctx)
102120
{

bpf/process/bpf_generic_lsm_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ generic_lsm_setup_event(void *ctx)
6363
__attribute__((section("lsm"), used)) int
6464
generic_lsm_process_event(void *ctx)
6565
{
66-
return generic_process_event(ctx, (struct bpf_map_def *)&lsm_calls);
66+
return generic_process_event(ctx, (struct bpf_map_def *)&lsm_calls, __READ_ARG_ALL);
6767
}
6868

6969
__attribute__((section("lsm"), used)) int

bpf/process/bpf_generic_rawtp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ generic_rawtp_setup_event(void *ctx)
8484
__attribute__((section("raw_tp"), used)) int
8585
generic_rawtp_process_event(void *ctx)
8686
{
87-
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls);
87+
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls, __READ_ARG_ALL);
8888
}
8989

9090
__attribute__((section("raw_tp"), used)) int

bpf/process/bpf_generic_tracepoint.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ generic_tracepoint_event(struct generic_tracepoint_event_arg *ctx)
263263
__attribute__((section("tracepoint"), used)) int
264264
generic_tracepoint_process_event(void *ctx)
265265
{
266-
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls);
266+
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls, __READ_ARG_ALL);
267267
}
268268

269269
__attribute__((section("tracepoint"), used)) int

bpf/process/bpf_generic_uprobe.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL";
1818

1919
int generic_uprobe_setup_event(void *ctx);
2020
int generic_uprobe_process_event(void *ctx);
21+
int generic_uprobe_process_event_2(void *ctx);
2122
int generic_uprobe_process_filter(void *ctx);
2223
int generic_uprobe_filter_arg(void *ctx);
2324
int generic_uprobe_actions(void *ctx);
@@ -39,6 +40,9 @@ struct {
3940
[TAIL_CALL_SEND] = (void *)&generic_uprobe_output,
4041
#ifndef __V61_BPF_PROG
4142
[TAIL_CALL_PATH] = (void *)&generic_uprobe_path,
43+
#endif
44+
#ifndef __LARGE_BPF_PROG
45+
[TAIL_CALL_PROCESS_2] = (void *)&generic_uprobe_process_event_2,
4246
#endif
4347
},
4448
};
@@ -68,12 +72,26 @@ generic_uprobe_setup_event(void *ctx)
6872
return generic_process_event_and_setup(ctx, (struct bpf_map_def *)&uprobe_calls);
6973
}
7074

75+
#ifdef __LARGE_BPF_PROG
76+
__attribute__((section(COMMON), used)) int
77+
generic_uprobe_process_event(void *ctx)
78+
{
79+
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls, __READ_ARG_ALL);
80+
}
81+
#else
7182
__attribute__((section(COMMON), used)) int
7283
generic_uprobe_process_event(void *ctx)
7384
{
74-
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls);
85+
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls, __READ_ARG_1);
7586
}
7687

88+
__attribute__((section(COMMON), used)) int
89+
generic_uprobe_process_event_2(void *ctx)
90+
{
91+
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls, __READ_ARG_2);
92+
}
93+
#endif
94+
7795
__attribute__((section(COMMON), used)) int
7896
generic_uprobe_process_filter(void *ctx)
7997
{

bpf/process/bpf_generic_usdt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ generic_usdt_setup_event(void *ctx)
7272
__attribute__((section(COMMON), used)) int
7373
generic_usdt_process_event(void *ctx)
7474
{
75-
return generic_process_event(ctx, (struct bpf_map_def *)&usdt_calls);
75+
return generic_process_event(ctx, (struct bpf_map_def *)&usdt_calls, __READ_ARG_ALL);
7676
}
7777

7878
__attribute__((section(COMMON), used)) int

bpf/process/generic_calls.h

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,34 @@ copy_iov_iter(void *ctx, long off, unsigned long arg, int argm, struct msg_gener
190190
#define copy_iov_iter(ctx, orig_off, arg, argm, e) 0
191191
#endif /* __LARGE_BPF_PROG */
192192

193+
FUNC_INLINE bool is_read_arg_1(long type)
194+
{
195+
switch (type) {
196+
case iov_iter_type:
197+
case fd_ty:
198+
case filename_ty:
199+
case string_type:
200+
case net_dev_ty:
201+
case data_loc_type:
202+
case syscall64_type:
203+
case size_type:
204+
case s64_ty:
205+
case u64_ty:
206+
case int_type:
207+
case s32_ty:
208+
case u32_ty:
209+
case s16_ty:
210+
case u16_ty:
211+
case s8_ty:
212+
case u8_ty:
213+
case skb_type:
214+
case sock_type:
215+
case sockaddr_type:
216+
return true;
217+
}
218+
return false;
219+
}
220+
193221
FUNC_INLINE long
194222
__read_arg_1(void *ctx, int type, long orig_off, unsigned long arg, int argm, char *args)
195223
{
@@ -395,7 +423,7 @@ __read_arg_2(void *ctx, int type, long orig_off, unsigned long arg, int argm, ch
395423
* Returns the size of data appended to @args.
396424
*/
397425
FUNC_INLINE long
398-
read_arg(void *ctx, int index, int type, long orig_off, unsigned long arg, int argm)
426+
read_arg(void *ctx, int index, int type, long orig_off, unsigned long arg, int argm, int process)
399427
{
400428
size_t min_size = type_to_min_size(type, argm);
401429
struct msg_generic_kprobe *e;
@@ -422,6 +450,11 @@ read_arg(void *ctx, int index, int type, long orig_off, unsigned long arg, int a
422450
if (path_arg)
423451
return copy_path(args, path_arg);
424452

453+
if (process == __READ_ARG_1)
454+
return __read_arg_1(ctx, type, orig_off, arg, argm, args);
455+
if (process == __READ_ARG_2)
456+
return __read_arg_2(ctx, type, orig_off, arg, argm, args);
457+
425458
size = __read_arg_1(ctx, type, orig_off, arg, argm, args);
426459
if (!size)
427460
size = __read_arg_2(ctx, type, orig_off, arg, argm, args);
@@ -531,7 +564,8 @@ FUNC_INLINE long get_pt_regs_arg(struct pt_regs *ctx, struct event_config *confi
531564
}
532565
#endif /* __TARGET_ARCH_x86 && (GENERIC_KPROBE || GENERIC_UPROBE) */
533566

534-
FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map_def *tailcals)
567+
FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map_def *tailcals,
568+
int process)
535569
{
536570
struct msg_generic_kprobe *e;
537571
struct event_config *config;
@@ -553,6 +587,13 @@ FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map
553587
ty = config->arg[index];
554588
am = config->arm[index];
555589

590+
#ifndef __LARGE_BPF_PROG
591+
#if defined(GENERIC_KPROBE) || defined(GENERIC_UPROBE)
592+
if (!is_read_arg_1(ty) && process == __READ_ARG_1)
593+
tail_call(ctx, tailcals, TAIL_CALL_PROCESS_2);
594+
#endif
595+
#endif
596+
556597
#if defined(GENERIC_TRACEPOINT) || defined(GENERIC_USDT)
557598
a = (&e->a0)[index];
558599
extract_arg(config, index, &a);
@@ -582,11 +623,11 @@ FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map
582623
return generic_path_offload(ctx, ty, a, index, off, tailcals);
583624
#endif
584625

585-
return read_arg(ctx, index, ty, off, a, am);
626+
return read_arg(ctx, index, ty, off, a, am, process);
586627
}
587628

588629
FUNC_INLINE int
589-
generic_process_event(void *ctx, struct bpf_map_def *tailcals)
630+
generic_process_event(void *ctx, struct bpf_map_def *tailcals, int process)
590631
{
591632
struct msg_generic_kprobe *e;
592633
int index, zero = 0;
@@ -603,7 +644,7 @@ generic_process_event(void *ctx, struct bpf_map_def *tailcals)
603644
if (total < MAX_TOTAL) {
604645
long errv;
605646

606-
errv = generic_read_arg(ctx, index, total, tailcals);
647+
errv = generic_read_arg(ctx, index, total, tailcals, process);
607648
if (errv > 0)
608649
total += errv;
609650
/* Follow filter lookup failed so lets abort the event.
@@ -1244,7 +1285,7 @@ FUNC_INLINE int generic_retprobe(void *ctx, struct bpf_map_def *calls, unsigned
12441285
ty_arg = config->argreturn;
12451286
do_copy = config->argreturncopy;
12461287
if (ty_arg) {
1247-
size += read_arg(ctx, 0, ty_arg, size, ret, 0);
1288+
size += read_arg(ctx, 0, ty_arg, size, ret, 0, __READ_ARG_ALL);
12481289
#if defined(__LARGE_BPF_PROG) && defined(GENERIC_KRETPROBE)
12491290
struct socket_owner owner;
12501291

bpf/process/types/basic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ enum {
138138
TAIL_CALL_ACTIONS = 4,
139139
TAIL_CALL_SEND = 5,
140140
TAIL_CALL_PATH = 6,
141+
TAIL_CALL_PROCESS_2 = 7,
141142
};
142143

143144
struct selector_action {

pkg/sensors/tracing/kprobe_test.go

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4424,12 +4424,6 @@ func TestLoadKprobeSensor(t *testing.T) {
44244424
}
44254425

44264426
sensorMaps = []tus.SensorMap{
4427-
// all kprobe programs
4428-
{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}},
4429-
4430-
// all but generic_kprobe_output
4431-
{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5, 7}},
4432-
44334427
// generic_retkprobe_event
44344428
{Name: "retkprobe_calls", Progs: []uint{8, 9, 10}},
44354429

@@ -4440,14 +4434,20 @@ func TestLoadKprobeSensor(t *testing.T) {
44404434
// generic_kprobe_actions
44414435
{Name: "override_tasks", Progs: []uint{5}},
44424436

4443-
// all kprobe but generic_kprobe_process_filter,generic_retkprobe_event
4444-
{Name: "config_map", Progs: []uint{0, 1, 2}},
4445-
44464437
// generic_kprobe_process_event*,generic_kprobe_actions,retkprobe
44474438
{Name: "fdinstall_map", Progs: []uint{2, 5, 8, 10}},
44484439
}
44494440

44504441
if config.EnableLargeProgs() {
4442+
// all kprobe programs
4443+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}})
4444+
4445+
// all but generic_kprobe_output
4446+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5, 7}})
4447+
4448+
// all kprobe but generic_kprobe_process_filter,generic_retkprobe_event
4449+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2}})
4450+
44514451
// shared with base sensor
44524452
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 5, 6, 8, 10}})
44534453

@@ -4468,6 +4468,17 @@ func TestLoadKprobeSensor(t *testing.T) {
44684468
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tg_conf_map", Progs: []uint{0}})
44694469
}
44704470
} else {
4471+
sensorProgs = append(sensorProgs, tus.SensorProg{Name: "generic_kprobe_process_event_2", Type: ebpf.Kprobe})
4472+
4473+
// all kprobe programs
4474+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}})
4475+
4476+
// all but generic_kprobe_output
4477+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5, 7, 12}})
4478+
4479+
// all kprobe but generic_kprobe_process_filter,generic_retkprobe_event
4480+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2, 12}})
4481+
44714482
// shared with base sensor
44724483
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 8}})
44734484

0 commit comments

Comments
 (0)