@@ -19,6 +19,7 @@ static struct {
1919 int ringbuf_sz ; /* per-ringbuf, in bytes */
2020 bool ringbuf_use_output ; /* use slower output API */
2121 int perfbuf_sz ; /* per-CPU size, in pages */
22+ bool overwrite ;
2223} args = {
2324 .back2back = false,
2425 .batch_cnt = 500 ,
@@ -27,6 +28,7 @@ static struct {
2728 .ringbuf_sz = 512 * 1024 ,
2829 .ringbuf_use_output = false,
2930 .perfbuf_sz = 128 ,
31+ .overwrite = false,
3032};
3133
3234enum {
3537 ARG_RB_BATCH_CNT = 2002 ,
3638 ARG_RB_SAMPLED = 2003 ,
3739 ARG_RB_SAMPLE_RATE = 2004 ,
40+ ARG_RB_OVERWRITE = 2005 ,
3841};
3942
4043static const struct argp_option opts [] = {
@@ -43,6 +46,7 @@ static const struct argp_option opts[] = {
4346 { "rb-batch-cnt" , ARG_RB_BATCH_CNT , "CNT" , 0 , "Set BPF-side record batch count" },
4447 { "rb-sampled" , ARG_RB_SAMPLED , NULL , 0 , "Notification sampling" },
4548 { "rb-sample-rate" , ARG_RB_SAMPLE_RATE , "RATE" , 0 , "Notification sample rate" },
49+ { "rb-overwrite" , ARG_RB_OVERWRITE , NULL , 0 , "Overwrite mode" },
4650 {},
4751};
4852
@@ -72,6 +76,9 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
7276 argp_usage (state );
7377 }
7478 break ;
79+ case ARG_RB_OVERWRITE :
80+ args .overwrite = true;
81+ break ;
7582 default :
7683 return ARGP_ERR_UNKNOWN ;
7784 }
@@ -95,8 +102,30 @@ static inline void bufs_trigger_batch(void)
95102
96103static void bufs_validate (void )
97104{
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" );
100129 exit (1 );
101130 }
102131
@@ -132,8 +161,10 @@ static void ringbuf_libbpf_measure(struct bench_res *res)
132161 res -> drops = atomic_swap (& ctx -> skel -> bss -> dropped , 0 );
133162}
134163
135- static struct ringbuf_bench * ringbuf_setup_skeleton (void )
164+ static struct ringbuf_bench * ringbuf_setup_skeleton (int bench_prod )
136165{
166+ __u32 flags ;
167+ struct bpf_map * ringbuf ;
137168 struct ringbuf_bench * skel ;
138169
139170 setup_libbpf ();
@@ -146,12 +177,19 @@ static struct ringbuf_bench *ringbuf_setup_skeleton(void)
146177
147178 skel -> rodata -> batch_cnt = args .batch_cnt ;
148179 skel -> rodata -> use_output = args .ringbuf_use_output ? 1 : 0 ;
180+ skel -> rodata -> bench_prod = bench_prod ;
149181
150182 if (args .sampled )
151183 /* record data + header take 16 bytes */
152184 skel -> rodata -> wakeup_data_size = args .sample_rate * 16 ;
153185
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 );
155193
156194 if (ringbuf_bench__load (skel )) {
157195 fprintf (stderr , "failed to load skeleton\n" );
@@ -171,10 +209,13 @@ static void ringbuf_libbpf_setup(void)
171209{
172210 struct ringbuf_libbpf_ctx * ctx = & ringbuf_libbpf_ctx ;
173211 struct bpf_link * link ;
212+ int map_fd ;
174213
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 );
178219 if (!ctx -> ringbuf ) {
179220 fprintf (stderr , "failed to create ringbuf\n" );
180221 exit (1 );
@@ -232,7 +273,7 @@ static void ringbuf_custom_setup(void)
232273 void * tmp ;
233274 int err ;
234275
235- ctx -> skel = ringbuf_setup_skeleton ();
276+ ctx -> skel = ringbuf_setup_skeleton (0 );
236277
237278 ctx -> epoll_fd = epoll_create1 (EPOLL_CLOEXEC );
238279 if (ctx -> epoll_fd < 0 ) {
@@ -277,6 +318,33 @@ static void ringbuf_custom_setup(void)
277318 }
278319}
279320
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+
280348#define RINGBUF_BUSY_BIT (1 << 31)
281349#define RINGBUF_DISCARD_BIT (1 << 30)
282350#define RINGBUF_META_LEN 8
@@ -540,6 +608,17 @@ const struct bench bench_rb_custom = {
540608 .report_final = hits_drops_report_final ,
541609};
542610
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+
543622const struct bench bench_pb_libbpf = {
544623 .name = "pb-libbpf" ,
545624 .argp = & bench_ringbufs_argp ,
0 commit comments