36
36
#include <sys/un.h>
37
37
#include <sys/wait.h>
38
38
39
- #if 0
40
-
41
39
#define NOTIF_TAG 0xfffffffULL
42
40
#define NONZC_TAG 0
43
41
#define ZC_TAG 1
49
47
MODE_MIXED = 3 ,
50
48
};
51
49
52
- static bool cfg_flush = false;
53
50
static bool cfg_cork = false;
54
51
static int cfg_mode = MODE_ZC_FIXED ;
55
52
static int cfg_nr_reqs = 8 ;
@@ -168,21 +165,6 @@ static int io_uring_register_buffers(struct io_uring *ring,
168
165
return (ret < 0 ) ? - errno : ret ;
169
166
}
170
167
171
- static int io_uring_register_notifications (struct io_uring * ring ,
172
- unsigned nr ,
173
- struct io_uring_notification_slot * slots )
174
- {
175
- int ret ;
176
- struct io_uring_notification_register r = {
177
- .nr_slots = nr ,
178
- .data = (unsigned long )slots ,
179
- };
180
-
181
- ret = syscall (__NR_io_uring_register , ring -> ring_fd ,
182
- IORING_REGISTER_NOTIFIERS , & r , sizeof (r ));
183
- return (ret < 0 ) ? - errno : ret ;
184
- }
185
-
186
168
static int io_uring_mmap (int fd , struct io_uring_params * p ,
187
169
struct io_uring_sq * sq , struct io_uring_cq * cq )
188
170
{
@@ -299,11 +281,10 @@ static inline void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd,
299
281
300
282
static inline void io_uring_prep_sendzc (struct io_uring_sqe * sqe , int sockfd ,
301
283
const void * buf , size_t len , int flags ,
302
- unsigned slot_idx , unsigned zc_flags )
284
+ unsigned zc_flags )
303
285
{
304
286
io_uring_prep_send (sqe , sockfd , buf , len , flags );
305
- sqe -> opcode = (__u8 ) IORING_OP_SENDZC_NOTIF ;
306
- sqe -> notification_idx = slot_idx ;
287
+ sqe -> opcode = (__u8 ) IORING_OP_SEND_ZC ;
307
288
sqe -> ioprio = zc_flags ;
308
289
}
309
290
@@ -376,7 +357,6 @@ static int do_setup_tx(int domain, int type, int protocol)
376
357
377
358
static void do_tx (int domain , int type , int protocol )
378
359
{
379
- struct io_uring_notification_slot b [1 ] = {{.tag = NOTIF_TAG }};
380
360
struct io_uring_sqe * sqe ;
381
361
struct io_uring_cqe * cqe ;
382
362
unsigned long packets = 0 , bytes = 0 ;
@@ -392,10 +372,6 @@ static void do_tx(int domain, int type, int protocol)
392
372
if (ret )
393
373
error (1 , ret , "io_uring: queue init" );
394
374
395
- ret = io_uring_register_notifications (& ring , 1 , b );
396
- if (ret )
397
- error (1 , ret , "io_uring: tx ctx registration" );
398
-
399
375
iov .iov_base = payload ;
400
376
iov .iov_len = cfg_payload_len ;
401
377
@@ -411,9 +387,8 @@ static void do_tx(int domain, int type, int protocol)
411
387
for (i = 0 ; i < cfg_nr_reqs ; i ++ ) {
412
388
unsigned zc_flags = 0 ;
413
389
unsigned buf_idx = 0 ;
414
- unsigned slot_idx = 0 ;
415
390
unsigned mode = cfg_mode ;
416
- unsigned msg_flags = 0 ;
391
+ unsigned msg_flags = MSG_WAITALL ;
417
392
418
393
if (cfg_mode == MODE_MIXED )
419
394
mode = rand () % 3 ;
@@ -425,13 +400,10 @@ static void do_tx(int domain, int type, int protocol)
425
400
cfg_payload_len , msg_flags );
426
401
sqe -> user_data = NONZC_TAG ;
427
402
} else {
428
- if (cfg_flush ) {
429
- zc_flags |= IORING_RECVSEND_NOTIF_FLUSH ;
430
- compl_cqes ++ ;
431
- }
403
+ compl_cqes ++ ;
432
404
io_uring_prep_sendzc (sqe , fd , payload ,
433
405
cfg_payload_len ,
434
- msg_flags , slot_idx , zc_flags );
406
+ msg_flags , zc_flags );
435
407
if (mode == MODE_ZC_FIXED ) {
436
408
sqe -> ioprio |= IORING_RECVSEND_FIXED_BUF ;
437
409
sqe -> buf_index = buf_idx ;
@@ -444,51 +416,57 @@ static void do_tx(int domain, int type, int protocol)
444
416
if (ret != cfg_nr_reqs )
445
417
error (1 , ret , "submit" );
446
418
419
+ if (cfg_cork )
420
+ do_setsockopt (fd , IPPROTO_UDP , UDP_CORK , 0 );
447
421
for (i = 0 ; i < cfg_nr_reqs ; i ++ ) {
448
422
ret = io_uring_wait_cqe (& ring , & cqe );
449
423
if (ret )
450
424
error (1 , ret , "wait cqe" );
451
425
452
- if (cqe -> user_data == NOTIF_TAG ) {
426
+ if (cqe -> user_data != NONZC_TAG &&
427
+ cqe -> user_data != ZC_TAG )
428
+ error (1 , - EINVAL , "invalid cqe->user_data" );
429
+
430
+ if (cqe -> flags & IORING_CQE_F_NOTIF ) {
431
+ if (cqe -> flags & IORING_CQE_F_MORE )
432
+ error (1 , - EINVAL , "invalid notif flags" );
453
433
compl_cqes -- ;
454
434
i -- ;
455
- } else if (cqe -> user_data != NONZC_TAG &&
456
- cqe -> user_data != ZC_TAG ) {
457
- error (1 , cqe -> res , "invalid user_data" );
458
- } else if (cqe -> res <= 0 && cqe -> res != - EAGAIN ) {
435
+ } else if (cqe -> res <= 0 ) {
436
+ if (cqe -> flags & IORING_CQE_F_MORE )
437
+ error (1 , cqe -> res , "more with a failed send" );
459
438
error (1 , cqe -> res , "send failed" );
460
439
} else {
461
- if (cqe -> res > 0 ) {
462
- packets ++ ;
463
- bytes += cqe -> res ;
464
- }
465
- /* failed requests don't flush */
466
- if (cfg_flush &&
467
- cqe -> res <= 0 &&
468
- cqe -> user_data == ZC_TAG )
469
- compl_cqes -- ;
440
+ if (cqe -> user_data == ZC_TAG &&
441
+ !(cqe -> flags & IORING_CQE_F_MORE ))
442
+ error (1 , cqe -> res , "missing more flag" );
443
+ packets ++ ;
444
+ bytes += cqe -> res ;
470
445
}
471
446
io_uring_cqe_seen (& ring );
472
447
}
473
- if (cfg_cork )
474
- do_setsockopt (fd , IPPROTO_UDP , UDP_CORK , 0 );
475
448
} while (gettimeofday_ms () < tstop );
476
449
477
- if (close (fd ))
478
- error (1 , errno , "close" );
479
-
480
- fprintf (stderr , "tx=%lu (MB=%lu), tx/s=%lu (MB/s=%lu)\n" ,
481
- packets , bytes >> 20 ,
482
- packets / (cfg_runtime_ms / 1000 ),
483
- (bytes >> 20 ) / (cfg_runtime_ms / 1000 ));
484
-
485
450
while (compl_cqes ) {
486
451
ret = io_uring_wait_cqe (& ring , & cqe );
487
452
if (ret )
488
453
error (1 , ret , "wait cqe" );
454
+ if (cqe -> flags & IORING_CQE_F_MORE )
455
+ error (1 , - EINVAL , "invalid notif flags" );
456
+ if (!(cqe -> flags & IORING_CQE_F_NOTIF ))
457
+ error (1 , - EINVAL , "missing notif flag" );
458
+
489
459
io_uring_cqe_seen (& ring );
490
460
compl_cqes -- ;
491
461
}
462
+
463
+ fprintf (stderr , "tx=%lu (MB=%lu), tx/s=%lu (MB/s=%lu)\n" ,
464
+ packets , bytes >> 20 ,
465
+ packets / (cfg_runtime_ms / 1000 ),
466
+ (bytes >> 20 ) / (cfg_runtime_ms / 1000 ));
467
+
468
+ if (close (fd ))
469
+ error (1 , errno , "close" );
492
470
}
493
471
494
472
static void do_test (int domain , int type , int protocol )
@@ -502,8 +480,8 @@ static void do_test(int domain, int type, int protocol)
502
480
503
481
static void usage (const char * filepath )
504
482
{
505
- error (1 , 0 , "Usage: %s [-f] [-n<N>] [-z0] [-s<payload size>] "
506
- "(-4|-6) [-t<time s>] -D<dst_ip> udp " , filepath );
483
+ error (1 , 0 , "Usage: %s (-4|-6) (udp|tcp) -D<dst_ip> [-s<payload size>] "
484
+ "[-t<time s>] [-n<batch>] [-p<port>] [-m<mode>] " , filepath );
507
485
}
508
486
509
487
static void parse_opts (int argc , char * * argv )
@@ -521,7 +499,7 @@ static void parse_opts(int argc, char **argv)
521
499
usage (argv [0 ]);
522
500
cfg_payload_len = max_payload_len ;
523
501
524
- while ((c = getopt (argc , argv , "46D:p:s:t:n:fc :m:" )) != -1 ) {
502
+ while ((c = getopt (argc , argv , "46D:p:s:t:n:c :m:" )) != -1 ) {
525
503
switch (c ) {
526
504
case '4' :
527
505
if (cfg_family != PF_UNSPEC )
@@ -550,9 +528,6 @@ static void parse_opts(int argc, char **argv)
550
528
case 'n' :
551
529
cfg_nr_reqs = strtoul (optarg , NULL , 0 );
552
530
break ;
553
- case 'f' :
554
- cfg_flush = 1 ;
555
- break ;
556
531
case 'c' :
557
532
cfg_cork = strtol (optarg , NULL , 0 );
558
533
break ;
@@ -585,8 +560,6 @@ static void parse_opts(int argc, char **argv)
585
560
586
561
if (cfg_payload_len > max_payload_len )
587
562
error (1 , 0 , "-s: payload exceeds max (%d)" , max_payload_len );
588
- if (cfg_mode == MODE_NONZC && cfg_flush )
589
- error (1 , 0 , "-f: only zerocopy modes support notifications" );
590
563
if (optind != argc - 1 )
591
564
usage (argv [0 ]);
592
565
}
@@ -605,10 +578,3 @@ int main(int argc, char **argv)
605
578
error (1 , 0 , "unknown cfg_test %s" , cfg_test );
606
579
return 0 ;
607
580
}
608
-
609
- #else
610
- int main (int argc , char * * argv )
611
- {
612
- return 0 ;
613
- }
614
- #endif
0 commit comments