~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/prog_tests/ringbuf_multi.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 }
148 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php