mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-19 14:47:06 -05:00
Merge branch 'xsk-refactors-around-generic-xmit-side'
Maciej Fijalkowski says: ==================== xsk: refactors around generic xmit side this small patchset is about refactoring code around xsk_build_skb() as it became pretty heavy. Generic xmit is a bit hard to follow so here are three clean ups to start with making this code more friendly. v1: https://lore.kernel.org/20250922152600.2455136-1-maciej.fijalkowski@intel.com ==================== Link: https://patch.msgid.link/20250925160009.2474816-1-maciej.fijalkowski@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
113
net/xdp/xsk.c
113
net/xdp/xsk.c
@@ -618,11 +618,16 @@ static void xsk_destruct_skb(struct sk_buff *skb)
|
||||
sock_wfree(skb);
|
||||
}
|
||||
|
||||
static void xsk_set_destructor_arg(struct sk_buff *skb, u64 addr)
|
||||
static void xsk_skb_init_misc(struct sk_buff *skb, struct xdp_sock *xs,
|
||||
u64 addr)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(struct xsk_addr_head) > sizeof(skb->cb));
|
||||
INIT_LIST_HEAD(&XSKCB(skb)->addrs_list);
|
||||
skb->dev = xs->dev;
|
||||
skb->priority = READ_ONCE(xs->sk.sk_priority);
|
||||
skb->mark = READ_ONCE(xs->sk.sk_mark);
|
||||
XSKCB(skb)->num_descs = 0;
|
||||
skb->destructor = xsk_destruct_skb;
|
||||
skb_shinfo(skb)->destructor_arg = (void *)(uintptr_t)addr;
|
||||
}
|
||||
|
||||
@@ -652,6 +657,45 @@ static void xsk_drop_skb(struct sk_buff *skb)
|
||||
xsk_consume_skb(skb);
|
||||
}
|
||||
|
||||
static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,
|
||||
struct xdp_desc *desc, struct xsk_buff_pool *pool,
|
||||
u32 hr)
|
||||
{
|
||||
struct xsk_tx_metadata *meta = NULL;
|
||||
|
||||
if (unlikely(pool->tx_metadata_len == 0))
|
||||
return -EINVAL;
|
||||
|
||||
meta = buffer - pool->tx_metadata_len;
|
||||
if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
|
||||
return -EINVAL;
|
||||
|
||||
if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) {
|
||||
if (unlikely(meta->request.csum_start +
|
||||
meta->request.csum_offset +
|
||||
sizeof(__sum16) > desc->len))
|
||||
return -EINVAL;
|
||||
|
||||
skb->csum_start = hr + meta->request.csum_start;
|
||||
skb->csum_offset = meta->request.csum_offset;
|
||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||
|
||||
if (unlikely(pool->tx_sw_csum)) {
|
||||
int err;
|
||||
|
||||
err = skb_checksum_help(skb);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
|
||||
skb->skb_mstamp_ns = meta->request.launch_time;
|
||||
xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
|
||||
struct xdp_desc *desc)
|
||||
{
|
||||
@@ -664,6 +708,9 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
|
||||
int err, i;
|
||||
u64 addr;
|
||||
|
||||
addr = desc->addr;
|
||||
buffer = xsk_buff_raw_get_data(pool, addr);
|
||||
|
||||
if (!skb) {
|
||||
hr = max(NET_SKB_PAD, L1_CACHE_ALIGN(xs->dev->needed_headroom));
|
||||
|
||||
@@ -673,7 +720,12 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
|
||||
|
||||
skb_reserve(skb, hr);
|
||||
|
||||
xsk_set_destructor_arg(skb, desc->addr);
|
||||
xsk_skb_init_misc(skb, xs, desc->addr);
|
||||
if (desc->options & XDP_TX_METADATA) {
|
||||
err = xsk_skb_metadata(skb, buffer, desc, pool, hr);
|
||||
if (unlikely(err))
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
} else {
|
||||
xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache, GFP_KERNEL);
|
||||
if (!xsk_addr)
|
||||
@@ -687,11 +739,9 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
|
||||
list_add_tail(&xsk_addr->addr_node, &XSKCB(skb)->addrs_list);
|
||||
}
|
||||
|
||||
addr = desc->addr;
|
||||
len = desc->len;
|
||||
ts = pool->unaligned ? len : pool->chunk_size;
|
||||
|
||||
buffer = xsk_buff_raw_get_data(pool, addr);
|
||||
offset = offset_in_page(buffer);
|
||||
addr = buffer - pool->addrs;
|
||||
|
||||
@@ -722,16 +772,15 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
|
||||
static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
|
||||
struct xdp_desc *desc)
|
||||
{
|
||||
struct xsk_tx_metadata *meta = NULL;
|
||||
struct net_device *dev = xs->dev;
|
||||
struct sk_buff *skb = xs->skb;
|
||||
bool first_frag = false;
|
||||
int err;
|
||||
|
||||
if (dev->priv_flags & IFF_TX_SKB_NO_LINEAR) {
|
||||
skb = xsk_build_skb_zerocopy(xs, desc);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
skb = NULL;
|
||||
goto free_err;
|
||||
}
|
||||
} else {
|
||||
@@ -742,8 +791,6 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
|
||||
len = desc->len;
|
||||
|
||||
if (!skb) {
|
||||
first_frag = true;
|
||||
|
||||
hr = max(NET_SKB_PAD, L1_CACHE_ALIGN(dev->needed_headroom));
|
||||
tr = dev->needed_tailroom;
|
||||
skb = sock_alloc_send_skb(&xs->sk, hr + len + tr, 1, &err);
|
||||
@@ -757,7 +804,13 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
|
||||
if (unlikely(err))
|
||||
goto free_err;
|
||||
|
||||
xsk_set_destructor_arg(skb, desc->addr);
|
||||
xsk_skb_init_misc(skb, xs, desc->addr);
|
||||
if (desc->options & XDP_TX_METADATA) {
|
||||
err = xsk_skb_metadata(skb, buffer, desc,
|
||||
xs->pool, hr);
|
||||
if (unlikely(err))
|
||||
goto free_err;
|
||||
}
|
||||
} else {
|
||||
int nr_frags = skb_shinfo(skb)->nr_frags;
|
||||
struct xsk_addr_node *xsk_addr;
|
||||
@@ -792,54 +845,14 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
|
||||
xsk_addr->addr = desc->addr;
|
||||
list_add_tail(&xsk_addr->addr_node, &XSKCB(skb)->addrs_list);
|
||||
}
|
||||
|
||||
if (first_frag && desc->options & XDP_TX_METADATA) {
|
||||
if (unlikely(xs->pool->tx_metadata_len == 0)) {
|
||||
err = -EINVAL;
|
||||
goto free_err;
|
||||
}
|
||||
|
||||
meta = buffer - xs->pool->tx_metadata_len;
|
||||
if (unlikely(!xsk_buff_valid_tx_metadata(meta))) {
|
||||
err = -EINVAL;
|
||||
goto free_err;
|
||||
}
|
||||
|
||||
if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) {
|
||||
if (unlikely(meta->request.csum_start +
|
||||
meta->request.csum_offset +
|
||||
sizeof(__sum16) > len)) {
|
||||
err = -EINVAL;
|
||||
goto free_err;
|
||||
}
|
||||
|
||||
skb->csum_start = hr + meta->request.csum_start;
|
||||
skb->csum_offset = meta->request.csum_offset;
|
||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||
|
||||
if (unlikely(xs->pool->tx_sw_csum)) {
|
||||
err = skb_checksum_help(skb);
|
||||
if (err)
|
||||
goto free_err;
|
||||
}
|
||||
}
|
||||
|
||||
if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
|
||||
skb->skb_mstamp_ns = meta->request.launch_time;
|
||||
}
|
||||
}
|
||||
|
||||
skb->dev = dev;
|
||||
skb->priority = READ_ONCE(xs->sk.sk_priority);
|
||||
skb->mark = READ_ONCE(xs->sk.sk_mark);
|
||||
skb->destructor = xsk_destruct_skb;
|
||||
xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
|
||||
xsk_inc_num_desc(skb);
|
||||
|
||||
return skb;
|
||||
|
||||
free_err:
|
||||
if (first_frag && skb)
|
||||
if (skb && !skb_shinfo(skb)->nr_frags)
|
||||
kfree_skb(skb);
|
||||
|
||||
if (err == -EOVERFLOW) {
|
||||
|
||||
Reference in New Issue
Block a user