Context |
Check |
Description |
bpf/vmtest-bpf-next-PR |
fail
|
PR summary
|
bpf/vmtest-bpf-next-VM_Test-4 |
success
|
Logs for aarch64-gcc / build / build for aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-2 |
success
|
Logs for Unittests
|
bpf/vmtest-bpf-next-VM_Test-10 |
success
|
Logs for aarch64-gcc / veristat
|
bpf/vmtest-bpf-next-VM_Test-0 |
success
|
Logs for Lint
|
bpf/vmtest-bpf-next-VM_Test-5 |
success
|
Logs for aarch64-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-1 |
success
|
Logs for ShellCheck
|
bpf/vmtest-bpf-next-VM_Test-3 |
success
|
Logs for Validate matrix.py
|
bpf/vmtest-bpf-next-VM_Test-12 |
success
|
Logs for s390x-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-32 |
fail
|
Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-7 |
fail
|
Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-8 |
fail
|
Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-9 |
fail
|
Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-6 |
fail
|
Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-17 |
success
|
Logs for s390x-gcc / veristat
|
bpf/vmtest-bpf-next-VM_Test-19 |
success
|
Logs for x86_64-gcc / build / build for x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-20 |
success
|
Logs for x86_64-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-23 |
fail
|
Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-18 |
success
|
Logs for set-matrix
|
bpf/vmtest-bpf-next-VM_Test-28 |
success
|
Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-11 |
success
|
Logs for s390x-gcc / build / build for s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-26 |
fail
|
Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-25 |
success
|
Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-21 |
fail
|
Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-24 |
success
|
Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-22 |
fail
|
Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-27 |
fail
|
Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-30 |
fail
|
Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-31 |
fail
|
Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-33 |
fail
|
Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-34 |
success
|
Logs for x86_64-llvm-17 / veristat
|
bpf/vmtest-bpf-next-VM_Test-35 |
success
|
Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-37 |
fail
|
Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-38 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-39 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-40 |
fail
|
Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-42 |
success
|
Logs for x86_64-llvm-18 / veristat
|
bpf/vmtest-bpf-next-VM_Test-41 |
fail
|
Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-29 |
success
|
Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17 and -O2 optimization
|
bpf/vmtest-bpf-next-VM_Test-36 |
success
|
Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18 and -O2 optimization
|
bpf/vmtest-bpf-next-VM_Test-16 |
fail
|
Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-14 |
fail
|
Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-15 |
fail
|
Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
|
netdev/series_format |
success
|
Posting correctly formatted
|
netdev/tree_selection |
success
|
Clearly marked for bpf-next, async
|
netdev/ynl |
success
|
SINGLE THREAD;
Generated files up to date;
no warnings/errors;
no diff in generated;
|
netdev/fixes_present |
success
|
Fixes tag not required for -next series
|
netdev/header_inline |
success
|
No static functions without inline keyword in header files
|
netdev/build_32bit |
success
|
Errors and warnings before: 8 this patch: 8
|
netdev/cc_maintainers |
warning
|
1 maintainers not CCed: linux-kselftest@vger.kernel.org
|
netdev/build_clang |
success
|
Errors and warnings before: 8 this patch: 8
|
netdev/verify_signedoff |
success
|
Signed-off-by tag matches author and committer
|
netdev/deprecated_api |
success
|
None detected
|
netdev/check_selftest |
success
|
No net selftest shell script
|
netdev/verify_fixes |
success
|
No Fixes tag
|
netdev/build_allmodconfig_warn |
success
|
Errors and warnings before: 8 this patch: 8
|
netdev/checkpatch |
warning
|
CHECK: Alignment should match open parenthesis
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
WARNING: line length of 81 exceeds 80 columns
|
netdev/build_clang_rust |
success
|
No Rust files in patch. Skipping build
|
netdev/kdoc |
success
|
Errors and warnings before: 0 this patch: 0
|
netdev/source_inline |
success
|
Was 0 now: 0
|
bpf/vmtest-bpf-next-VM_Test-13 |
fail
|
Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
|
@@ -951,6 +951,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_BLOOM_FILTER,
BPF_MAP_TYPE_USER_RINGBUF,
BPF_MAP_TYPE_CGRP_STORAGE,
+ BPF_MAP_TYPE_RELAY,
};
/* Note that tracing related programs such as
@@ -1330,6 +1331,9 @@ enum {
/* Get path from provided FD in BPF_OBJ_PIN/BPF_OBJ_GET commands */
BPF_F_PATH_FD = (1U << 14),
+
+/* Enable overwrite for relay map */
+ BPF_F_OVERWRITE = (1U << 15),
};
/* Flags for BPF_PROG_QUERY. */
@@ -1401,6 +1405,9 @@ union bpf_attr {
* BPF_MAP_TYPE_BLOOM_FILTER - the lowest 4 bits indicate the
* number of hash functions (if 0, the bloom filter will default
* to using 5 hash functions).
+ *
+ * BPF_MAP_TYPE_RELAY - the lowest 32 bits indicate the number of
+ * relay subbufs (if 0, the number will be set to 8 by default).
*/
__u64 map_extra;
};
@@ -427,7 +427,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_map_key.c
+ test_ringbuf_map_key.c test_relay_map.c
# Generate both light skeleton and libbpf skeleton for these
LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test.c \
@@ -87,3 +87,4 @@ CONFIG_VSOCKETS=y
CONFIG_VXLAN=y
CONFIG_XDP_SOCKETS=y
CONFIG_XFRM_INTERFACE=y
+CONFIG_RELAY=y
new file mode 100644
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <linux/compiler.h>
+#include <linux/bpf.h>
+#include <sys/sysinfo.h>
+#include <test_progs.h>
+#include <sched.h>
+
+#include "test_relay_map.lskel.h"
+
+static int duration;
+
+/* file names in debugfs */
+static const char dirname[] = "relay_map_selftest";
+static const char mapname[] = "relay_map";
+static const char mapname_ow[] = "relay_map_ow";
+struct relay_sample {
+ int pid;
+ int seq;
+ long value;
+ char comm[16];
+};
+
+static int sample_cnt;
+static int overwrite;
+
+static void process_sample(struct relay_sample *s)
+{
+ ++sample_cnt;
+
+ switch (s->seq) {
+ case 0:
+ /* sample1 will not appear in overwrite mode */
+ CHECK(overwrite != 0, "overwrite_mode",
+ "sample1 appears in overwrite mode\n");
+ CHECK(s->value != 333, "sample1_value", "exp %ld, got %ld\n",
+ 333L, s->value);
+ break;
+ case 1:
+ CHECK(s->value != 777, "sample2_value", "exp %ld, got %ld\n",
+ 777L, s->value);
+ break;
+ default:
+ break;
+ }
+}
+
+static int relaymap_read(const char *mapname)
+{
+ int cpu = libbpf_num_possible_cpus();
+ char name[NAME_MAX];
+ struct relay_sample data;
+ int maxloop;
+ FILE *fp;
+
+ for (int i = 0; i < cpu; ++i) {
+ sprintf(name, "/sys/kernel/debug/%s/%s%d", dirname, mapname, i);
+ fp = fopen(name, "r");
+ if (CHECK(!fp, "fopen", "relay file open failed\n"))
+ return -1;
+
+ maxloop = 0;
+ while (fread(&data, sizeof(data), 1, fp)) {
+ process_sample(&data);
+
+ /* just 2 samples output */
+ if (++maxloop > 2)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static struct test_relay_map_lskel *skel;
+
+static void trigger_samples(void)
+{
+ skel->bss->dropped = 0;
+ skel->bss->total = 0;
+ skel->bss->seq = 0;
+
+ /* trigger exactly two samples */
+ skel->bss->value = 333;
+ syscall(__NR_getpgid);
+ skel->bss->value = 777;
+ syscall(__NR_getpgid);
+}
+
+static void relaymap_subtest(void)
+{
+ int err, map_fd;
+
+ skel = test_relay_map_lskel__open();
+ if (CHECK(!skel, "skel_open", "skeleton open failed\n"))
+ return;
+
+ /* setup relay param */
+ skel->maps.relay_map.max_entries = 1024;
+
+ err = test_relay_map_lskel__load(skel);
+ if (CHECK(err, "skel_load", "skeleton load failed\n"))
+ goto cleanup;
+
+ /* only trigger BPF program for current process */
+ skel->bss->pid = getpid();
+
+ /* turn off overwrite */
+ skel->bss->overwrite_enable = 0;
+ overwrite = skel->bss->overwrite_enable;
+
+ err = test_relay_map_lskel__attach(skel);
+ if (CHECK(err, "skel_attach", "skeleton attachment failed: %d\n", err))
+ goto cleanup;
+
+ /* before file setup - output failed */
+ trigger_samples();
+ CHECK(skel->bss->dropped != 2, "err_dropped", "exp %ld, got %ld\n",
+ 0L, skel->bss->dropped);
+ CHECK(skel->bss->total != 2, "err_total", "exp %ld, got %ld\n",
+ 2L, skel->bss->total);
+
+ /* after file setup - output succ */
+ map_fd = skel->maps.relay_map.map_fd;
+ err = bpf_map_update_elem(map_fd, NULL, dirname, 0);
+ if (CHECK(err, "map_update", "map update failed: %d\n", err))
+ goto cleanup;
+ trigger_samples();
+ CHECK(skel->bss->dropped != 0, "err_dropped", "exp %ld, got %ld\n",
+ 0L, skel->bss->dropped);
+ CHECK(skel->bss->total != 2, "err_total", "exp %ld, got %ld\n",
+ 2L, skel->bss->total);
+
+ sample_cnt = 0;
+ err = relaymap_read(mapname);
+ CHECK(sample_cnt != 2, "sample_cnt", "exp %d samples, got %d\n",
+ 2, sample_cnt);
+
+ test_relay_map_lskel__detach(skel);
+cleanup:
+ test_relay_map_lskel__destroy(skel);
+}
+
+static void relaymap_overwrite_subtest(void)
+{
+ int err, map_fd;
+
+ skel = test_relay_map_lskel__open();
+ if (CHECK(!skel, "skel_open", "skeleton open failed\n"))
+ return;
+
+ /* To test overwrite mode, we create subbuf of one-sample size */
+ skel->maps.relay_map_ow.max_entries = sizeof(struct relay_sample);
+
+ err = test_relay_map_lskel__load(skel);
+ if (CHECK(err, "skel_load", "skeleton load failed\n"))
+ goto cleanup;
+
+ /* only trigger BPF program for current process */
+ skel->bss->pid = getpid();
+
+ /* turn on overwrite */
+ skel->bss->overwrite_enable = 1;
+ overwrite = skel->bss->overwrite_enable;
+
+ err = test_relay_map_lskel__attach(skel);
+ if (CHECK(err, "skel_attach", "skeleton attachment failed: %d\n", err))
+ goto cleanup;
+
+ map_fd = skel->maps.relay_map_ow.map_fd;
+ err = bpf_map_update_elem(map_fd, NULL, dirname, 0);
+ if (CHECK(err, "map_update", "map update failed: %d\n", err))
+ goto cleanup;
+ trigger_samples();
+ /* relay_write never fails whether overwriting or not */
+ CHECK(skel->bss->dropped != 0, "err_dropped", "exp %ld, got %ld\n",
+ 0L, skel->bss->dropped);
+ CHECK(skel->bss->total != 2, "err_total", "exp %ld, got %ld\n",
+ 2L, skel->bss->total);
+
+ /* 2 samples are output, but only the last (val=777) could be seen */
+ sample_cnt = 0;
+ err = relaymap_read(mapname_ow);
+ CHECK(sample_cnt != 1, "sample_cnt", "exp %d samples, got %d\n",
+ 1, sample_cnt);
+
+ test_relay_map_lskel__detach(skel);
+cleanup:
+ test_relay_map_lskel__destroy(skel);
+}
+
+void test_relaymap(void)
+{
+ if (test__start_subtest("relaymap"))
+ relaymap_subtest();
+ if (test__start_subtest("relaymap_overwrite"))
+ relaymap_overwrite_subtest();
+}
new file mode 100644
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+char _license[] SEC("license") = "GPL";
+
+extern int bpf_relay_output(struct bpf_map *map, void *data,
+ __u64 data__sz, __u32 flags) __ksym;
+
+struct relay_sample {
+ int pid;
+ int seq;
+ long value;
+ char comm[16];
+};
+
+struct {
+ __uint(type, BPF_MAP_TYPE_RELAY);
+ __uint(max_entries, 1024);
+} relay_map SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_RELAY);
+ __uint(map_flags, BPF_F_OVERWRITE);
+ __uint(max_entries, 1024);
+ __uint(map_extra, 1);
+} relay_map_ow SEC(".maps");
+
+/* inputs */
+int pid = 0;
+long value = 0;
+int overwrite_enable = 0;
+
+/* outputs */
+long total = 0;
+long dropped = 0;
+
+/* inner state */
+long seq = 0;
+
+SEC("fentry/" SYS_PREFIX "sys_getpgid")
+int test_bpf_relaymap(void *ctx)
+{
+ int cur_pid = bpf_get_current_pid_tgid() >> 32;
+ struct relay_sample sample;
+ int ret = 0;
+
+ if (cur_pid != pid)
+ return 0;
+
+ sample.pid = pid;
+ bpf_get_current_comm(sample.comm, sizeof(sample.comm));
+ sample.value = value;
+ sample.seq = seq++;
+ __sync_fetch_and_add(&total, 1);
+
+ if (overwrite_enable)
+ ret = bpf_relay_output((struct bpf_map *)&relay_map_ow,
+ &sample, sizeof(sample), 0);
+ else
+ ret = bpf_relay_output((struct bpf_map *)&relay_map,
+ &sample, sizeof(sample), 0);
+
+ if (ret)
+ __sync_fetch_and_add(&dropped, 1);
+
+ return 0;
+}
The operations of relay map create, update_elem, and output are tested. The test is borrowed from ringbuf tests, where 2 samples are written into the relay channel, and we get the samples by reading the files. Overwriting mode is also tested, where the size of relay buffer equals sample size and just the last sample can be seen. Signed-off-by: Philo Lu <lulie@linux.alibaba.com> --- tools/include/uapi/linux/bpf.h | 7 + tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/config | 1 + .../selftests/bpf/prog_tests/relay_map.c | 197 ++++++++++++++++++ .../selftests/bpf/progs/test_relay_map.c | 69 ++++++ 5 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/relay_map.c create mode 100644 tools/testing/selftests/bpf/progs/test_relay_map.c