diff mbox series

[v12,bpf-next,06/18] net: marvell: rely on xdp_update_skb_shared_info utility routine

Message ID 4f0438cf2a94e539e56b6a291978e08fd2e9c60b.1629473233.git.lorenzo@kernel.org
State New
Headers show
Series mvneta: introduce XDP multi-buffer support | expand

Commit Message

Lorenzo Bianconi Aug. 20, 2021, 3:40 p.m. UTC
Rely on xdp_update_skb_shared_info routine in order to avoid
resetting frags array in skb_shared_info structure building
the skb in mvneta_swbm_build_skb(). Frags array is expected to
be initialized by the receiving driver building the xdp_buff
and here we just need to update memory metadata.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/marvell/mvneta.c | 35 +++++++++++++++------------
 1 file changed, 20 insertions(+), 15 deletions(-)

Comments

John Fastabend Aug. 31, 2021, 11:41 p.m. UTC | #1
Lorenzo Bianconi wrote:
> Rely on xdp_update_skb_shared_info routine in order to avoid

> resetting frags array in skb_shared_info structure building

> the skb in mvneta_swbm_build_skb(). Frags array is expected to

> be initialized by the receiving driver building the xdp_buff

> and here we just need to update memory metadata.

> 

> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

> ---


Acked-by: John Fastabend <john.fastabend@gmail.com>


>  drivers/net/ethernet/marvell/mvneta.c | 35 +++++++++++++++------------

>  1 file changed, 20 insertions(+), 15 deletions(-)

> 

> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c

> index cbf614d6b993..b996eb49d813 100644

> --- a/drivers/net/ethernet/marvell/mvneta.c

> +++ b/drivers/net/ethernet/marvell/mvneta.c

> @@ -2304,11 +2304,19 @@ mvneta_swbm_add_rx_fragment(struct mvneta_port *pp,

>  		skb_frag_size_set(frag, data_len);

>  		__skb_frag_set_page(frag, page);

>  

> -		if (!xdp_buff_is_mb(xdp))

> +		if (!xdp_buff_is_mb(xdp)) {

> +			sinfo->xdp_frags_size = *size;

>  			xdp_buff_set_mb(xdp);

> +		}

> +		if (page_is_pfmemalloc(page))

> +			xdp_buff_set_frag_pfmemalloc(xdp);

>  	} else {

>  		page_pool_put_full_page(rxq->page_pool, page, true);

>  	}

> +

> +	/* last fragment */

> +	if (len == *size)

> +		sinfo->xdp_frags_tsize = sinfo->nr_frags * PAGE_SIZE;

>  	*size -= len;

>  }

>  

> @@ -2316,13 +2324,18 @@ static struct sk_buff *

>  mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,

>  		      struct xdp_buff *xdp, u32 desc_status)

>  {

> -	struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);

> +	unsigned int size, truesize;

>  	struct sk_buff *skb;

>  	u8 num_frags;

> -	int i;

>  

> -	if (unlikely(xdp_buff_is_mb(xdp)))

> +	if (unlikely(xdp_buff_is_mb(xdp))) {


Just curious does the mvneta hardware support header split? If we
get to that point then we can drop the unlikely.

> +		struct skb_shared_info *sinfo;

> +

> +		sinfo = xdp_get_shared_info_from_buff(xdp);

> +		truesize = sinfo->xdp_frags_tsize;

> +		size = sinfo->xdp_frags_size;

>  		num_frags = sinfo->nr_frags;

> +	}

>  

>  	skb = build_skb(xdp->data_hard_start, PAGE_SIZE);

>  	if (!skb)

> @@ -2334,18 +2347,10 @@ mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,

>  	skb_put(skb, xdp->data_end - xdp->data);

>  	skb->ip_summed = mvneta_rx_csum(pp, desc_status);

>  

> -	if (likely(!xdp_buff_is_mb(xdp)))

> -		goto out;

> -

> -	for (i = 0; i < num_frags; i++) {

> -		skb_frag_t *frag = &sinfo->frags[i];

> -

> -		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,

> -				skb_frag_page(frag), skb_frag_off(frag),

> -				skb_frag_size(frag), PAGE_SIZE);

> -	}

> +	if (unlikely(xdp_buff_is_mb(xdp)))

> +		xdp_update_skb_shared_info(skb, num_frags, size, truesize,

> +					   xdp_buff_is_frag_pfmemalloc(xdp));

>  

> -out:

>  	return skb;

>  }

>  

> -- 

> 2.31.1

>
Lorenzo Bianconi Sept. 3, 2021, 5:27 p.m. UTC | #2
>

> Lorenzo Bianconi wrote:

> > Rely on xdp_update_skb_shared_info routine in order to avoid

> > resetting frags array in skb_shared_info structure building

> > the skb in mvneta_swbm_build_skb(). Frags array is expected to

> > be initialized by the receiving driver building the xdp_buff

> > and here we just need to update memory metadata.

> >

> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

> > ---

>

> Acked-by: John Fastabend <john.fastabend@gmail.com>

>

> >  drivers/net/ethernet/marvell/mvneta.c | 35 +++++++++++++++------------

> >  1 file changed, 20 insertions(+), 15 deletions(-)

> >

> > diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c

> > index cbf614d6b993..b996eb49d813 100644

> > --- a/drivers/net/ethernet/marvell/mvneta.c

> > +++ b/drivers/net/ethernet/marvell/mvneta.c

