@@ -248,8 +248,7 @@ int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size,
248248 return 0 ;
249249
250250out_mmap :
251- munmap (umem -> fill ,
252- off .fr .desc + umem -> config .fill_size * sizeof (__u64 ));
251+ munmap (map , off .fr .desc + umem -> config .fill_size * sizeof (__u64 ));
253252out_socket :
254253 close (umem -> fd );
255254out_umem_alloc :
@@ -388,21 +387,17 @@ static void xsk_delete_bpf_maps(struct xsk_socket *xsk)
388387{
389388 close (xsk -> qidconf_map_fd );
390389 close (xsk -> xsks_map_fd );
390+ xsk -> qidconf_map_fd = -1 ;
391+ xsk -> xsks_map_fd = -1 ;
391392}
392393
393- static int xsk_update_bpf_maps (struct xsk_socket * xsk , int qidconf_value ,
394- int xsks_value )
394+ static int xsk_lookup_bpf_maps (struct xsk_socket * xsk )
395395{
396- bool qidconf_map_updated = false, xsks_map_updated = false;
396+ __u32 i , * map_ids , num_maps , prog_len = sizeof (struct bpf_prog_info );
397+ __u32 map_len = sizeof (struct bpf_map_info );
397398 struct bpf_prog_info prog_info = {};
398- __u32 prog_len = sizeof (prog_info );
399399 struct bpf_map_info map_info ;
400- __u32 map_len = sizeof (map_info );
401- __u32 * map_ids ;
402- int reset_value = 0 ;
403- __u32 num_maps ;
404- unsigned int i ;
405- int err ;
400+ int fd , err ;
406401
407402 err = bpf_obj_get_info_by_fd (xsk -> prog_fd , & prog_info , & prog_len );
408403 if (err )
@@ -423,66 +418,71 @@ static int xsk_update_bpf_maps(struct xsk_socket *xsk, int qidconf_value,
423418 goto out_map_ids ;
424419
425420 for (i = 0 ; i < prog_info .nr_map_ids ; i ++ ) {
426- int fd ;
421+ if (xsk -> qidconf_map_fd != -1 && xsk -> xsks_map_fd != -1 )
422+ break ;
427423
428424 fd = bpf_map_get_fd_by_id (map_ids [i ]);
429- if (fd < 0 ) {
430- err = - errno ;
431- goto out_maps ;
432- }
425+ if (fd < 0 )
426+ continue ;
433427
434428 err = bpf_obj_get_info_by_fd (fd , & map_info , & map_len );
435- if (err )
436- goto out_maps ;
429+ if (err ) {
430+ close (fd );
431+ continue ;
432+ }
437433
438434 if (!strcmp (map_info .name , "qidconf_map" )) {
439- err = bpf_map_update_elem (fd , & xsk -> queue_id ,
440- & qidconf_value , 0 );
441- if (err )
442- goto out_maps ;
443- qidconf_map_updated = true;
444435 xsk -> qidconf_map_fd = fd ;
445- } else if (!strcmp (map_info .name , "xsks_map" )) {
446- err = bpf_map_update_elem (fd , & xsk -> queue_id ,
447- & xsks_value , 0 );
448- if (err )
449- goto out_maps ;
450- xsks_map_updated = true;
436+ continue ;
437+ }
438+
439+ if (!strcmp (map_info .name , "xsks_map" )) {
451440 xsk -> xsks_map_fd = fd ;
441+ continue ;
452442 }
453443
454- if (qidconf_map_updated && xsks_map_updated )
455- break ;
444+ close (fd );
456445 }
457446
458- if (!(qidconf_map_updated && xsks_map_updated )) {
447+ err = 0 ;
448+ if (xsk -> qidconf_map_fd < 0 || xsk -> xsks_map_fd < 0 ) {
459449 err = - ENOENT ;
460- goto out_maps ;
450+ xsk_delete_bpf_maps ( xsk ) ;
461451 }
462452
463- err = 0 ;
464- goto out_success ;
465-
466- out_maps :
467- if (qidconf_map_updated )
468- (void )bpf_map_update_elem (xsk -> qidconf_map_fd , & xsk -> queue_id ,
469- & reset_value , 0 );
470- if (xsks_map_updated )
471- (void )bpf_map_update_elem (xsk -> xsks_map_fd , & xsk -> queue_id ,
472- & reset_value , 0 );
473- out_success :
474- if (qidconf_map_updated )
475- close (xsk -> qidconf_map_fd );
476- if (xsks_map_updated )
477- close (xsk -> xsks_map_fd );
478453out_map_ids :
479454 free (map_ids );
480455 return err ;
481456}
482457
458+ static void xsk_clear_bpf_maps (struct xsk_socket * xsk )
459+ {
460+ int qid = false;
461+
462+ bpf_map_update_elem (xsk -> qidconf_map_fd , & xsk -> queue_id , & qid , 0 );
463+ bpf_map_delete_elem (xsk -> xsks_map_fd , & xsk -> queue_id );
464+ }
465+
466+ static int xsk_set_bpf_maps (struct xsk_socket * xsk )
467+ {
468+ int qid = true, fd = xsk -> fd , err ;
469+
470+ err = bpf_map_update_elem (xsk -> qidconf_map_fd , & xsk -> queue_id , & qid , 0 );
471+ if (err )
472+ goto out ;
473+
474+ err = bpf_map_update_elem (xsk -> xsks_map_fd , & xsk -> queue_id , & fd , 0 );
475+ if (err )
476+ goto out ;
477+
478+ return 0 ;
479+ out :
480+ xsk_clear_bpf_maps (xsk );
481+ return err ;
482+ }
483+
483484static int xsk_setup_xdp_prog (struct xsk_socket * xsk )
484485{
485- bool prog_attached = false;
486486 __u32 prog_id = 0 ;
487487 int err ;
488488
@@ -492,7 +492,6 @@ static int xsk_setup_xdp_prog(struct xsk_socket *xsk)
492492 return err ;
493493
494494 if (!prog_id ) {
495- prog_attached = true;
496495 err = xsk_create_bpf_maps (xsk );
497496 if (err )
498497 return err ;
@@ -502,20 +501,21 @@ static int xsk_setup_xdp_prog(struct xsk_socket *xsk)
502501 goto out_maps ;
503502 } else {
504503 xsk -> prog_fd = bpf_prog_get_fd_by_id (prog_id );
504+ err = xsk_lookup_bpf_maps (xsk );
505+ if (err )
506+ goto out_load ;
505507 }
506508
507- err = xsk_update_bpf_maps (xsk , true, xsk -> fd );
509+ err = xsk_set_bpf_maps (xsk );
508510 if (err )
509511 goto out_load ;
510512
511513 return 0 ;
512514
513515out_load :
514- if (prog_attached )
515- close (xsk -> prog_fd );
516+ close (xsk -> prog_fd );
516517out_maps :
517- if (prog_attached )
518- xsk_delete_bpf_maps (xsk );
518+ xsk_delete_bpf_maps (xsk );
519519 return err ;
520520}
521521
@@ -524,11 +524,11 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
524524 struct xsk_ring_cons * rx , struct xsk_ring_prod * tx ,
525525 const struct xsk_socket_config * usr_config )
526526{
527+ void * rx_map = NULL , * tx_map = NULL ;
527528 struct sockaddr_xdp sxdp = {};
528529 struct xdp_mmap_offsets off ;
529530 struct xsk_socket * xsk ;
530531 socklen_t optlen ;
531- void * map ;
532532 int err ;
533533
534534 if (!umem || !xsk_ptr || !rx || !tx )
@@ -594,40 +594,40 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
594594 }
595595
596596 if (rx ) {
597- map = xsk_mmap (NULL , off .rx .desc +
598- xsk -> config .rx_size * sizeof (struct xdp_desc ),
599- PROT_READ | PROT_WRITE ,
600- MAP_SHARED | MAP_POPULATE ,
601- xsk -> fd , XDP_PGOFF_RX_RING );
602- if (map == MAP_FAILED ) {
597+ rx_map = xsk_mmap (NULL , off .rx .desc +
598+ xsk -> config .rx_size * sizeof (struct xdp_desc ),
599+ PROT_READ | PROT_WRITE ,
600+ MAP_SHARED | MAP_POPULATE ,
601+ xsk -> fd , XDP_PGOFF_RX_RING );
602+ if (rx_map == MAP_FAILED ) {
603603 err = - errno ;
604604 goto out_socket ;
605605 }
606606
607607 rx -> mask = xsk -> config .rx_size - 1 ;
608608 rx -> size = xsk -> config .rx_size ;
609- rx -> producer = map + off .rx .producer ;
610- rx -> consumer = map + off .rx .consumer ;
611- rx -> ring = map + off .rx .desc ;
609+ rx -> producer = rx_map + off .rx .producer ;
610+ rx -> consumer = rx_map + off .rx .consumer ;
611+ rx -> ring = rx_map + off .rx .desc ;
612612 }
613613 xsk -> rx = rx ;
614614
615615 if (tx ) {
616- map = xsk_mmap (NULL , off .tx .desc +
617- xsk -> config .tx_size * sizeof (struct xdp_desc ),
618- PROT_READ | PROT_WRITE ,
619- MAP_SHARED | MAP_POPULATE ,
620- xsk -> fd , XDP_PGOFF_TX_RING );
621- if (map == MAP_FAILED ) {
616+ tx_map = xsk_mmap (NULL , off .tx .desc +
617+ xsk -> config .tx_size * sizeof (struct xdp_desc ),
618+ PROT_READ | PROT_WRITE ,
619+ MAP_SHARED | MAP_POPULATE ,
620+ xsk -> fd , XDP_PGOFF_TX_RING );
621+ if (tx_map == MAP_FAILED ) {
622622 err = - errno ;
623623 goto out_mmap_rx ;
624624 }
625625
626626 tx -> mask = xsk -> config .tx_size - 1 ;
627627 tx -> size = xsk -> config .tx_size ;
628- tx -> producer = map + off .tx .producer ;
629- tx -> consumer = map + off .tx .consumer ;
630- tx -> ring = map + off .tx .desc ;
628+ tx -> producer = tx_map + off .tx .producer ;
629+ tx -> consumer = tx_map + off .tx .consumer ;
630+ tx -> ring = tx_map + off .tx .desc ;
631631 tx -> cached_cons = xsk -> config .tx_size ;
632632 }
633633 xsk -> tx = tx ;
@@ -643,6 +643,9 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
643643 goto out_mmap_tx ;
644644 }
645645
646+ xsk -> qidconf_map_fd = -1 ;
647+ xsk -> xsks_map_fd = -1 ;
648+
646649 if (!(xsk -> config .libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD )) {
647650 err = xsk_setup_xdp_prog (xsk );
648651 if (err )
@@ -654,13 +657,11 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
654657
655658out_mmap_tx :
656659 if (tx )
657- munmap (xsk -> tx ,
658- off .tx .desc +
660+ munmap (tx_map , off .tx .desc +
659661 xsk -> config .tx_size * sizeof (struct xdp_desc ));
660662out_mmap_rx :
661663 if (rx )
662- munmap (xsk -> rx ,
663- off .rx .desc +
664+ munmap (rx_map , off .rx .desc +
664665 xsk -> config .rx_size * sizeof (struct xdp_desc ));
665666out_socket :
666667 if (-- umem -> refcount )
@@ -685,9 +686,9 @@ int xsk_umem__delete(struct xsk_umem *umem)
685686 optlen = sizeof (off );
686687 err = getsockopt (umem -> fd , SOL_XDP , XDP_MMAP_OFFSETS , & off , & optlen );
687688 if (!err ) {
688- munmap (umem -> fill -> ring ,
689+ munmap (umem -> fill -> ring - off . fr . desc ,
689690 off .fr .desc + umem -> config .fill_size * sizeof (__u64 ));
690- munmap (umem -> comp -> ring ,
691+ munmap (umem -> comp -> ring - off . cr . desc ,
691692 off .cr .desc + umem -> config .comp_size * sizeof (__u64 ));
692693 }
693694
@@ -699,26 +700,29 @@ int xsk_umem__delete(struct xsk_umem *umem)
699700
700701void xsk_socket__delete (struct xsk_socket * xsk )
701702{
703+ size_t desc_sz = sizeof (struct xdp_desc );
702704 struct xdp_mmap_offsets off ;
703705 socklen_t optlen ;
704706 int err ;
705707
706708 if (!xsk )
707709 return ;
708710
709- (void )xsk_update_bpf_maps (xsk , 0 , 0 );
711+ xsk_clear_bpf_maps (xsk );
712+ xsk_delete_bpf_maps (xsk );
710713
711714 optlen = sizeof (off );
712715 err = getsockopt (xsk -> fd , SOL_XDP , XDP_MMAP_OFFSETS , & off , & optlen );
713716 if (!err ) {
714- if (xsk -> rx )
715- munmap (xsk -> rx -> ring ,
716- off .rx .desc +
717- xsk -> config .rx_size * sizeof (struct xdp_desc ));
718- if (xsk -> tx )
719- munmap (xsk -> tx -> ring ,
720- off .tx .desc +
721- xsk -> config .tx_size * sizeof (struct xdp_desc ));
717+ if (xsk -> rx ) {
718+ munmap (xsk -> rx -> ring - off .rx .desc ,
719+ off .rx .desc + xsk -> config .rx_size * desc_sz );
720+ }
721+ if (xsk -> tx ) {
722+ munmap (xsk -> tx -> ring - off .tx .desc ,
723+ off .tx .desc + xsk -> config .tx_size * desc_sz );
724+ }
725+
722726 }
723727
724728 xsk -> umem -> refcount -- ;
0 commit comments