Skip to content

Commit 26523ad

Browse files
mfijalkoKernel Patches Daemon
authored andcommitted
xsk: wrap generic metadata handling onto separate function
xsk_build_skb() has gone wild with its size and one of the things we can do about it is to pull out a branch that takes care of metadata handling and make it a separate function. While at it, let us add metadata SW support for devices supporting IFF_TX_SKB_NO_LINEAR flag, that happen to have separate logic for building skb in xsk's generic xmit path. Acked-by: Stanislav Fomichev <[email protected]> Reviewed-by: Jason Xing <[email protected]> Signed-off-by: Maciej Fijalkowski <[email protected]>
1 parent 4cce954 commit 26523ad

File tree

1 file changed

+53
-39
lines changed

1 file changed

+53
-39
lines changed

net/xdp/xsk.c

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,45 @@ static void xsk_drop_skb(struct sk_buff *skb)
657657
xsk_consume_skb(skb);
658658
}
659659

660+
static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,
661+
struct xdp_desc *desc, struct xsk_buff_pool *pool,
662+
u32 hr)
663+
{
664+
struct xsk_tx_metadata *meta = NULL;
665+
666+
if (unlikely(pool->tx_metadata_len == 0))
667+
return -EINVAL;
668+
669+
meta = buffer - pool->tx_metadata_len;
670+
if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
671+
return -EINVAL;
672+
673+
if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) {
674+
if (unlikely(meta->request.csum_start +
675+
meta->request.csum_offset +
676+
sizeof(__sum16) > desc->len))
677+
return -EINVAL;
678+
679+
skb->csum_start = hr + meta->request.csum_start;
680+
skb->csum_offset = meta->request.csum_offset;
681+
skb->ip_summed = CHECKSUM_PARTIAL;
682+
683+
if (unlikely(pool->tx_sw_csum)) {
684+
int err;
685+
686+
err = skb_checksum_help(skb);
687+
if (err)
688+
return err;
689+
}
690+
}
691+
692+
if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
693+
skb->skb_mstamp_ns = meta->request.launch_time;
694+
xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
695+
696+
return 0;
697+
}
698+
660699
static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
661700
struct xdp_desc *desc)
662701
{
@@ -669,6 +708,9 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
669708
int err, i;
670709
u64 addr;
671710

711+
addr = desc->addr;
712+
buffer = xsk_buff_raw_get_data(pool, addr);
713+
672714
if (!skb) {
673715
hr = max(NET_SKB_PAD, L1_CACHE_ALIGN(xs->dev->needed_headroom));
674716

@@ -679,6 +721,11 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
679721
skb_reserve(skb, hr);
680722

681723
xsk_skb_init_misc(skb, xs, desc->addr);
724+
if (desc->options & XDP_TX_METADATA) {
725+
err = xsk_skb_metadata(skb, buffer, desc, pool, hr);
726+
if (unlikely(err))
727+
return ERR_PTR(err);
728+
}
682729
} else {
683730
xsk_addr = kmem_cache_zalloc(xsk_tx_generic_cache, GFP_KERNEL);
684731
if (!xsk_addr)
@@ -692,11 +739,9 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
692739
list_add_tail(&xsk_addr->addr_node, &XSKCB(skb)->addrs_list);
693740
}
694741

695-
addr = desc->addr;
696742
len = desc->len;
697743
ts = pool->unaligned ? len : pool->chunk_size;
698744

699-
buffer = xsk_buff_raw_get_data(pool, addr);
700745
offset = offset_in_page(buffer);
701746
addr = buffer - pool->addrs;
702747

@@ -727,7 +772,6 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
727772
static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
728773
struct xdp_desc *desc)
729774
{
730-
struct xsk_tx_metadata *meta = NULL;
731775
struct net_device *dev = xs->dev;
732776
struct sk_buff *skb = xs->skb;
733777
int err;
@@ -761,6 +805,12 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
761805
goto free_err;
762806

763807
xsk_skb_init_misc(skb, xs, desc->addr);
808+
if (desc->options & XDP_TX_METADATA) {
809+
err = xsk_skb_metadata(skb, buffer, desc,
810+
xs->pool, hr);
811+
if (unlikely(err))
812+
goto free_err;
813+
}
764814
} else {
765815
int nr_frags = skb_shinfo(skb)->nr_frags;
766816
struct xsk_addr_node *xsk_addr;
@@ -795,42 +845,6 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
795845
xsk_addr->addr = desc->addr;
796846
list_add_tail(&xsk_addr->addr_node, &XSKCB(skb)->addrs_list);
797847
}
798-
799-
if (!skb_shinfo(skb)->nr_frags && desc->options & XDP_TX_METADATA) {
800-
if (unlikely(xs->pool->tx_metadata_len == 0)) {
801-
err = -EINVAL;
802-
goto free_err;
803-
}
804-
805-
meta = buffer - xs->pool->tx_metadata_len;
806-
if (unlikely(!xsk_buff_valid_tx_metadata(meta))) {
807-
err = -EINVAL;
808-
goto free_err;
809-
}
810-
811-
if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) {
812-
if (unlikely(meta->request.csum_start +
813-
meta->request.csum_offset +
814-
sizeof(__sum16) > len)) {
815-
err = -EINVAL;
816-
goto free_err;
817-
}
818-
819-
skb->csum_start = hr + meta->request.csum_start;
820-
skb->csum_offset = meta->request.csum_offset;
821-
skb->ip_summed = CHECKSUM_PARTIAL;
822-
823-
if (unlikely(xs->pool->tx_sw_csum)) {
824-
err = skb_checksum_help(skb);
825-
if (err)
826-
goto free_err;
827-
}
828-
}
829-
830-
if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
831-
skb->skb_mstamp_ns = meta->request.launch_time;
832-
xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);
833-
}
834848
}
835849

836850
xsk_inc_num_desc(skb);

0 commit comments

Comments
 (0)