@@ -19,6 +19,8 @@ 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 ;
23+ bool bench_producer ;
2224} args = {
2325 .back2back = false,
2426 .batch_cnt = 500 ,
@@ -27,6 +29,8 @@ static struct {
2729 .ringbuf_sz = 512 * 1024 ,
2830 .ringbuf_use_output = false,
2931 .perfbuf_sz = 128 ,
32+ .overwrite = false,
33+ .bench_producer = false,
3034};
3135
3236enum {
3539 ARG_RB_BATCH_CNT = 2002 ,
3640 ARG_RB_SAMPLED = 2003 ,
3741 ARG_RB_SAMPLE_RATE = 2004 ,
42+ ARG_RB_OVERWRITE = 2005 ,
43+ ARG_RB_BENCH_PRODUCER = 2006 ,
3844};
3945
4046static const struct argp_option opts [] = {
@@ -43,6 +49,8 @@ static const struct argp_option opts[] = {
4349 { "rb-batch-cnt" , ARG_RB_BATCH_CNT , "CNT" , 0 , "Set BPF-side record batch count" },
4450 { "rb-sampled" , ARG_RB_SAMPLED , NULL , 0 , "Notification sampling" },
4551 { "rb-sample-rate" , ARG_RB_SAMPLE_RATE , "RATE" , 0 , "Notification sample rate" },
52+ { "rb-overwrite" , ARG_RB_OVERWRITE , NULL , 0 , "Overwrite mode" },
53+ { "rb-bench-producer" , ARG_RB_BENCH_PRODUCER , NULL , 0 , "Benchmark producer" },
4654 {},
4755};
4856
@@ -72,6 +80,12 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
7280 argp_usage (state );
7381 }
7482 break ;
83+ case ARG_RB_OVERWRITE :
84+ args .overwrite = true;
85+ break ;
86+ case ARG_RB_BENCH_PRODUCER :
87+ args .bench_producer = true;
88+ break ;
7589 default :
7690 return ARGP_ERR_UNKNOWN ;
7791 }
@@ -95,8 +109,33 @@ static inline void bufs_trigger_batch(void)
95109
96110static void bufs_validate (void )
97111{
98- if (env .consumer_cnt != 1 ) {
99- fprintf (stderr , "rb-libbpf benchmark needs one consumer!\n" );
112+ if (args .bench_producer && strcmp (env .bench_name , "rb-libbpf" )) {
113+ fprintf (stderr , "--rb-bench-producer only works with rb-libbpf!\n" );
114+ exit (1 );
115+ }
116+
117+ if (args .overwrite && !args .bench_producer ) {
118+ fprintf (stderr , "overwrite mode only works with --rb-bench-producer for now!\n" );
119+ exit (1 );
120+ }
121+
122+ if (args .bench_producer && env .consumer_cnt != 0 ) {
123+ fprintf (stderr , "no consumer is needed for --rb-bench-producer!\n" );
124+ exit (1 );
125+ }
126+
127+ if (args .bench_producer && args .back2back ) {
128+ fprintf (stderr , "back-to-back mode makes no sense for --rb-bench-producer!\n" );
129+ exit (1 );
130+ }
131+
132+ if (args .bench_producer && args .sampled ) {
133+ fprintf (stderr , "sampling mode makes no sense for --rb-bench-producer!\n" );
134+ exit (1 );
135+ }
136+
137+ if (!args .bench_producer && env .consumer_cnt != 1 ) {
138+ fprintf (stderr , "benchmarks without --rb-bench-producer require exactly one consumer!\n" );
100139 exit (1 );
101140 }
102141
@@ -128,12 +167,17 @@ static void ringbuf_libbpf_measure(struct bench_res *res)
128167{
129168 struct ringbuf_libbpf_ctx * ctx = & ringbuf_libbpf_ctx ;
130169
131- res -> hits = atomic_swap (& buf_hits .value , 0 );
170+ if (args .bench_producer )
171+ res -> hits = atomic_swap (& ctx -> skel -> bss -> hits , 0 );
172+ else
173+ res -> hits = atomic_swap (& buf_hits .value , 0 );
132174 res -> drops = atomic_swap (& ctx -> skel -> bss -> dropped , 0 );
133175}
134176
135177static struct ringbuf_bench * ringbuf_setup_skeleton (void )
136178{
179+ __u32 flags ;
180+ struct bpf_map * ringbuf ;
137181 struct ringbuf_bench * skel ;
138182
139183 setup_libbpf ();
@@ -146,12 +190,19 @@ static struct ringbuf_bench *ringbuf_setup_skeleton(void)
146190
147191 skel -> rodata -> batch_cnt = args .batch_cnt ;
148192 skel -> rodata -> use_output = args .ringbuf_use_output ? 1 : 0 ;
193+ skel -> rodata -> bench_producer = args .bench_producer ;
149194
150195 if (args .sampled )
151196 /* record data + header take 16 bytes */
152197 skel -> rodata -> wakeup_data_size = args .sample_rate * 16 ;
153198
154- bpf_map__set_max_entries (skel -> maps .ringbuf , args .ringbuf_sz );
199+ ringbuf = skel -> maps .ringbuf ;
200+ if (args .overwrite ) {
201+ flags = bpf_map__map_flags (ringbuf ) | BPF_F_RB_OVERWRITE ;
202+ bpf_map__set_map_flags (ringbuf , flags );
203+ }
204+
205+ bpf_map__set_max_entries (ringbuf , args .ringbuf_sz );
155206
156207 if (ringbuf_bench__load (skel )) {
157208 fprintf (stderr , "failed to load skeleton\n" );
@@ -171,10 +222,13 @@ static void ringbuf_libbpf_setup(void)
171222{
172223 struct ringbuf_libbpf_ctx * ctx = & ringbuf_libbpf_ctx ;
173224 struct bpf_link * link ;
225+ int map_fd ;
174226
175227 ctx -> skel = ringbuf_setup_skeleton ();
176- ctx -> ringbuf = ring_buffer__new (bpf_map__fd (ctx -> skel -> maps .ringbuf ),
177- buf_process_sample , NULL , NULL );
228+
229+ map_fd = bpf_map__fd (ctx -> skel -> maps .ringbuf );
230+ ctx -> ringbuf = ring_buffer__new (map_fd , buf_process_sample ,
231+ NULL , NULL );
178232 if (!ctx -> ringbuf ) {
179233 fprintf (stderr , "failed to create ringbuf\n" );
180234 exit (1 );
0 commit comments