Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xsk: add indirect call for xsk_destruct_skb

Since Eric proposed an idea about adding indirect call wrappers for
UDP and managed to see a huge improvement[1], the same situation can
also be applied in xsk scenario.

This patch adds an indirect call for xsk and helps current copy mode
improve the performance by around 1% stably which was observed with
IXGBE at 10Gb/sec loaded. If the throughput grows, the positive effect
will be magnified. I applied this patch on top of batch xmit series[2],
and was able to see <5% improvement from our internal application
which is a little bit unstable though.

Use INDIRECT wrappers to keep xsk_destruct_skb static as it used to
be when the mitigation config is off.

Be aware of the freeing path that can be very hot since the frequency
can reach around 2,000,000 times per second with the xdpsock test.

[1]: https://lore.kernel.org/netdev/20251006193103.2684156-2-edumazet@google.com/
[2]: https://lore.kernel.org/all/20251021131209.41491-1-kerneljasonxing@gmail.com/

Suggested-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: Jason Xing <kernelxing@tencent.com>
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Link: https://patch.msgid.link/20251031103328.95468-1-kerneljasonxing@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Jason Xing and committed by
Paolo Abeni
8da7bea7 b981e100

+14 -4
+7
include/net/xdp_sock.h
··· 125 125 int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp); 126 126 int __xsk_map_redirect(struct xdp_sock *xs, struct xdp_buff *xdp); 127 127 void __xsk_map_flush(struct list_head *flush_list); 128 + INDIRECT_CALLABLE_DECLARE(void xsk_destruct_skb(struct sk_buff *)); 128 129 129 130 /** 130 131 * xsk_tx_metadata_to_compl - Save enough relevant metadata information ··· 218 217 static inline void __xsk_map_flush(struct list_head *flush_list) 219 218 { 220 219 } 220 + 221 + #ifdef CONFIG_MITIGATION_RETPOLINE 222 + static inline void xsk_destruct_skb(struct sk_buff *skb) 223 + { 224 + } 225 + #endif 221 226 222 227 static inline void xsk_tx_metadata_to_compl(struct xsk_tx_metadata *meta, 223 228 struct xsk_tx_metadata_compl *compl)
+5 -3
net/core/skbuff.c
··· 81 81 #include <net/page_pool/helpers.h> 82 82 #include <net/psp/types.h> 83 83 #include <net/dropreason.h> 84 + #include <net/xdp_sock.h> 84 85 85 86 #include <linux/uaccess.h> 86 87 #include <trace/events/skb.h> ··· 1141 1140 if (skb->destructor) { 1142 1141 DEBUG_NET_WARN_ON_ONCE(in_hardirq()); 1143 1142 #ifdef CONFIG_INET 1144 - INDIRECT_CALL_3(skb->destructor, 1143 + INDIRECT_CALL_4(skb->destructor, 1145 1144 tcp_wfree, __sock_wfree, sock_wfree, 1145 + xsk_destruct_skb, 1146 1146 skb); 1147 1147 #else 1148 - INDIRECT_CALL_1(skb->destructor, 1149 - sock_wfree, 1148 + INDIRECT_CALL_2(skb->destructor, 1149 + sock_wfree, xsk_destruct_skb, 1150 1150 skb); 1151 1151 1152 1152 #endif
+2 -1
net/xdp/xsk.c
··· 602 602 return XSKCB(skb)->num_descs; 603 603 } 604 604 605 - static void xsk_destruct_skb(struct sk_buff *skb) 605 + INDIRECT_CALLABLE_SCOPE 606 + void xsk_destruct_skb(struct sk_buff *skb) 606 607 { 607 608 struct xsk_tx_metadata_compl *compl = &skb_shinfo(skb)->xsk_meta; 608 609