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

xsk: Add option to calculate TX checksum in SW

For XDP_COPY mode, add a UMEM option XDP_UMEM_TX_SW_CSUM
to call skb_checksum_help in transmit path. Might be useful
to debugging issues with real hardware. I also use this mode
in the selftests.

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20231127190319.1190813-9-sdf@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Stanislav Fomichev and committed by
Alexei Starovoitov
11614723 ce59f968

+37 -3
+9
Documentation/networking/xsk-tx-metadata.rst
··· 50 50 bit in the ``options`` field. Also note that in a multi-buffer packet 51 51 only the first chunk should carry the metadata. 52 52 53 + Software TX Checksum 54 + ==================== 55 + 56 + For development and testing purposes its possible to pass 57 + ``XDP_UMEM_TX_SW_CSUM`` flag to ``XDP_UMEM_REG`` UMEM registration call. 58 + In this case, when running in ``XDK_COPY`` mode, the TX checksum 59 + is calculated on the CPU. Do not enable this option in production because 60 + it will negatively affect performance. 61 + 53 62 Querying Device Capabilities 54 63 ============================ 55 64
+1
include/net/xsk_buff_pool.h
··· 83 83 bool uses_need_wakeup; 84 84 bool dma_need_sync; 85 85 bool unaligned; 86 + bool tx_sw_csum; 86 87 void *addrs; 87 88 /* Mutual exclusion of the completion ring in the SKB mode. Two cases to protect: 88 89 * NAPI TX thread and sendmsg error paths in the SKB destructor callback and when
+7 -1
include/uapi/linux/if_xdp.h
··· 33 33 #define XDP_USE_SG (1 << 4) 34 34 35 35 /* Flags for xsk_umem_config flags */ 36 - #define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0) 36 + #define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0) 37 + 38 + /* Force checksum calculation in software. Can be used for testing or 39 + * working around potential HW issues. This option causes performance 40 + * degradation and only works in XDP_COPY mode. 41 + */ 42 + #define XDP_UMEM_TX_SW_CSUM (1 << 1) 37 43 38 44 struct sockaddr_xdp { 39 45 __u16 sxdp_family;
+6 -1
net/xdp/xdp_umem.c
··· 148 148 return 0; 149 149 } 150 150 151 + #define XDP_UMEM_FLAGS_VALID ( \ 152 + XDP_UMEM_UNALIGNED_CHUNK_FLAG | \ 153 + XDP_UMEM_TX_SW_CSUM | \ 154 + 0) 155 + 151 156 static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) 152 157 { 153 158 bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG; ··· 172 167 return -EINVAL; 173 168 } 174 169 175 - if (mr->flags & ~XDP_UMEM_UNALIGNED_CHUNK_FLAG) 170 + if (mr->flags & ~XDP_UMEM_FLAGS_VALID) 176 171 return -EINVAL; 177 172 178 173 if (!unaligned_chunks && !is_power_of_2(chunk_size))
+6
net/xdp/xsk.c
··· 744 744 skb->csum_start = hr + meta->request.csum_start; 745 745 skb->csum_offset = meta->request.csum_offset; 746 746 skb->ip_summed = CHECKSUM_PARTIAL; 747 + 748 + if (unlikely(xs->pool->tx_sw_csum)) { 749 + err = skb_checksum_help(skb); 750 + if (err) 751 + goto free_err; 752 + } 747 753 } 748 754 } 749 755 }
+1
net/xdp/xsk_buff_pool.c
··· 86 86 pool->umem = umem; 87 87 pool->addrs = umem->addrs; 88 88 pool->tx_metadata_len = umem->tx_metadata_len; 89 + pool->tx_sw_csum = umem->flags & XDP_UMEM_TX_SW_CSUM; 89 90 INIT_LIST_HEAD(&pool->free_list); 90 91 INIT_LIST_HEAD(&pool->xskb_list); 91 92 INIT_LIST_HEAD(&pool->xsk_tx_list);
+7 -1
tools/include/uapi/linux/if_xdp.h
··· 33 33 #define XDP_USE_SG (1 << 4) 34 34 35 35 /* Flags for xsk_umem_config flags */ 36 - #define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0) 36 + #define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0) 37 + 38 + /* Force checksum calculation in software. Can be used for testing or 39 + * working around potential HW issues. This option causes performance 40 + * degradation and only works in XDP_COPY mode. 41 + */ 42 + #define XDP_UMEM_TX_SW_CSUM (1 << 1) 37 43 38 44 struct sockaddr_xdp { 39 45 __u16 sxdp_family;