Commit 11614723 authored by Stanislav Fomichev's avatar Stanislav Fomichev Committed by Alexei Starovoitov

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: default avatarStanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20231127190319.1190813-9-sdf@google.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent ce59f968
...@@ -50,6 +50,15 @@ packet's ``struct xdp_desc`` descriptor should set ``XDP_TX_METADATA`` ...@@ -50,6 +50,15 @@ packet's ``struct xdp_desc`` descriptor should set ``XDP_TX_METADATA``
bit in the ``options`` field. Also note that in a multi-buffer packet bit in the ``options`` field. Also note that in a multi-buffer packet
only the first chunk should carry the metadata. only the first chunk should carry the metadata.
Software TX Checksum
====================
For development and testing purposes its possible to pass
``XDP_UMEM_TX_SW_CSUM`` flag to ``XDP_UMEM_REG`` UMEM registration call.
In this case, when running in ``XDK_COPY`` mode, the TX checksum
is calculated on the CPU. Do not enable this option in production because
it will negatively affect performance.
Querying Device Capabilities Querying Device Capabilities
============================ ============================
......
...@@ -83,6 +83,7 @@ struct xsk_buff_pool { ...@@ -83,6 +83,7 @@ struct xsk_buff_pool {
bool uses_need_wakeup; bool uses_need_wakeup;
bool dma_need_sync; bool dma_need_sync;
bool unaligned; bool unaligned;
bool tx_sw_csum;
void *addrs; void *addrs;
/* Mutual exclusion of the completion ring in the SKB mode. Two cases to protect: /* Mutual exclusion of the completion ring in the SKB mode. Two cases to protect:
* NAPI TX thread and sendmsg error paths in the SKB destructor callback and when * NAPI TX thread and sendmsg error paths in the SKB destructor callback and when
......
...@@ -33,7 +33,13 @@ ...@@ -33,7 +33,13 @@
#define XDP_USE_SG (1 << 4) #define XDP_USE_SG (1 << 4)
/* Flags for xsk_umem_config flags */ /* Flags for xsk_umem_config flags */
#define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0) #define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0)
/* Force checksum calculation in software. Can be used for testing or
* working around potential HW issues. This option causes performance
* degradation and only works in XDP_COPY mode.
*/
#define XDP_UMEM_TX_SW_CSUM (1 << 1)
struct sockaddr_xdp { struct sockaddr_xdp {
__u16 sxdp_family; __u16 sxdp_family;
......
...@@ -148,6 +148,11 @@ static int xdp_umem_account_pages(struct xdp_umem *umem) ...@@ -148,6 +148,11 @@ static int xdp_umem_account_pages(struct xdp_umem *umem)
return 0; return 0;
} }
#define XDP_UMEM_FLAGS_VALID ( \
XDP_UMEM_UNALIGNED_CHUNK_FLAG | \
XDP_UMEM_TX_SW_CSUM | \
0)
static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
{ {
bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG; 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) ...@@ -167,7 +172,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
return -EINVAL; return -EINVAL;
} }
if (mr->flags & ~XDP_UMEM_UNALIGNED_CHUNK_FLAG) if (mr->flags & ~XDP_UMEM_FLAGS_VALID)
return -EINVAL; return -EINVAL;
if (!unaligned_chunks && !is_power_of_2(chunk_size)) if (!unaligned_chunks && !is_power_of_2(chunk_size))
......
...@@ -744,6 +744,12 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, ...@@ -744,6 +744,12 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
skb->csum_start = hr + meta->request.csum_start; skb->csum_start = hr + meta->request.csum_start;
skb->csum_offset = meta->request.csum_offset; skb->csum_offset = meta->request.csum_offset;
skb->ip_summed = CHECKSUM_PARTIAL; skb->ip_summed = CHECKSUM_PARTIAL;
if (unlikely(xs->pool->tx_sw_csum)) {
err = skb_checksum_help(skb);
if (err)
goto free_err;
}
} }
} }
} }
......
...@@ -86,6 +86,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, ...@@ -86,6 +86,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
pool->umem = umem; pool->umem = umem;
pool->addrs = umem->addrs; pool->addrs = umem->addrs;
pool->tx_metadata_len = umem->tx_metadata_len; pool->tx_metadata_len = umem->tx_metadata_len;
pool->tx_sw_csum = umem->flags & XDP_UMEM_TX_SW_CSUM;
INIT_LIST_HEAD(&pool->free_list); INIT_LIST_HEAD(&pool->free_list);
INIT_LIST_HEAD(&pool->xskb_list); INIT_LIST_HEAD(&pool->xskb_list);
INIT_LIST_HEAD(&pool->xsk_tx_list); INIT_LIST_HEAD(&pool->xsk_tx_list);
......
...@@ -33,7 +33,13 @@ ...@@ -33,7 +33,13 @@
#define XDP_USE_SG (1 << 4) #define XDP_USE_SG (1 << 4)
/* Flags for xsk_umem_config flags */ /* Flags for xsk_umem_config flags */
#define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0) #define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0)
/* Force checksum calculation in software. Can be used for testing or
* working around potential HW issues. This option causes performance
* degradation and only works in XDP_COPY mode.
*/
#define XDP_UMEM_TX_SW_CSUM (1 << 1)
struct sockaddr_xdp { struct sockaddr_xdp {
__u16 sxdp_family; __u16 sxdp_family;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment