3636#include <sys/un.h>
3737#include <sys/wait.h>
3838
39- #if 0
40-
4139#define NOTIF_TAG 0xfffffffULL
4240#define NONZC_TAG 0
4341#define ZC_TAG 1
4947 MODE_MIXED = 3 ,
5048};
5149
52- static bool cfg_flush = false;
5350static bool cfg_cork = false;
5451static int cfg_mode = MODE_ZC_FIXED ;
5552static int cfg_nr_reqs = 8 ;
@@ -168,21 +165,6 @@ static int io_uring_register_buffers(struct io_uring *ring,
168165 return (ret < 0 ) ? - errno : ret ;
169166}
170167
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-
186168static int io_uring_mmap (int fd , struct io_uring_params * p ,
187169 struct io_uring_sq * sq , struct io_uring_cq * cq )
188170{
@@ -299,11 +281,10 @@ static inline void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd,
299281
300282static inline void io_uring_prep_sendzc (struct io_uring_sqe * sqe , int sockfd ,
301283 const void * buf , size_t len , int flags ,
302- unsigned slot_idx , unsigned zc_flags )
284+ unsigned zc_flags )
303285{
304286 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 ;
307288 sqe -> ioprio = zc_flags ;
308289}
309290
@@ -376,7 +357,6 @@ static int do_setup_tx(int domain, int type, int protocol)
376357
377358static void do_tx (int domain , int type , int protocol )
378359{
379- struct io_uring_notification_slot b [1 ] = {{.tag = NOTIF_TAG }};
380360 struct io_uring_sqe * sqe ;
381361 struct io_uring_cqe * cqe ;
382362 unsigned long packets = 0 , bytes = 0 ;
@@ -392,10 +372,6 @@ static void do_tx(int domain, int type, int protocol)
392372 if (ret )
393373 error (1 , ret , "io_uring: queue init" );
394374
395- ret = io_uring_register_notifications (& ring , 1 , b );
396- if (ret )
397- error (1 , ret , "io_uring: tx ctx registration" );
398-
399375 iov .iov_base = payload ;
400376 iov .iov_len = cfg_payload_len ;
401377
@@ -411,9 +387,8 @@ static void do_tx(int domain, int type, int protocol)
411387 for (i = 0 ; i < cfg_nr_reqs ; i ++ ) {
412388 unsigned zc_flags = 0 ;
413389 unsigned buf_idx = 0 ;
414- unsigned slot_idx = 0 ;
415390 unsigned mode = cfg_mode ;
416- unsigned msg_flags = 0 ;
391+ unsigned msg_flags = MSG_WAITALL ;
417392
418393 if (cfg_mode == MODE_MIXED )
419394 mode = rand () % 3 ;
@@ -425,13 +400,10 @@ static void do_tx(int domain, int type, int protocol)
425400 cfg_payload_len , msg_flags );
426401 sqe -> user_data = NONZC_TAG ;
427402 } else {
428- if (cfg_flush ) {
429- zc_flags |= IORING_RECVSEND_NOTIF_FLUSH ;
430- compl_cqes ++ ;
431- }
403+ compl_cqes ++ ;
432404 io_uring_prep_sendzc (sqe , fd , payload ,
433405 cfg_payload_len ,
434- msg_flags , slot_idx , zc_flags );
406+ msg_flags , zc_flags );
435407 if (mode == MODE_ZC_FIXED ) {
436408 sqe -> ioprio |= IORING_RECVSEND_FIXED_BUF ;
437409 sqe -> buf_index = buf_idx ;
@@ -444,51 +416,57 @@ static void do_tx(int domain, int type, int protocol)
444416 if (ret != cfg_nr_reqs )
445417 error (1 , ret , "submit" );
446418
419+ if (cfg_cork )
420+ do_setsockopt (fd , IPPROTO_UDP , UDP_CORK , 0 );
447421 for (i = 0 ; i < cfg_nr_reqs ; i ++ ) {
448422 ret = io_uring_wait_cqe (& ring , & cqe );
449423 if (ret )
450424 error (1 , ret , "wait cqe" );
451425
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" );
453433 compl_cqes -- ;
454434 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" );
459438 error (1 , cqe -> res , "send failed" );
460439 } 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 ;
470445 }
471446 io_uring_cqe_seen (& ring );
472447 }
473- if (cfg_cork )
474- do_setsockopt (fd , IPPROTO_UDP , UDP_CORK , 0 );
475448 } while (gettimeofday_ms () < tstop );
476449
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-
485450 while (compl_cqes ) {
486451 ret = io_uring_wait_cqe (& ring , & cqe );
487452 if (ret )
488453 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+
489459 io_uring_cqe_seen (& ring );
490460 compl_cqes -- ;
491461 }
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" );
492470}
493471
494472static void do_test (int domain , int type , int protocol )
@@ -502,8 +480,8 @@ static void do_test(int domain, int type, int protocol)
502480
503481static void usage (const char * filepath )
504482{
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 );
507485}
508486
509487static void parse_opts (int argc , char * * argv )
@@ -521,7 +499,7 @@ static void parse_opts(int argc, char **argv)
521499 usage (argv [0 ]);
522500 cfg_payload_len = max_payload_len ;
523501
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 ) {
525503 switch (c ) {
526504 case '4' :
527505 if (cfg_family != PF_UNSPEC )
@@ -550,9 +528,6 @@ static void parse_opts(int argc, char **argv)
550528 case 'n' :
551529 cfg_nr_reqs = strtoul (optarg , NULL , 0 );
552530 break ;
553- case 'f' :
554- cfg_flush = 1 ;
555- break ;
556531 case 'c' :
557532 cfg_cork = strtol (optarg , NULL , 0 );
558533 break ;
@@ -585,8 +560,6 @@ static void parse_opts(int argc, char **argv)
585560
586561 if (cfg_payload_len > max_payload_len )
587562 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" );
590563 if (optind != argc - 1 )
591564 usage (argv [0 ]);
592565}
@@ -605,10 +578,3 @@ int main(int argc, char **argv)
605578 error (1 , 0 , "unknown cfg_test %s" , cfg_test );
606579 return 0 ;
607580}
608-
609- #else
610- int main (int argc , char * * argv )
611- {
612- return 0 ;
613- }
614- #endif
0 commit comments