]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/prog_tests/ringbuf_multi.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / prog_tests / ringbuf_multi.c
1 // SPDX-License-Identifier: GPL-2.0
2 #define _GNU_SOURCE
3 #include <test_progs.h>
4 #include <sys/epoll.h>
5 #include "test_ringbuf_multi.skel.h"
6
7 static int duration = 0;
8
9 struct sample {
10         int pid;
11         int seq;
12         long value;
13         char comm[16];
14 };
15
16 static int process_sample(void *ctx, void *data, size_t len)
17 {
18         int ring = (unsigned long)ctx;
19         struct sample *s = data;
20
21         switch (s->seq) {
22         case 0:
23                 CHECK(ring != 1, "sample1_ring", "exp %d, got %d\n", 1, ring);
24                 CHECK(s->value != 333, "sample1_value", "exp %ld, got %ld\n",
25                       333L, s->value);
26                 break;
27         case 1:
28                 CHECK(ring != 2, "sample2_ring", "exp %d, got %d\n", 2, ring);
29                 CHECK(s->value != 777, "sample2_value", "exp %ld, got %ld\n",
30                       777L, s->value);
31                 break;
32         default:
33                 CHECK(true, "extra_sample", "unexpected sample seq %d, val %ld\n",
34                       s->seq, s->value);
35                 return -1;
36         }
37
38         return 0;
39 }
40
41 void test_ringbuf_multi(void)
42 {
43         struct test_ringbuf_multi *skel;
44         struct ring_buffer *ringbuf = NULL;
45         struct ring *ring_old;
46         struct ring *ring;
47         int err;
48         int page_size = getpagesize();
49         int proto_fd = -1;
50
51         skel = test_ringbuf_multi__open();
52         if (CHECK(!skel, "skel_open", "skeleton open failed\n"))
53                 return;
54
55         /* validate ringbuf size adjustment logic */
56         ASSERT_EQ(bpf_map__max_entries(skel->maps.ringbuf1), page_size, "rb1_size_before");
57         ASSERT_OK(bpf_map__set_max_entries(skel->maps.ringbuf1, page_size + 1), "rb1_resize");
58         ASSERT_EQ(bpf_map__max_entries(skel->maps.ringbuf1), 2 * page_size, "rb1_size_after");
59         ASSERT_OK(bpf_map__set_max_entries(skel->maps.ringbuf1, page_size), "rb1_reset");
60         ASSERT_EQ(bpf_map__max_entries(skel->maps.ringbuf1), page_size, "rb1_size_final");
61
62         proto_fd = bpf_map_create(BPF_MAP_TYPE_RINGBUF, NULL, 0, 0, page_size, NULL);
63         if (CHECK(proto_fd < 0, "bpf_map_create", "bpf_map_create failed\n"))
64                 goto cleanup;
65
66         err = bpf_map__set_inner_map_fd(skel->maps.ringbuf_hash, proto_fd);
67         if (CHECK(err != 0, "bpf_map__set_inner_map_fd", "bpf_map__set_inner_map_fd failed\n"))
68                 goto cleanup;
69
70         err = test_ringbuf_multi__load(skel);
71         if (CHECK(err != 0, "skel_load", "skeleton load failed\n"))
72                 goto cleanup;
73
74         close(proto_fd);
75         proto_fd = -1;
76
77         /* make sure we can't resize ringbuf after object load */
78         if (!ASSERT_ERR(bpf_map__set_max_entries(skel->maps.ringbuf1, 3 * page_size), "rb1_resize_after_load"))
79                 goto cleanup;
80
81         /* only trigger BPF program for current process */
82         skel->bss->pid = getpid();
83
84         ringbuf = ring_buffer__new(bpf_map__fd(skel->maps.ringbuf1),
85                                    process_sample, (void *)(long)1, NULL);
86         if (CHECK(!ringbuf, "ringbuf_create", "failed to create ringbuf\n"))
87                 goto cleanup;
88
89         /* verify ring_buffer__ring returns expected results */
90         ring = ring_buffer__ring(ringbuf, 0);
91         if (!ASSERT_OK_PTR(ring, "ring_buffer__ring_idx_0"))
92                 goto cleanup;
93         ring_old = ring;
94         ring = ring_buffer__ring(ringbuf, 1);
95         ASSERT_ERR_PTR(ring, "ring_buffer__ring_idx_1");
96
97         err = ring_buffer__add(ringbuf, bpf_map__fd(skel->maps.ringbuf2),
98                               process_sample, (void *)(long)2);
99         if (CHECK(err, "ringbuf_add", "failed to add another ring\n"))
100                 goto cleanup;
101
102         /* verify adding a new ring didn't invalidate our older pointer */
103         ring = ring_buffer__ring(ringbuf, 0);
104         if (!ASSERT_EQ(ring, ring_old, "ring_buffer__ring_again"))
105                 goto cleanup;
106
107         err = test_ringbuf_multi__attach(skel);
108         if (CHECK(err, "skel_attach", "skeleton attachment failed: %d\n", err))
109                 goto cleanup;
110
111         /* trigger few samples, some will be skipped */
112         skel->bss->target_ring = 0;
113         skel->bss->value = 333;
114         syscall(__NR_getpgid);
115
116         /* skipped, no ringbuf in slot 1 */
117         skel->bss->target_ring = 1;
118         skel->bss->value = 555;
119         syscall(__NR_getpgid);
120
121         skel->bss->target_ring = 2;
122         skel->bss->value = 777;
123         syscall(__NR_getpgid);
124
125         /* poll for samples, should get 2 ringbufs back */
126         err = ring_buffer__poll(ringbuf, -1);
127         if (CHECK(err != 2, "poll_res", "expected 2 records, got %d\n", err))
128                 goto cleanup;
129
130         /* expect extra polling to return nothing */
131         err = ring_buffer__poll(ringbuf, 0);
132         if (CHECK(err < 0, "extra_samples", "poll result: %d\n", err))
133                 goto cleanup;
134
135         CHECK(skel->bss->dropped != 0, "err_dropped", "exp %ld, got %ld\n",
136               0L, skel->bss->dropped);
137         CHECK(skel->bss->skipped != 1, "err_skipped", "exp %ld, got %ld\n",
138               1L, skel->bss->skipped);
139         CHECK(skel->bss->total != 2, "err_total", "exp %ld, got %ld\n",
140               2L, skel->bss->total);
141
142 cleanup:
143         if (proto_fd >= 0)
144                 close(proto_fd);
145         ring_buffer__free(ringbuf);
146         test_ringbuf_multi__destroy(skel);
147 }
This page took 0.036751 seconds and 4 git commands to generate.