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 | bit in the ``options`` field. Also note that in a multi-buffer packet | 50 | bit in the ``options`` field. Also note that in a multi-buffer packet |
| 51 | only the first chunk should carry the metadata. | 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 | Querying Device Capabilities | 62 | Querying Device Capabilities |
| 54 | ============================ | 63 | ============================ |
| 55 | 64 | ||
| @@ -83,6 +83,7 @@ struct xsk_buff_pool { · 82 unmodified lines | |||
| 83 | bool uses_need_wakeup; | 83 | bool uses_need_wakeup; |
| 84 | bool dma_need_sync; | 84 | bool dma_need_sync; |
| 85 | bool unaligned; | 85 | bool unaligned; |
| 86 | bool tx_sw_csum; | ||
| 86 | void *addrs; | 87 | void *addrs; |
| 87 | /* Mutual exclusion of the completion ring in the SKB mode. Two cases to protect: | 88 | /* Mutual exclusion of the completion ring in the SKB mode. Two cases to protect: |
| 88 | * NAPI TX thread and sendmsg error paths in the SKB destructor callback and when | 89 | * NAPI TX thread and sendmsg error paths in the SKB destructor callback and when |
| @@ -33,7 +33,13 @@ · 32 unmodified lines | |||
| 33 | #define XDP_USE_SG (1 << 4) | 33 | #define XDP_USE_SG (1 << 4) |
| 34 | 34 | ||
| 35 | /* Flags for xsk_umem_config flags */ | 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 | struct sockaddr_xdp { | 44 | struct sockaddr_xdp { |
| 39 | __u16 sxdp_family; | 45 | __u16 sxdp_family; |
| @@ -148,6 +148,11 @@ static int xdp_umem_account_pages(struct xdp_umem *umem) · 147 unmodified lines | |||
| 148 | return 0; | 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 | static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) | 156 | static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) |
| 152 | { | 157 | { |
| 153 | bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG; | 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 | return -EINVAL; | 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 | return -EINVAL; | 176 | return -EINVAL; |
| 172 | 177 | ||
| 173 | if (!unaligned_chunks && !is_power_of_2(chunk_size)) | 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 | skb->csum_start = hr + meta->request.csum_start; | 744 | skb->csum_start = hr + meta->request.csum_start; |
| 745 | skb->csum_offset = meta->request.csum_offset; | 745 | skb->csum_offset = meta->request.csum_offset; |
| 746 | skb->ip_summed = CHECKSUM_PARTIAL; | 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 | pool->umem = umem; | 86 | pool->umem = umem; |
| 87 | pool->addrs = umem->addrs; | 87 | pool->addrs = umem->addrs; |
| 88 | pool->tx_metadata_len = umem->tx_metadata_len; | 88 | pool->tx_metadata_len = umem->tx_metadata_len; |
| 89 | pool->tx_sw_csum = umem->flags & XDP_UMEM_TX_SW_CSUM; | ||
| 89 | INIT_LIST_HEAD(&pool->free_list); | 90 | INIT_LIST_HEAD(&pool->free_list); |
| 90 | INIT_LIST_HEAD(&pool->xskb_list); | 91 | INIT_LIST_HEAD(&pool->xskb_list); |
| 91 | INIT_LIST_HEAD(&pool->xsk_tx_list); | 92 | INIT_LIST_HEAD(&pool->xsk_tx_list); |
| @@ -33,7 +33,13 @@ · 32 unmodified lines | |||
| 33 | #define XDP_USE_SG (1 << 4) | 33 | #define XDP_USE_SG (1 << 4) |
| 34 | 34 | ||
| 35 | /* Flags for xsk_umem_config flags */ | 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 | struct sockaddr_xdp { | 44 | struct sockaddr_xdp { |
| 39 | __u16 sxdp_family; | 45 | __u16 sxdp_family; |