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.
Unified · Split
| @@ -50,6 +50,15 @@ packet's ``struct xdp_desc`` descriptor should set ``XDP_TX_METADATA`` · 49 unmodified lines | ||
| 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 | |
| @@ -83,6 +83,7 @@ struct xsk_buff_pool { · 82 unmodified lines | ||
| 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 |
| @@ -33,7 +33,13 @@ · 32 unmodified lines | ||
| 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; |
| @@ -148,6 +148,11 @@ static int xdp_umem_account_pages(struct xdp_umem *umem) · 147 unmodified lines | ||
| 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; |
| @@ -167,7 +172,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) · 13 unmodified lines | ||
| 167 | 172 | return -EINVAL; |
| 168 | 173 | } |
| 169 | 174 | |
| 170 | − if (mr->flags & ~XDP_UMEM_UNALIGNED_CHUNK_FLAG) | |
| 175 | + if (mr->flags & ~XDP_UMEM_FLAGS_VALID) | |
| 171 | 176 | return -EINVAL; |
| 172 | 177 | |
| 173 | 178 | if (!unaligned_chunks && !is_power_of_2(chunk_size)) |
| @@ -744,6 +744,12 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, · 743 unmodified lines | ||
| 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 | } |
| @@ -86,6 +86,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, · 85 unmodified lines | ||
| 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); |
| @@ -33,7 +33,13 @@ · 32 unmodified lines | ||
| 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; |