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 <daniel@iogearbox.net>
  • Loading branch information
borkmann authored and intel-lab-lkp committed Jun 25, 2024
1 parent b7cbd0e commit a87765e
Showing 3 changed files with 89 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
@@ -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 \
46 changes: 46 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/ringbuf.c
Original file line number Diff line number Diff line change
@@ -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

@@ -84,6 +86,48 @@ 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;
ASSERT_OK(munmap(mmap_ptr, page_size), "unmap_rw");

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);
@@ -451,4 +495,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 a87765e

Please sign in to comment.