Skip to content

Commit

Permalink
selftests/bpf: Add more ring buffer test coverage
Browse files Browse the repository at this point in the history
Add test coverage for reservations beyond the ring buffer size in order
to validate that bpf_ringbuf_reserve() rejects the request with NULL, all
other ring buffer tests keep passing as well:

  # ./vmtest.sh -- ./test_progs -t ringbuf
  [...]
  ./test_progs -t ringbuf
  [    1.165434] bpf_testmod: loading out-of-tree module taints kernel.
  [    1.165825] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel
  [    1.284001] tsc: Refined TSC clocksource calibration: 3407.982 MHz
  [    1.286871] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x311fc34e357, max_idle_ns: 440795379773 ns
  [    1.289555] clocksource: Switched to clocksource tsc
  torvalds#274/1   ringbuf/ringbuf:OK
  torvalds#274/2   ringbuf/ringbuf_n:OK
  torvalds#274/3   ringbuf/ringbuf_map_key:OK
  torvalds#274/4   ringbuf/ringbuf_write:OK
  torvalds#274     ringbuf:OK
  torvalds#275     ringbuf_multi:OK
  [...]

Signed-off-by: Daniel Borkmann <[email protected]>
  • Loading branch information
borkmann authored and intel-lab-lkp committed Jun 25, 2024
1 parent 029e749 commit f7367f3
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tools/testing/selftests/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ LINKED_SKELS := test_static_linked.skel.h linked_funcs.skel.h \
LSKELS := fentry_test.c fexit_test.c fexit_sleep.c atomics.c \
trace_printk.c trace_vprintk.c map_ptr_kern.c \
core_kern.c core_kern_overflow.c test_ringbuf.c \
test_ringbuf_n.c test_ringbuf_map_key.c
test_ringbuf_n.c test_ringbuf_map_key.c test_ringbuf_write.c

# Generate both light skeleton and libbpf skeleton for these
LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test.c \
Expand Down
45 changes: 45 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
#include <sys/sysinfo.h>
#include <linux/perf_event.h>
#include <linux/ring_buffer.h>

#include "test_ringbuf.lskel.h"
#include "test_ringbuf_n.lskel.h"
#include "test_ringbuf_map_key.lskel.h"
#include "test_ringbuf_write.lskel.h"

#define EDONE 7777

Expand Down Expand Up @@ -84,6 +86,47 @@ static void *poll_thread(void *input)
return (void *)(long)ring_buffer__poll(ringbuf, timeout);
}

static void ringbuf_write_subtest(void)
{
struct test_ringbuf_write_lskel *skel;
int page_size = getpagesize();
size_t *mmap_ptr;
int err, rb_fd;

skel = test_ringbuf_write_lskel__open();
if (!ASSERT_OK_PTR(skel, "skel_load"))
return;

skel->maps.ringbuf.max_entries = 0x4000;

err = test_ringbuf_write_lskel__load(skel);
if (!ASSERT_OK(err, "ringbuf_write"))
goto cleanup;

rb_fd = skel->maps.ringbuf.map_fd;

mmap_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, rb_fd, 0);
ASSERT_OK_PTR(mmap_ptr, "rw_cons_pos");
*mmap_ptr = 0x3000;

skel->bss->pid = getpid();

ringbuf = ring_buffer__new(rb_fd, process_sample, NULL, NULL);
if (!ASSERT_OK_PTR(ringbuf, "ringbuf_create"))
goto cleanup;

err = test_ringbuf_write_lskel__attach(skel);
if (!ASSERT_OK(err, "ringbuf_write"))
goto cleanup;

trigger_samples();
ASSERT_GE(skel->bss->discarded, 1, "discarded");
ASSERT_EQ(skel->bss->passed, 0, "passed");
cleanup:
ring_buffer__free(ringbuf);
test_ringbuf_write_lskel__destroy(skel);
}

static void ringbuf_subtest(void)
{
const size_t rec_sz = BPF_RINGBUF_HDR_SZ + sizeof(struct sample);
Expand Down Expand Up @@ -451,4 +494,6 @@ void test_ringbuf(void)
ringbuf_n_subtest();
if (test__start_subtest("ringbuf_map_key"))
ringbuf_map_key_subtest();
if (test__start_subtest("ringbuf_write"))
ringbuf_write_subtest();
}
42 changes: 42 additions & 0 deletions tools/testing/selftests/bpf/progs/test_ringbuf_write.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-2.0

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"

char _license[] SEC("license") = "GPL";

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
} ringbuf SEC(".maps");

long discarded, passed;
int pid;

SEC("fentry/" SYS_PREFIX "sys_getpgid")
int test_ringbuf_write(void *ctx)
{
int *foo, cur_pid = bpf_get_current_pid_tgid() >> 32;
void *sample1, *sample2;

if (cur_pid != pid)
return 0;

sample1 = bpf_ringbuf_reserve(&ringbuf, 0x3000, 0);
if (!sample1)
return 0;
/* first one can pass */
sample2 = bpf_ringbuf_reserve(&ringbuf, 0x3000, 0);
if (!sample2) {
bpf_ringbuf_discard(sample1, 0);
__sync_fetch_and_add(&discarded, 1);
return 0;
}
/* second one must not */
__sync_fetch_and_add(&passed, 1);
foo = sample2 + 4084;
*foo = 256;
bpf_ringbuf_discard(sample1, 0);
bpf_ringbuf_discard(sample2, 0);
return 0;
}

0 comments on commit f7367f3

Please sign in to comment.