@@ -19,6 +19,7 @@ static struct {
19
19
int ringbuf_sz ; /* per-ringbuf, in bytes */
20
20
bool ringbuf_use_output ; /* use slower output API */
21
21
int perfbuf_sz ; /* per-CPU size, in pages */
22
+ bool overwrite ;
22
23
} args = {
23
24
.back2back = false,
24
25
.batch_cnt = 500 ,
@@ -27,6 +28,7 @@ static struct {
27
28
.ringbuf_sz = 512 * 1024 ,
28
29
.ringbuf_use_output = false,
29
30
.perfbuf_sz = 128 ,
31
+ .overwrite = false,
30
32
};
31
33
32
34
enum {
35
37
ARG_RB_BATCH_CNT = 2002 ,
36
38
ARG_RB_SAMPLED = 2003 ,
37
39
ARG_RB_SAMPLE_RATE = 2004 ,
40
+ ARG_RB_OVERWRITE = 2005 ,
38
41
};
39
42
40
43
static const struct argp_option opts [] = {
@@ -43,6 +46,7 @@ static const struct argp_option opts[] = {
43
46
{ "rb-batch-cnt" , ARG_RB_BATCH_CNT , "CNT" , 0 , "Set BPF-side record batch count" },
44
47
{ "rb-sampled" , ARG_RB_SAMPLED , NULL , 0 , "Notification sampling" },
45
48
{ "rb-sample-rate" , ARG_RB_SAMPLE_RATE , "RATE" , 0 , "Notification sample rate" },
49
+ { "rb-overwrite" , ARG_RB_OVERWRITE , NULL , 0 , "Overwrite mode" },
46
50
{},
47
51
};
48
52
@@ -72,6 +76,9 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
72
76
argp_usage (state );
73
77
}
74
78
break ;
79
+ case ARG_RB_OVERWRITE :
80
+ args .overwrite = true;
81
+ break ;
75
82
default :
76
83
return ARGP_ERR_UNKNOWN ;
77
84
}
@@ -95,8 +102,30 @@ static inline void bufs_trigger_batch(void)
95
102
96
103
static void bufs_validate (void )
97
104
{
98
- if (env .consumer_cnt != 1 ) {
99
- fprintf (stderr , "rb-libbpf benchmark needs one consumer!\n" );
105
+ bool bench_prod = !strcmp (env .bench_name , "rb-prod" );
106
+
107
+ if (args .overwrite && !bench_prod ) {
108
+ fprintf (stderr , "overwite mode only works with benchmakr rb-prod!\n" );
109
+ exit (1 );
110
+ }
111
+
112
+ if (bench_prod && env .consumer_cnt != 0 ) {
113
+ fprintf (stderr , "rb-prod benchmark does not need consumer!\n" );
114
+ exit (1 );
115
+ }
116
+
117
+ if (bench_prod && args .back2back ) {
118
+ fprintf (stderr , "back-to-back mode makes no sense for rb-prod!\n" );
119
+ exit (1 );
120
+ }
121
+
122
+ if (bench_prod && args .sampled ) {
123
+ fprintf (stderr , "sampling mode makes no sense for rb-prod!\n" );
124
+ exit (1 );
125
+ }
126
+
127
+ if (!bench_prod && env .consumer_cnt != 1 ) {
128
+ fprintf (stderr , "benchmarks excluding rb-prod need one consumer!\n" );
100
129
exit (1 );
101
130
}
102
131
@@ -132,8 +161,10 @@ static void ringbuf_libbpf_measure(struct bench_res *res)
132
161
res -> drops = atomic_swap (& ctx -> skel -> bss -> dropped , 0 );
133
162
}
134
163
135
- static struct ringbuf_bench * ringbuf_setup_skeleton (void )
164
+ static struct ringbuf_bench * ringbuf_setup_skeleton (int bench_prod )
136
165
{
166
+ __u32 flags ;
167
+ struct bpf_map * ringbuf ;
137
168
struct ringbuf_bench * skel ;
138
169
139
170
setup_libbpf ();
@@ -146,12 +177,19 @@ static struct ringbuf_bench *ringbuf_setup_skeleton(void)
146
177
147
178
skel -> rodata -> batch_cnt = args .batch_cnt ;
148
179
skel -> rodata -> use_output = args .ringbuf_use_output ? 1 : 0 ;
180
+ skel -> rodata -> bench_prod = bench_prod ;
149
181
150
182
if (args .sampled )
151
183
/* record data + header take 16 bytes */
152
184
skel -> rodata -> wakeup_data_size = args .sample_rate * 16 ;
153
185
154
- bpf_map__set_max_entries (skel -> maps .ringbuf , args .ringbuf_sz );
186
+ ringbuf = skel -> maps .ringbuf ;
187
+ if (args .overwrite ) {
188
+ flags = bpf_map__map_flags (ringbuf ) | BPF_F_OVERWRITE ;
189
+ bpf_map__set_map_flags (ringbuf , flags );
190
+ }
191
+
192
+ bpf_map__set_max_entries (ringbuf , args .ringbuf_sz );
155
193
156
194
if (ringbuf_bench__load (skel )) {
157
195
fprintf (stderr , "failed to load skeleton\n" );
@@ -171,10 +209,13 @@ static void ringbuf_libbpf_setup(void)
171
209
{
172
210
struct ringbuf_libbpf_ctx * ctx = & ringbuf_libbpf_ctx ;
173
211
struct bpf_link * link ;
212
+ int map_fd ;
174
213
175
- ctx -> skel = ringbuf_setup_skeleton ();
176
- ctx -> ringbuf = ring_buffer__new (bpf_map__fd (ctx -> skel -> maps .ringbuf ),
177
- buf_process_sample , NULL , NULL );
214
+ ctx -> skel = ringbuf_setup_skeleton (0 );
215
+
216
+ map_fd = bpf_map__fd (ctx -> skel -> maps .ringbuf );
217
+ ctx -> ringbuf = ring_buffer__new (map_fd , buf_process_sample ,
218
+ NULL , NULL );
178
219
if (!ctx -> ringbuf ) {
179
220
fprintf (stderr , "failed to create ringbuf\n" );
180
221
exit (1 );
@@ -232,7 +273,7 @@ static void ringbuf_custom_setup(void)
232
273
void * tmp ;
233
274
int err ;
234
275
235
- ctx -> skel = ringbuf_setup_skeleton ();
276
+ ctx -> skel = ringbuf_setup_skeleton (0 );
236
277
237
278
ctx -> epoll_fd = epoll_create1 (EPOLL_CLOEXEC );
238
279
if (ctx -> epoll_fd < 0 ) {
@@ -277,6 +318,33 @@ static void ringbuf_custom_setup(void)
277
318
}
278
319
}
279
320
321
+ /* RINGBUF-PRODUCER benchmark */
322
+ static struct ringbuf_prod_ctx {
323
+ struct ringbuf_bench * skel ;
324
+ } ringbuf_prod_ctx ;
325
+
326
+ static void ringbuf_prod_measure (struct bench_res * res )
327
+ {
328
+ struct ringbuf_prod_ctx * ctx = & ringbuf_prod_ctx ;
329
+
330
+ res -> hits = atomic_swap (& ctx -> skel -> bss -> hits , 0 );
331
+ res -> drops = atomic_swap (& ctx -> skel -> bss -> dropped , 0 );
332
+ }
333
+
334
+ static void ringbuf_prod_setup (void )
335
+ {
336
+ struct ringbuf_prod_ctx * ctx = & ringbuf_prod_ctx ;
337
+ struct bpf_link * link ;
338
+
339
+ ctx -> skel = ringbuf_setup_skeleton (1 );
340
+
341
+ link = bpf_program__attach (ctx -> skel -> progs .bench_ringbuf );
342
+ if (!link ) {
343
+ fprintf (stderr , "failed to attach program!\n" );
344
+ exit (1 );
345
+ }
346
+ }
347
+
280
348
#define RINGBUF_BUSY_BIT (1 << 31)
281
349
#define RINGBUF_DISCARD_BIT (1 << 30)
282
350
#define RINGBUF_META_LEN 8
@@ -540,6 +608,17 @@ const struct bench bench_rb_custom = {
540
608
.report_final = hits_drops_report_final ,
541
609
};
542
610
611
+ const struct bench bench_rb_prod = {
612
+ .name = "rb-prod" ,
613
+ .argp = & bench_ringbufs_argp ,
614
+ .validate = bufs_validate ,
615
+ .setup = ringbuf_prod_setup ,
616
+ .producer_thread = bufs_sample_producer ,
617
+ .measure = ringbuf_prod_measure ,
618
+ .report_progress = hits_drops_report_progress ,
619
+ .report_final = hits_drops_report_final ,
620
+ };
621
+
543
622
const struct bench bench_pb_libbpf = {
544
623
.name = "pb-libbpf" ,
545
624
.argp = & bench_ringbufs_argp ,
0 commit comments