@@ -61,6 +61,9 @@ static int cfg_port = 8000;
61
61
static int cfg_payload_len ;
62
62
static const char * cfg_ifname ;
63
63
static int cfg_queue_id = -1 ;
64
+ static bool cfg_oneshot ;
65
+ static int cfg_oneshot_recvs ;
66
+ static int cfg_send_size = SEND_SIZE ;
64
67
static struct sockaddr_in6 cfg_addr ;
65
68
66
69
static char payload [SEND_SIZE ] __attribute__((aligned (PAGE_SIZE )));
@@ -196,6 +199,17 @@ static void add_recvzc(struct io_uring *ring, int sockfd)
196
199
sqe -> user_data = 2 ;
197
200
}
198
201
202
+ static void add_recvzc_oneshot (struct io_uring * ring , int sockfd , size_t len )
203
+ {
204
+ struct io_uring_sqe * sqe ;
205
+
206
+ sqe = io_uring_get_sqe (ring );
207
+
208
+ io_uring_prep_rw (IORING_OP_RECV_ZC , sqe , sockfd , NULL , len , 0 );
209
+ sqe -> ioprio |= IORING_RECV_MULTISHOT ;
210
+ sqe -> user_data = 2 ;
211
+ }
212
+
199
213
static void process_accept (struct io_uring * ring , struct io_uring_cqe * cqe )
200
214
{
201
215
if (cqe -> res < 0 )
@@ -204,7 +218,10 @@ static void process_accept(struct io_uring *ring, struct io_uring_cqe *cqe)
204
218
error (1 , 0 , "Unexpected second connection" );
205
219
206
220
connfd = cqe -> res ;
207
- add_recvzc (ring , connfd );
221
+ if (cfg_oneshot )
222
+ add_recvzc_oneshot (ring , connfd , PAGE_SIZE );
223
+ else
224
+ add_recvzc (ring , connfd );
208
225
}
209
226
210
227
static void process_recvzc (struct io_uring * ring , struct io_uring_cqe * cqe )
@@ -218,16 +235,22 @@ static void process_recvzc(struct io_uring *ring, struct io_uring_cqe *cqe)
218
235
ssize_t n ;
219
236
int i ;
220
237
221
- if (cqe -> res == 0 && cqe -> flags == 0 ) {
238
+ if (cqe -> res == 0 && cqe -> flags == 0 && cfg_oneshot_recvs == 0 ) {
222
239
stop = true;
223
240
return ;
224
241
}
225
242
226
243
if (cqe -> res < 0 )
227
244
error (1 , 0 , "recvzc(): %d" , cqe -> res );
228
245
229
- if (!(cqe -> flags & IORING_CQE_F_MORE ))
246
+ if (cfg_oneshot ) {
247
+ if (cqe -> res == 0 && cqe -> flags == 0 && cfg_oneshot_recvs ) {
248
+ add_recvzc_oneshot (ring , connfd , PAGE_SIZE );
249
+ cfg_oneshot_recvs -- ;
250
+ }
251
+ } else if (!(cqe -> flags & IORING_CQE_F_MORE )) {
230
252
add_recvzc (ring , connfd );
253
+ }
231
254
232
255
rcqe = (struct io_uring_zcrx_cqe * )(cqe + 1 );
233
256
@@ -237,7 +260,7 @@ static void process_recvzc(struct io_uring *ring, struct io_uring_cqe *cqe)
237
260
238
261
for (i = 0 ; i < n ; i ++ ) {
239
262
if (* (data + i ) != payload [(received + i )])
240
- error (1 , 0 , "payload mismatch" );
263
+ error (1 , 0 , "payload mismatch at " , i );
241
264
}
242
265
received += n ;
243
266
@@ -313,7 +336,7 @@ static void run_server(void)
313
336
314
337
static void run_client (void )
315
338
{
316
- ssize_t to_send = SEND_SIZE ;
339
+ ssize_t to_send = cfg_send_size ;
317
340
ssize_t sent = 0 ;
318
341
ssize_t chunk , res ;
319
342
int fd ;
@@ -360,7 +383,7 @@ static void parse_opts(int argc, char **argv)
360
383
usage (argv [0 ]);
361
384
cfg_payload_len = max_payload_len ;
362
385
363
- while ((c = getopt (argc , argv , "46sch :p:l:i:q:" )) != -1 ) {
386
+ while ((c = getopt (argc , argv , "sch :p:l:i:q:o:z :" )) != -1 ) {
364
387
switch (c ) {
365
388
case 's' :
366
389
if (cfg_client )
@@ -387,6 +410,14 @@ static void parse_opts(int argc, char **argv)
387
410
case 'q' :
388
411
cfg_queue_id = strtoul (optarg , NULL , 0 );
389
412
break ;
413
+ case 'o' : {
414
+ cfg_oneshot = true;
415
+ cfg_oneshot_recvs = strtoul (optarg , NULL , 0 );
416
+ break ;
417
+ }
418
+ case 'z' :
419
+ cfg_send_size = strtoul (optarg , NULL , 0 );
420
+ break ;
390
421
}
391
422
}
392
423
0 commit comments