36
36
#define TX_BATCH_SIZE 32
37
37
#define MAX_PER_SOCKET_BUDGET 32
38
38
39
+ struct xsk_addrs {
40
+ u32 num_descs ;
41
+ u64 addrs [MAX_SKB_FRAGS + 1 ];
42
+ };
43
+
44
+ struct xsk_generic_cache {
45
+ struct kmem_cache * cache ;
46
+ refcount_t users ;
47
+ };
48
+
49
+ DEFINE_PER_CPU (struct xsk_generic_cache , system_xsk_generic_cache );
50
+
39
51
void xsk_set_rx_need_wakeup (struct xsk_buff_pool * pool )
40
52
{
41
53
if (pool -> cached_need_wakeup & XDP_WAKEUP_RX )
@@ -532,25 +544,39 @@ static int xsk_wakeup(struct xdp_sock *xs, u8 flags)
532
544
return dev -> netdev_ops -> ndo_xsk_wakeup (dev , xs -> queue_id , flags );
533
545
}
534
546
535
- static int xsk_cq_reserve_addr_locked (struct xsk_buff_pool * pool , u64 addr )
547
+ static int xsk_cq_reserve_locked (struct xsk_buff_pool * pool )
536
548
{
537
549
unsigned long flags ;
538
550
int ret ;
539
551
540
552
spin_lock_irqsave (& pool -> cq_lock , flags );
541
- ret = xskq_prod_reserve_addr (pool -> cq , addr );
553
+ ret = xskq_prod_reserve (pool -> cq );
542
554
spin_unlock_irqrestore (& pool -> cq_lock , flags );
543
555
544
556
return ret ;
545
557
}
546
558
547
- static void xsk_cq_submit_locked (struct xsk_buff_pool * pool , u32 n )
559
+ static void xsk_cq_submit_addr_locked (struct xdp_sock * xs ,
560
+ struct sk_buff * skb )
548
561
{
562
+ struct xsk_buff_pool * pool = xs -> pool ;
563
+ struct xsk_addrs * xsk_addrs ;
549
564
unsigned long flags ;
565
+ u32 num_desc , i ;
566
+ u32 idx ;
567
+
568
+ xsk_addrs = (struct xsk_addrs * )skb_shinfo (skb )-> destructor_arg ;
569
+ num_desc = xsk_addrs -> num_descs ;
550
570
551
571
spin_lock_irqsave (& pool -> cq_lock , flags );
552
- xskq_prod_submit_n (pool -> cq , n );
572
+ idx = xskq_get_prod (pool -> cq );
573
+
574
+ for (i = 0 ; i < num_desc ; i ++ )
575
+ xskq_prod_write_addr (pool -> cq , idx + i , xsk_addrs -> addrs [i ]);
576
+ xskq_prod_submit_n (pool -> cq , num_desc );
577
+
553
578
spin_unlock_irqrestore (& pool -> cq_lock , flags );
579
+ kmem_cache_free (xs -> generic_cache , xsk_addrs );
554
580
}
555
581
556
582
static void xsk_cq_cancel_locked (struct xsk_buff_pool * pool , u32 n )
@@ -562,11 +588,6 @@ static void xsk_cq_cancel_locked(struct xsk_buff_pool *pool, u32 n)
562
588
spin_unlock_irqrestore (& pool -> cq_lock , flags );
563
589
}
564
590
565
- static u32 xsk_get_num_desc (struct sk_buff * skb )
566
- {
567
- return skb ? (long )skb_shinfo (skb )-> destructor_arg : 0 ;
568
- }
569
-
570
591
static void xsk_destruct_skb (struct sk_buff * skb )
571
592
{
572
593
struct xsk_tx_metadata_compl * compl = & skb_shinfo (skb )-> xsk_meta ;
@@ -576,21 +597,37 @@ static void xsk_destruct_skb(struct sk_buff *skb)
576
597
* compl -> tx_timestamp = ktime_get_tai_fast_ns ();
577
598
}
578
599
579
- xsk_cq_submit_locked (xdp_sk (skb -> sk )-> pool , xsk_get_num_desc ( skb ) );
600
+ xsk_cq_submit_addr_locked (xdp_sk (skb -> sk ), skb );
580
601
sock_wfree (skb );
581
602
}
582
603
583
- static void xsk_set_destructor_arg (struct sk_buff * skb )
604
+ static u32 xsk_get_num_desc (struct sk_buff * skb )
584
605
{
585
- long num = xsk_get_num_desc (xdp_sk (skb -> sk )-> skb ) + 1 ;
606
+ struct xsk_addrs * addrs ;
607
+
608
+ addrs = (struct xsk_addrs * )skb_shinfo (skb )-> destructor_arg ;
609
+ return addrs -> num_descs ;
610
+ }
586
611
587
- skb_shinfo (skb )-> destructor_arg = (void * )num ;
612
+ static void xsk_set_destructor_arg (struct sk_buff * skb , struct xsk_addrs * addrs )
613
+ {
614
+ skb_shinfo (skb )-> destructor_arg = (void * )addrs ;
615
+ }
616
+
617
+ static void xsk_inc_skb_descs (struct sk_buff * skb )
618
+ {
619
+ struct xsk_addrs * addrs ;
620
+
621
+ addrs = (struct xsk_addrs * )skb_shinfo (skb )-> destructor_arg ;
622
+ addrs -> num_descs ++ ;
588
623
}
589
624
590
625
static void xsk_consume_skb (struct sk_buff * skb )
591
626
{
592
627
struct xdp_sock * xs = xdp_sk (skb -> sk );
593
628
629
+ kmem_cache_free (xs -> generic_cache ,
630
+ (struct xsk_addrs * )skb_shinfo (skb )-> destructor_arg );
594
631
skb -> destructor = sock_wfree ;
595
632
xsk_cq_cancel_locked (xs -> pool , xsk_get_num_desc (skb ));
596
633
/* Free skb without triggering the perf drop trace */
@@ -605,10 +642,12 @@ static void xsk_drop_skb(struct sk_buff *skb)
605
642
}
606
643
607
644
static struct sk_buff * xsk_build_skb_zerocopy (struct xdp_sock * xs ,
608
- struct xdp_desc * desc )
645
+ struct xdp_desc * desc ,
646
+ struct kmem_cache * cache )
609
647
{
610
648
struct xsk_buff_pool * pool = xs -> pool ;
611
649
u32 hr , len , ts , offset , copy , copied ;
650
+ struct xsk_addrs * addrs = NULL ;
612
651
struct sk_buff * skb = xs -> skb ;
613
652
struct page * page ;
614
653
void * buffer ;
@@ -623,6 +662,12 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
623
662
return ERR_PTR (err );
624
663
625
664
skb_reserve (skb , hr );
665
+
666
+ addrs = kmem_cache_zalloc (cache , GFP_KERNEL );
667
+ if (!addrs )
668
+ return ERR_PTR (- ENOMEM );
669
+
670
+ xsk_set_destructor_arg (skb , addrs );
626
671
}
627
672
628
673
addr = desc -> addr ;
@@ -662,12 +707,13 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
662
707
{
663
708
struct xsk_tx_metadata * meta = NULL ;
664
709
struct net_device * dev = xs -> dev ;
710
+ struct xsk_addrs * addrs = NULL ;
665
711
struct sk_buff * skb = xs -> skb ;
666
712
bool first_frag = false;
667
713
int err ;
668
714
669
715
if (dev -> priv_flags & IFF_TX_SKB_NO_LINEAR ) {
670
- skb = xsk_build_skb_zerocopy (xs , desc );
716
+ skb = xsk_build_skb_zerocopy (xs , desc , xs -> generic_cache );
671
717
if (IS_ERR (skb )) {
672
718
err = PTR_ERR (skb );
673
719
goto free_err ;
@@ -694,6 +740,15 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
694
740
err = skb_store_bits (skb , 0 , buffer , len );
695
741
if (unlikely (err ))
696
742
goto free_err ;
743
+
744
+ addrs = kmem_cache_zalloc (xs -> generic_cache , GFP_KERNEL );
745
+ if (!addrs ) {
746
+ err = - ENOMEM ;
747
+ goto free_err ;
748
+ }
749
+
750
+ xsk_set_destructor_arg (skb , addrs );
751
+
697
752
} else {
698
753
int nr_frags = skb_shinfo (skb )-> nr_frags ;
699
754
struct page * page ;
@@ -759,7 +814,9 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
759
814
skb -> mark = READ_ONCE (xs -> sk .sk_mark );
760
815
skb -> destructor = xsk_destruct_skb ;
761
816
xsk_tx_metadata_to_compl (meta , & skb_shinfo (skb )-> xsk_meta );
762
- xsk_set_destructor_arg (skb );
817
+
818
+ addrs = (struct xsk_addrs * )skb_shinfo (skb )-> destructor_arg ;
819
+ addrs -> addrs [addrs -> num_descs ++ ] = desc -> addr ;
763
820
764
821
return skb ;
765
822
@@ -769,7 +826,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
769
826
770
827
if (err == - EOVERFLOW ) {
771
828
/* Drop the packet */
772
- xsk_set_destructor_arg (xs -> skb );
829
+ xsk_inc_skb_descs (xs -> skb );
773
830
xsk_drop_skb (xs -> skb );
774
831
xskq_cons_release (xs -> tx );
775
832
} else {
@@ -812,7 +869,7 @@ static int __xsk_generic_xmit(struct sock *sk)
812
869
* if there is space in it. This avoids having to implement
813
870
* any buffering in the Tx path.
814
871
*/
815
- err = xsk_cq_reserve_addr_locked (xs -> pool , desc . addr );
872
+ err = xsk_cq_reserve_locked (xs -> pool );
816
873
if (err ) {
817
874
err = - EAGAIN ;
818
875
goto out ;
@@ -1095,6 +1152,7 @@ static void xsk_delete_from_maps(struct xdp_sock *xs)
1095
1152
1096
1153
static int xsk_release (struct socket * sock )
1097
1154
{
1155
+ struct xsk_generic_cache * pcpu_cache ;
1098
1156
struct sock * sk = sock -> sk ;
1099
1157
struct xdp_sock * xs = xdp_sk (sk );
1100
1158
struct net * net ;
@@ -1123,6 +1181,15 @@ static int xsk_release(struct socket *sock)
1123
1181
xskq_destroy (xs -> fq_tmp );
1124
1182
xskq_destroy (xs -> cq_tmp );
1125
1183
1184
+ pcpu_cache = per_cpu_ptr (& system_xsk_generic_cache , xs -> queue_id );
1185
+ if (pcpu_cache -> cache ) {
1186
+ if (refcount_dec_and_test (& pcpu_cache -> users )) {
1187
+ kmem_cache_destroy (pcpu_cache -> cache );
1188
+ pcpu_cache -> cache = NULL ;
1189
+ xs -> generic_cache = NULL ;
1190
+ }
1191
+ }
1192
+
1126
1193
sock_orphan (sk );
1127
1194
sock -> sk = NULL ;
1128
1195
@@ -1153,6 +1220,33 @@ static bool xsk_validate_queues(struct xdp_sock *xs)
1153
1220
return xs -> fq_tmp && xs -> cq_tmp ;
1154
1221
}
1155
1222
1223
+ static int xsk_alloc_generic_xmit_cache (struct xdp_sock * xs , u16 qid )
1224
+ {
1225
+ struct xsk_generic_cache * pcpu_cache =
1226
+ per_cpu_ptr (& system_xsk_generic_cache , qid );
1227
+ struct kmem_cache * cache ;
1228
+ char cache_name [32 ];
1229
+
1230
+ if (refcount_read (& pcpu_cache -> users ) > 0 ) {
1231
+ refcount_inc (& pcpu_cache -> users );
1232
+ xs -> generic_cache = pcpu_cache -> cache ;
1233
+ return 0 ;
1234
+ }
1235
+
1236
+ snprintf (cache_name , sizeof (cache_name ),
1237
+ "xsk_generic_xmit_cache%d" , qid );
1238
+ cache = kmem_cache_create (cache_name , sizeof (struct xsk_addrs ), 0 ,
1239
+ SLAB_HWCACHE_ALIGN , NULL );
1240
+ if (!cache )
1241
+ return - ENOMEM ;
1242
+
1243
+ refcount_set (& pcpu_cache -> users , 1 );
1244
+ pcpu_cache -> cache = cache ;
1245
+ xs -> generic_cache = pcpu_cache -> cache ;
1246
+
1247
+ return 0 ;
1248
+ }
1249
+
1156
1250
static int xsk_bind (struct socket * sock , struct sockaddr * addr , int addr_len )
1157
1251
{
1158
1252
struct sockaddr_xdp * sxdp = (struct sockaddr_xdp * )addr ;
@@ -1306,6 +1400,16 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
1306
1400
xs -> zc = xs -> umem -> zc ;
1307
1401
xs -> sg = !!(xs -> umem -> flags & XDP_UMEM_SG_FLAG );
1308
1402
xs -> queue_id = qid ;
1403
+
1404
+ if (!xs -> zc ) {
1405
+ err = xsk_alloc_generic_xmit_cache (xs , qid );
1406
+ if (err ) {
1407
+ xp_destroy (xs -> pool );
1408
+ xs -> pool = NULL ;
1409
+ goto out_unlock ;
1410
+ }
1411
+ }
1412
+
1309
1413
xp_add_xsk (xs -> pool , xs );
1310
1414
1311
1415
if (qid < dev -> real_num_rx_queues ) {
0 commit comments