@@ -545,19 +545,6 @@ bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count)
545
545
return __ice_alloc_rx_bufs_zc (rx_ring , leftover );
546
546
}
547
547
548
- /**
549
- * ice_bump_ntc - Bump the next_to_clean counter of an Rx ring
550
- * @rx_ring: Rx ring
551
- */
552
- static void ice_bump_ntc (struct ice_rx_ring * rx_ring )
553
- {
554
- int ntc = rx_ring -> next_to_clean + 1 ;
555
-
556
- ntc = (ntc < rx_ring -> count ) ? ntc : 0 ;
557
- rx_ring -> next_to_clean = ntc ;
558
- prefetch (ICE_RX_DESC (rx_ring , ntc ));
559
- }
560
-
561
548
/**
562
549
* ice_construct_skb_zc - Create an sk_buff from zero-copy buffer
563
550
* @rx_ring: Rx ring
@@ -572,8 +559,14 @@ ice_construct_skb_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
572
559
{
573
560
unsigned int totalsize = xdp -> data_end - xdp -> data_meta ;
574
561
unsigned int metasize = xdp -> data - xdp -> data_meta ;
562
+ struct skb_shared_info * sinfo = NULL ;
575
563
struct sk_buff * skb ;
564
+ u32 nr_frags = 0 ;
576
565
566
+ if (unlikely (xdp_buff_has_frags (xdp ))) {
567
+ sinfo = xdp_get_shared_info_from_buff (xdp );
568
+ nr_frags = sinfo -> nr_frags ;
569
+ }
577
570
net_prefetch (xdp -> data_meta );
578
571
579
572
skb = __napi_alloc_skb (& rx_ring -> q_vector -> napi , totalsize ,
@@ -589,6 +582,29 @@ ice_construct_skb_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
589
582
__skb_pull (skb , metasize );
590
583
}
591
584
585
+ if (likely (!xdp_buff_has_frags (xdp )))
586
+ goto out ;
587
+
588
+ for (int i = 0 ; i < nr_frags ; i ++ ) {
589
+ struct skb_shared_info * skinfo = skb_shinfo (skb );
590
+ skb_frag_t * frag = & sinfo -> frags [i ];
591
+ struct page * page ;
592
+ void * addr ;
593
+
594
+ page = dev_alloc_page ();
595
+ if (!page ) {
596
+ dev_kfree_skb (skb );
597
+ return NULL ;
598
+ }
599
+ addr = page_to_virt (page );
600
+
601
+ memcpy (addr , skb_frag_page (frag ), skb_frag_size (frag ));
602
+
603
+ __skb_fill_page_desc_noacc (skinfo , skinfo -> nr_frags ++ ,
604
+ addr , 0 , skb_frag_size (frag ));
605
+ }
606
+
607
+ out :
592
608
xsk_buff_free (xdp );
593
609
return skb ;
594
610
}
@@ -752,6 +768,34 @@ ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
752
768
return result ;
753
769
}
754
770
771
+ static int
772
+ ice_add_xsk_frag (struct ice_rx_ring * rx_ring , struct xdp_buff * first ,
773
+ struct xdp_buff * xdp , const unsigned int size )
774
+ {
775
+ struct skb_shared_info * sinfo = xdp_get_shared_info_from_buff (first );
776
+
777
+ if (!size )
778
+ return 0 ;
779
+
780
+ if (!xdp_buff_has_frags (first )) {
781
+ sinfo -> nr_frags = 0 ;
782
+ sinfo -> xdp_frags_size = 0 ;
783
+ xdp_buff_set_frags_flag (first );
784
+ }
785
+
786
+ if (unlikely (sinfo -> nr_frags == MAX_SKB_FRAGS )) {
787
+ xsk_buff_free (first );
788
+ return - ENOMEM ;
789
+ }
790
+
791
+ __skb_fill_page_desc_noacc (sinfo , sinfo -> nr_frags ++ ,
792
+ virt_to_page (xdp -> data_hard_start ), 0 , size );
793
+ sinfo -> xdp_frags_size += size ;
794
+ xsk_buff_add_frag (xdp );
795
+
796
+ return 0 ;
797
+ }
798
+
755
799
/**
756
800
* ice_clean_rx_irq_zc - consumes packets from the hardware ring
757
801
* @rx_ring: AF_XDP Rx ring
@@ -762,9 +806,14 @@ ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
762
806
int ice_clean_rx_irq_zc (struct ice_rx_ring * rx_ring , int budget )
763
807
{
764
808
unsigned int total_rx_bytes = 0 , total_rx_packets = 0 ;
809
+ struct xsk_buff_pool * xsk_pool = rx_ring -> xsk_pool ;
810
+ u32 ntc = rx_ring -> next_to_clean ;
811
+ u32 ntu = rx_ring -> next_to_use ;
812
+ struct xdp_buff * first = NULL ;
765
813
struct ice_tx_ring * xdp_ring ;
766
814
unsigned int xdp_xmit = 0 ;
767
815
struct bpf_prog * xdp_prog ;
816
+ u32 cnt = rx_ring -> count ;
768
817
bool failure = false;
769
818
int entries_to_alloc ;
770
819
@@ -774,6 +823,9 @@ int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget)
774
823
xdp_prog = READ_ONCE (rx_ring -> xdp_prog );
775
824
xdp_ring = rx_ring -> xdp_ring ;
776
825
826
+ if (ntc != rx_ring -> first_desc )
827
+ first = * ice_xdp_buf (rx_ring , rx_ring -> first_desc );
828
+
777
829
while (likely (total_rx_packets < (unsigned int )budget )) {
778
830
union ice_32b_rx_flex_desc * rx_desc ;
779
831
unsigned int size , xdp_res = 0 ;
@@ -783,7 +835,7 @@ int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget)
783
835
u16 vlan_tag = 0 ;
784
836
u16 rx_ptype ;
785
837
786
- rx_desc = ICE_RX_DESC (rx_ring , rx_ring -> next_to_clean );
838
+ rx_desc = ICE_RX_DESC (rx_ring , ntc );
787
839
788
840
stat_err_bits = BIT (ICE_RX_FLEX_DESC_STATUS0_DD_S );
789
841
if (!ice_test_staterr (rx_desc -> wb .status_error0 , stat_err_bits ))
@@ -795,51 +847,61 @@ int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget)
795
847
*/
796
848
dma_rmb ();
797
849
798
- if (unlikely (rx_ring -> next_to_clean == rx_ring -> next_to_use ))
850
+ if (unlikely (ntc == ntu ))
799
851
break ;
800
852
801
- xdp = * ice_xdp_buf (rx_ring , rx_ring -> next_to_clean );
853
+ xdp = * ice_xdp_buf (rx_ring , ntc );
802
854
803
855
size = le16_to_cpu (rx_desc -> wb .pkt_len ) &
804
856
ICE_RX_FLX_DESC_PKT_LEN_M ;
805
- if (!size ) {
806
- xdp -> data = NULL ;
807
- xdp -> data_end = NULL ;
808
- xdp -> data_hard_start = NULL ;
809
- xdp -> data_meta = NULL ;
810
- goto construct_skb ;
811
- }
812
857
813
858
xsk_buff_set_size (xdp , size );
814
- xsk_buff_dma_sync_for_cpu (xdp , rx_ring -> xsk_pool );
859
+ xsk_buff_dma_sync_for_cpu (xdp , xsk_pool );
860
+
861
+ if (!first ) {
862
+ first = xdp ;
863
+ xdp_buff_clear_frags_flag (first );
864
+ } else if (ice_add_xsk_frag (rx_ring , first , xdp , size )) {
865
+ break ;
866
+ }
867
+
868
+ if (++ ntc == cnt )
869
+ ntc = 0 ;
870
+
871
+ if (ice_is_non_eop (rx_ring , rx_desc ))
872
+ continue ;
815
873
816
- xdp_res = ice_run_xdp_zc (rx_ring , xdp , xdp_prog , xdp_ring );
874
+ xdp_res = ice_run_xdp_zc (rx_ring , first , xdp_prog , xdp_ring );
817
875
if (likely (xdp_res & (ICE_XDP_TX | ICE_XDP_REDIR ))) {
818
876
xdp_xmit |= xdp_res ;
819
877
} else if (xdp_res == ICE_XDP_EXIT ) {
820
878
failure = true;
879
+ first = NULL ;
880
+ rx_ring -> first_desc = ntc ;
821
881
break ;
822
882
} else if (xdp_res == ICE_XDP_CONSUMED ) {
823
- xsk_buff_free (xdp );
883
+ xsk_buff_free (first );
824
884
} else if (xdp_res == ICE_XDP_PASS ) {
825
885
goto construct_skb ;
826
886
}
827
887
828
- total_rx_bytes += size ;
888
+ total_rx_bytes += xdp_get_buff_len ( first ) ;
829
889
total_rx_packets ++ ;
830
890
831
- ice_bump_ntc (rx_ring );
891
+ first = NULL ;
892
+ rx_ring -> first_desc = ntc ;
832
893
continue ;
833
894
834
895
construct_skb :
835
896
/* XDP_PASS path */
836
- skb = ice_construct_skb_zc (rx_ring , xdp );
897
+ skb = ice_construct_skb_zc (rx_ring , first );
837
898
if (!skb ) {
838
899
rx_ring -> ring_stats -> rx_stats .alloc_buf_failed ++ ;
839
900
break ;
840
901
}
841
902
842
- ice_bump_ntc (rx_ring );
903
+ first = NULL ;
904
+ rx_ring -> first_desc = ntc ;
843
905
844
906
if (eth_skb_pad (skb )) {
845
907
skb = NULL ;
@@ -858,18 +920,22 @@ int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget)
858
920
ice_receive_skb (rx_ring , skb , vlan_tag );
859
921
}
860
922
861
- entries_to_alloc = ICE_DESC_UNUSED (rx_ring );
923
+ rx_ring -> next_to_clean = ntc ;
924
+ entries_to_alloc = ICE_RX_DESC_UNUSED (rx_ring );
862
925
if (entries_to_alloc > ICE_RING_QUARTER (rx_ring ))
863
926
failure |= !ice_alloc_rx_bufs_zc (rx_ring , entries_to_alloc );
864
927
865
928
ice_finalize_xdp_rx (xdp_ring , xdp_xmit , 0 );
866
929
ice_update_rx_ring_stats (rx_ring , total_rx_packets , total_rx_bytes );
867
930
868
- if (xsk_uses_need_wakeup (rx_ring -> xsk_pool )) {
869
- if (failure || rx_ring -> next_to_clean == rx_ring -> next_to_use )
870
- xsk_set_rx_need_wakeup (rx_ring -> xsk_pool );
931
+ if (xsk_uses_need_wakeup (xsk_pool )) {
932
+ /* ntu could have changed when allocating entries above, so
933
+ * use rx_ring value instead of stack based one
934
+ */
935
+ if (failure || ntc == rx_ring -> next_to_use )
936
+ xsk_set_rx_need_wakeup (xsk_pool );
871
937
else
872
- xsk_clear_rx_need_wakeup (rx_ring -> xsk_pool );
938
+ xsk_clear_rx_need_wakeup (xsk_pool );
873
939
874
940
return (int )total_rx_packets ;
875
941
}
0 commit comments