Skip to content

Commit

Permalink
tools/ttysnoop: add ringbuf
Browse files Browse the repository at this point in the history
Kernel provides BPF ringbuf from v5.8, it sloves memory efficiency
and event re-ordering problems of the BPF perf buffer.

When using perfbuf it may get lots of 'Possibly lost x samples' on
screen if many contents burst out to the snooping tty device. After
changing to ringbuf, this issus will disappear.

Signed-off-by: mickey_zhu <[email protected]>
  • Loading branch information
michael-chuh authored and yonghong-song committed Jan 4, 2023
1 parent 4d3e1c9 commit ec8a4f7
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions tools/ttysnoop.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def usage():
};
BPF_ARRAY(data_map, struct data_t, 1);
BPF_PERF_OUTPUT(events);
PERF_TABLE
static int do_tty_write(void *ctx, const char __user *buf, size_t count)
{
Expand Down Expand Up @@ -107,7 +107,7 @@ def usage():
data->count = BUFSIZE;
else
data->count = count;
events.perf_submit(ctx, data, sizeof(*data));
PERF_OUTPUT_CTX
if (count < BUFSIZE)
return 0;
count -= BUFSIZE;
Expand Down Expand Up @@ -178,6 +178,18 @@ def usage():
else:
bpf_text = bpf_text.replace('PROBE_TTY_WRITE', probe_tty_write_kprobe)

if BPF.kernel_struct_has_field(b'bpf_ringbuf', b'waitq') == 1:
PERF_MODE = "USE_BPF_RING_BUF"
bpf_text = bpf_text.replace('PERF_TABLE',
'BPF_RINGBUF_OUTPUT(events, 64);')
bpf_text = bpf_text.replace('PERF_OUTPUT_CTX',
'events.ringbuf_output(data, sizeof(*data), 0);')
else:
PERF_MODE = "USE_BPF_PERF_BUF"
bpf_text = bpf_text.replace('PERF_TABLE', 'BPF_PERF_OUTPUT(events);')
bpf_text = bpf_text.replace('PERF_OUTPUT_CTX',
'events.perf_submit(ctx, data, sizeof(*data));')

bpf_text = bpf_text.replace('PTS', str(pi.st_ino))
if debug or args.ebpf:
print(bpf_text)
Expand All @@ -200,9 +212,16 @@ def print_event(cpu, data, size):
sys.stdout.flush()

# loop with callback to print_event
b["events"].open_perf_buffer(print_event)
if PERF_MODE == "USE_BPF_RING_BUF":
b["events"].open_ring_buffer(print_event)
else:
b["events"].open_perf_buffer(print_event, page_cnt=64)

while 1:
try:
b.perf_buffer_poll()
if PERF_MODE == "USE_BPF_RING_BUF":
b.ring_buffer_poll()
else:
b.perf_buffer_poll()
except KeyboardInterrupt:
exit()

0 comments on commit ec8a4f7

Please sign in to comment.