> > @@ -2304,11 +2304,19 @@ mvneta_swbm_add_rx_fragment(struct mvneta_port *pp,

> >               skb_frag_size_set(frag, data_len);

> >               __skb_frag_set_page(frag, page);

> >

> > -             if (!xdp_buff_is_mb(xdp))

> > +             if (!xdp_buff_is_mb(xdp)) {

> > +                     sinfo->xdp_frags_size = *size;

> >                       xdp_buff_set_mb(xdp);

> > +             }

> > +             if (page_is_pfmemalloc(page))

> > +                     xdp_buff_set_frag_pfmemalloc(xdp);

> >       } else {

> >               page_pool_put_full_page(rxq->page_pool, page, true);

> >       }

> > +

> > +     /* last fragment */

> > +     if (len == *size)

> > +             sinfo->xdp_frags_tsize = sinfo->nr_frags * PAGE_SIZE;

> >       *size -= len;

> >  }

> >

> > @@ -2316,13 +2324,18 @@ static struct sk_buff *

> >  mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,

> >                     struct xdp_buff *xdp, u32 desc_status)

> >  {

> > -     struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);

> > +     unsigned int size, truesize;

> >       struct sk_buff *skb;

> >       u8 num_frags;

> > -     int i;

> >

> > -     if (unlikely(xdp_buff_is_mb(xdp)))

> > +     if (unlikely(xdp_buff_is_mb(xdp))) {

>

> Just curious does the mvneta hardware support header split? If we

> get to that point then we can drop the unlikely.


nope, it does not :(

Regards,
Lorenzo

>

> > +             struct skb_shared_info *sinfo;

> > +

> > +             sinfo = xdp_get_shared_info_from_buff(xdp);

> > +             truesize = sinfo->xdp_frags_tsize;

> > +             size = sinfo->xdp_frags_size;

> >               num_frags = sinfo->nr_frags;

> > +     }

> >

> >       skb = build_skb(xdp->data_hard_start, PAGE_SIZE);

> >       if (!skb)

> > @@ -2334,18 +2347,10 @@ mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,

> >       skb_put(skb, xdp->data_end - xdp->data);

> >       skb->ip_summed = mvneta_rx_csum(pp, desc_status);

> >

> > -     if (likely(!xdp_buff_is_mb(xdp)))

> > -             goto out;

> > -

> > -     for (i = 0; i < num_frags; i++) {

> > -             skb_frag_t *frag = &sinfo->frags[i];

> > -

> > -             skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,

> > -                             skb_frag_page(frag), skb_frag_off(frag),

> > -                             skb_frag_size(frag), PAGE_SIZE);

> > -     }

> > +     if (unlikely(xdp_buff_is_mb(xdp)))

> > +             xdp_update_skb_shared_info(skb, num_frags, size, truesize,

> > +                                        xdp_buff_is_frag_pfmemalloc(xdp));

> >

> > -out:

> >       return skb;

> >  }

> >

> > --

> > 2.31.1

> >

>

>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index cbf614d6b993..b996eb49d813 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2304,11 +2304,19 @@  mvneta_swbm_add_rx_fragment(struct mvneta_port *pp,
 		skb_frag_size_set(frag, data_len);
 		__skb_frag_set_page(frag, page);
 
-		if (!xdp_buff_is_mb(xdp))
+		if (!xdp_buff_is_mb(xdp)) {
+			sinfo->xdp_frags_size = *size;
 			xdp_buff_set_mb(xdp);
+		}
+		if (page_is_pfmemalloc(page))
+			xdp_buff_set_frag_pfmemalloc(xdp);
 	} else {
 		page_pool_put_full_page(rxq->page_pool, page, true);
 	}
+
+	/* last fragment */
+	if (len == *size)
+		sinfo->xdp_frags_tsize = sinfo->nr_frags * PAGE_SIZE;
 	*size -= len;
 }
 
@@ -2316,13 +2324,18 @@  static struct sk_buff *
 mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,
 		      struct xdp_buff *xdp, u32 desc_status)
 {
-	struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
+	unsigned int size, truesize;
 	struct sk_buff *skb;
 	u8 num_frags;
-	int i;
 
-	if (unlikely(xdp_buff_is_mb(xdp)))
+	if (unlikely(xdp_buff_is_mb(xdp))) {
+		struct skb_shared_info *sinfo;
+
+		sinfo = xdp_get_shared_info_from_buff(xdp);
+		truesize = sinfo->xdp_frags_tsize;
+		size = sinfo->xdp_frags_size;
 		num_frags = sinfo->nr_frags;
+	}
 
 	skb = build_skb(xdp->data_hard_start, PAGE_SIZE);
 	if (!skb)
@@ -2334,18 +2347,10 @@  mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool,
 	skb_put(skb, xdp->data_end - xdp->data);
 	skb->ip_summed = mvneta_rx_csum(pp, desc_status);
 
-	if (likely(!xdp_buff_is_mb(xdp)))
-		goto out;
-
-	for (i = 0; i < num_frags; i++) {
-		skb_frag_t *frag = &sinfo->frags[i];
-
-		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
-				skb_frag_page(frag), skb_frag_off(frag),
-				skb_frag_size(frag), PAGE_SIZE);
-	}
+	if (unlikely(xdp_buff_is_mb(xdp)))
+		xdp_update_skb_shared_info(skb, num_frags, size, truesize,
+					   xdp_buff_is_frag_pfmemalloc(xdp));
 
-out:
 	return skb;
 }