diff mbox series

[net-next] net: lan966x: Don't use xdp_frame when action is XDP_TX

Message ID 20230420121152.2737625-1-horatiu.vultur@microchip.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [net-next] net: lan966x: Don't use xdp_frame when action is XDP_TX | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/cc_maintainers warning 1 maintainers not CCed: ast@kernel.org
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 130 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Horatiu Vultur April 20, 2023, 12:11 p.m. UTC
When the action of an xdp program was XDP_TX, lan966x was creating
a xdp_frame and use this one to send the frame back. But it is also
possible to send back the frame without needing a xdp_frame, because
it possible to send it back using the page.
And then once the frame is transmitted is possible to use directly
page_pool_recycle_direct as lan966x is using page pools.
This would save some CPU usage on this path.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 .../ethernet/microchip/lan966x/lan966x_fdma.c | 35 +++++++++++--------
 .../ethernet/microchip/lan966x/lan966x_main.h |  2 ++
 .../ethernet/microchip/lan966x/lan966x_xdp.c  | 11 +++---
 3 files changed, 27 insertions(+), 21 deletions(-)

Comments

Alexander Lobakin April 20, 2023, 2:49 p.m. UTC | #1
From: Horatiu Vultur <horatiu.vultur@microchip.com>
Date: Thu, 20 Apr 2023 14:11:52 +0200

> When the action of an xdp program was XDP_TX, lan966x was creating
> a xdp_frame and use this one to send the frame back. But it is also
> possible to send back the frame without needing a xdp_frame, because
> it possible to send it back using the page.
> And then once the frame is transmitted is possible to use directly
> page_pool_recycle_direct as lan966x is using page pools.
> This would save some CPU usage on this path.
> 
> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>

[...]

> @@ -702,6 +704,7 @@ static void lan966x_fdma_tx_start(struct lan966x_tx *tx, int next_to_use)
>  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>  			   struct xdp_frame *xdpf,
>  			   struct page *page,
> +			   u32 len,
>  			   bool dma_map)

I think you can cut the number of arguments by almost a half:

int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
			   void *ptr, u32 len)
{
	if (len) {
		/* XDP_TX, ptr is page */
		page = ptr;

		dma_sync_here(page, len);
	} else {
		/* XDP_REDIR, ptr is xdp_frame */
		xdpf = ptr;

		dma_map_here(xdpf->data, xdpf->len);
	}

@page and @xdpf are mutually exclusive. When @xdpf is non-null, @len is
excessive (xdpf->len is here), so you can use @len as logical
`len * !dma_map`, i.e. zero for REDIR and the actual frame length for TX.

I generally enjoy seeing how you constantly improve stuff in your driver :)

>  {
>  	struct lan966x *lan966x = port->lan966x;
> @@ -722,6 +725,15 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>  		goto out;
>  	}
[...]

Thanks,
Olek
Fijalkowski, Maciej April 20, 2023, 8:52 p.m. UTC | #2
On Thu, Apr 20, 2023 at 02:11:52PM +0200, Horatiu Vultur wrote:

'net: ' in patch subject is excessive to me

> When the action of an xdp program was XDP_TX, lan966x was creating
> a xdp_frame and use this one to send the frame back. But it is also
> possible to send back the frame without needing a xdp_frame, because
> it possible to send it back using the page.

s/it/it is

> And then once the frame is transmitted is possible to use directly
> page_pool_recycle_direct as lan966x is using page pools.
> This would save some CPU usage on this path.

i remember this optimization gave me noticeable perf improvement, would
you mind sharing it in % on your side?

> 
> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> ---
>  .../ethernet/microchip/lan966x/lan966x_fdma.c | 35 +++++++++++--------
>  .../ethernet/microchip/lan966x/lan966x_main.h |  2 ++
>  .../ethernet/microchip/lan966x/lan966x_xdp.c  | 11 +++---
>  3 files changed, 27 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
> index 2ed76bb61a731..7947259e67e4e 100644
> --- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
> +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
> @@ -390,6 +390,7 @@ static void lan966x_fdma_stop_netdev(struct lan966x *lan966x)
>  static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
>  {
>  	struct lan966x_tx *tx = &lan966x->tx;
> +	struct lan966x_rx *rx = &lan966x->rx;
>  	struct lan966x_tx_dcb_buf *dcb_buf;
>  	struct xdp_frame_bulk bq;
>  	struct lan966x_db *db;
> @@ -432,7 +433,8 @@ static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
>  			if (dcb_buf->xdp_ndo)
>  				xdp_return_frame_bulk(dcb_buf->data.xdpf, &bq);
>  			else
> -				xdp_return_frame_rx_napi(dcb_buf->data.xdpf);
> +				page_pool_recycle_direct(rx->page_pool,
> +							 dcb_buf->data.page);
>  		}
>  
>  		clear = true;
> @@ -702,6 +704,7 @@ static void lan966x_fdma_tx_start(struct lan966x_tx *tx, int next_to_use)
>  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>  			   struct xdp_frame *xdpf,
>  			   struct page *page,
> +			   u32 len,

agreed with Olek regarding arguments reduction here

>  			   bool dma_map)
>  {
>  	struct lan966x *lan966x = port->lan966x;
> @@ -722,6 +725,15 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>  		goto out;
>  	}
>  
> +	/* Fill up the buffer */
> +	next_dcb_buf = &tx->dcbs_buf[next_to_use];
> +	next_dcb_buf->use_skb = false;
> +	next_dcb_buf->xdp_ndo = dma_map;

a bit misleading that xdp_ndo is a bool :P

> +	next_dcb_buf->len = len + IFH_LEN_BYTES;
> +	next_dcb_buf->used = true;
> +	next_dcb_buf->ptp = false;
> +	next_dcb_buf->dev = port->dev;
> +
>  	/* Generate new IFH */
>  	if (dma_map) {
>  		if (xdpf->headroom < IFH_LEN_BYTES) {
> @@ -736,16 +748,18 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>  
>  		dma_addr = dma_map_single(lan966x->dev,
>  					  xdpf->data - IFH_LEN_BYTES,
> -					  xdpf->len + IFH_LEN_BYTES,
> +					  len + IFH_LEN_BYTES,
>  					  DMA_TO_DEVICE);
>  		if (dma_mapping_error(lan966x->dev, dma_addr)) {
>  			ret = NETDEV_TX_OK;
>  			goto out;
>  		}
>  
> +		next_dcb_buf->data.xdpf = xdpf;
> +
>  		/* Setup next dcb */
>  		lan966x_fdma_tx_setup_dcb(tx, next_to_use,
> -					  xdpf->len + IFH_LEN_BYTES,
> +					  len + IFH_LEN_BYTES,
>  					  dma_addr);
>  	} else {
>  		ifh = page_address(page) + XDP_PACKET_HEADROOM;
> @@ -756,25 +770,18 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>  		dma_addr = page_pool_get_dma_addr(page);
>  		dma_sync_single_for_device(lan966x->dev,
>  					   dma_addr + XDP_PACKET_HEADROOM,
> -					   xdpf->len + IFH_LEN_BYTES,
> +					   len + IFH_LEN_BYTES,
>  					   DMA_TO_DEVICE);
>  
> +		next_dcb_buf->data.page = page;
> +
>  		/* Setup next dcb */
>  		lan966x_fdma_tx_setup_dcb(tx, next_to_use,
> -					  xdpf->len + IFH_LEN_BYTES,
> +					  len + IFH_LEN_BYTES,
>  					  dma_addr + XDP_PACKET_HEADROOM);
>  	}
>  
> -	/* Fill up the buffer */
> -	next_dcb_buf = &tx->dcbs_buf[next_to_use];
> -	next_dcb_buf->use_skb = false;
> -	next_dcb_buf->data.xdpf = xdpf;
> -	next_dcb_buf->xdp_ndo = dma_map;
> -	next_dcb_buf->len = xdpf->len + IFH_LEN_BYTES;
>  	next_dcb_buf->dma_addr = dma_addr;
> -	next_dcb_buf->used = true;
> -	next_dcb_buf->ptp = false;
> -	next_dcb_buf->dev = port->dev;
>  
>  	/* Start the transmission */
>  	lan966x_fdma_tx_start(tx, next_to_use);
> diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
> index 851afb0166b19..59da35a2c93d4 100644
> --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
> +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
> @@ -243,6 +243,7 @@ struct lan966x_tx_dcb_buf {
>  	union {
>  		struct sk_buff *skb;
>  		struct xdp_frame *xdpf;
> +		struct page *page;
>  	} data;
>  	u32 len;
>  	u32 used : 1;
> @@ -544,6 +545,7 @@ int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device *dev);
>  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>  			   struct xdp_frame *frame,
>  			   struct page *page,
> +			   u32 len,
>  			   bool dma_map);
>  int lan966x_fdma_change_mtu(struct lan966x *lan966x);
>  void lan966x_fdma_netdev_init(struct lan966x *lan966x, struct net_device *dev);
> diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
> index 2e6f486ec67d7..a8ad1f4e431cb 100644
> --- a/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
> +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
> @@ -62,7 +62,7 @@ int lan966x_xdp_xmit(struct net_device *dev,
>  		struct xdp_frame *xdpf = frames[i];
>  		int err;
>  
> -		err = lan966x_fdma_xmit_xdpf(port, xdpf, NULL, true);
> +		err = lan966x_fdma_xmit_xdpf(port, xdpf, NULL, xdpf->len, true);
>  		if (err)
>  			break;
>  
> @@ -76,7 +76,6 @@ int lan966x_xdp_run(struct lan966x_port *port, struct page *page, u32 data_len)
>  {
>  	struct bpf_prog *xdp_prog = port->xdp_prog;
>  	struct lan966x *lan966x = port->lan966x;
> -	struct xdp_frame *xdpf;
>  	struct xdp_buff xdp;
>  	u32 act;
>  
> @@ -90,11 +89,9 @@ int lan966x_xdp_run(struct lan966x_port *port, struct page *page, u32 data_len)
>  	case XDP_PASS:
>  		return FDMA_PASS;
>  	case XDP_TX:
> -		xdpf = xdp_convert_buff_to_frame(&xdp);
> -		if (!xdpf)
> -			return FDMA_DROP;
> -
> -		return lan966x_fdma_xmit_xdpf(port, xdpf, page, false) ?
> +		return lan966x_fdma_xmit_xdpf(port, NULL, page,
> +					      data_len - IFH_LEN_BYTES,
> +					      false) ?
>  		       FDMA_DROP : FDMA_TX;
>  	case XDP_REDIRECT:
>  		if (xdp_do_redirect(port->dev, &xdp, xdp_prog))
> -- 
> 2.38.0
>
Horatiu Vultur April 21, 2023, 7:49 a.m. UTC | #3
The 04/20/2023 16:49, Alexander Lobakin wrote:
> 
> From: Horatiu Vultur <horatiu.vultur@microchip.com>
> Date: Thu, 20 Apr 2023 14:11:52 +0200

Hi Olek,

> 
> > When the action of an xdp program was XDP_TX, lan966x was creating
> > a xdp_frame and use this one to send the frame back. But it is also
> > possible to send back the frame without needing a xdp_frame, because
> > it possible to send it back using the page.
> > And then once the frame is transmitted is possible to use directly
> > page_pool_recycle_direct as lan966x is using page pools.
> > This would save some CPU usage on this path.
> >
> > Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> 
> [...]
> 
> > @@ -702,6 +704,7 @@ static void lan966x_fdma_tx_start(struct lan966x_tx *tx, int next_to_use)
> >  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
> >                          struct xdp_frame *xdpf,
> >                          struct page *page,
> > +                        u32 len,
> >                          bool dma_map)
> 
> I think you can cut the number of arguments by almost a half:
> 
> int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
>                            void *ptr, u32 len)
> {
>         if (len) {
>                 /* XDP_TX, ptr is page */
>                 page = ptr;
> 
>                 dma_sync_here(page, len);
>         } else {
>                 /* XDP_REDIR, ptr is xdp_frame */
>                 xdpf = ptr;
> 
>                 dma_map_here(xdpf->data, xdpf->len);
>         }
> 
> @page and @xdpf are mutually exclusive. When @xdpf is non-null, @len is
> excessive (xdpf->len is here), so you can use @len as logical
> `len * !dma_map`, i.e. zero for REDIR and the actual frame length for TX.

Thanks for the review. You are right, I can reduce number of arguments,
the reason why I have done it like this, I thought it is a little bit more
clear this way. But I will update as you propose in the next version

> 
> I generally enjoy seeing how you constantly improve stuff in your driver :)
> 
> >  {
> >       struct lan966x *lan966x = port->lan966x;
> > @@ -722,6 +725,15 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
> >               goto out;
> >       }
> [...]
> 
> Thanks,
> Olek
Horatiu Vultur April 21, 2023, 8:03 a.m. UTC | #4
The 04/20/2023 22:52, Maciej Fijalkowski wrote:
> [Some people who received this message don't often get email from maciej.fijalkowski@intel.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 

Hi Maciej,

> 
> On Thu, Apr 20, 2023 at 02:11:52PM +0200, Horatiu Vultur wrote:
> 
> 'net: ' in patch subject is excessive to me

I usually have set this in the subject. I can remove this in the next
version and I will try to keep in mind for other patches for lan966x.

> 
> > When the action of an xdp program was XDP_TX, lan966x was creating
> > a xdp_frame and use this one to send the frame back. But it is also
> > possible to send back the frame without needing a xdp_frame, because
> > it possible to send it back using the page.
> 
> s/it/it is
> 
> > And then once the frame is transmitted is possible to use directly
> > page_pool_recycle_direct as lan966x is using page pools.
> > This would save some CPU usage on this path.
> 
> i remember this optimization gave me noticeable perf improvement, would
> you mind sharing it in % on your side?

The way I have done the measurements, is to measure actually how much
more traffic can be send back. I tried with different frame sizes,
frame size     improvement
64                ~8%
256              ~11%
512               ~8%
1000              ~0%
1500              ~0%

I will make sure do add this to the comments in the next version.

> 
> >
> > Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> > ---
> >  .../ethernet/microchip/lan966x/lan966x_fdma.c | 35 +++++++++++--------
> >  .../ethernet/microchip/lan966x/lan966x_main.h |  2 ++
> >  .../ethernet/microchip/lan966x/lan966x_xdp.c  | 11 +++---
> >  3 files changed, 27 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
> > index 2ed76bb61a731..7947259e67e4e 100644
> > --- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
> > +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
> > @@ -390,6 +390,7 @@ static void lan966x_fdma_stop_netdev(struct lan966x *lan966x)
> >  static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
> >  {
> >       struct lan966x_tx *tx = &lan966x->tx;
> > +     struct lan966x_rx *rx = &lan966x->rx;
> >       struct lan966x_tx_dcb_buf *dcb_buf;
> >       struct xdp_frame_bulk bq;
> >       struct lan966x_db *db;
> > @@ -432,7 +433,8 @@ static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
> >                       if (dcb_buf->xdp_ndo)
> >                               xdp_return_frame_bulk(dcb_buf->data.xdpf, &bq);
> >                       else
> > -                             xdp_return_frame_rx_napi(dcb_buf->data.xdpf);
> > +                             page_pool_recycle_direct(rx->page_pool,
> > +                                                      dcb_buf->data.page);
> >               }
> >
> >               clear = true;
> > @@ -702,6 +704,7 @@ static void lan966x_fdma_tx_start(struct lan966x_tx *tx, int next_to_use)
> >  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
> >                          struct xdp_frame *xdpf,
> >                          struct page *page,
> > +                        u32 len,
> 
> agreed with Olek regarding arguments reduction here

Yes, I will change this in the next version.

> 
> >                          bool dma_map)
> >  {
> >       struct lan966x *lan966x = port->lan966x;
> > @@ -722,6 +725,15 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
> >               goto out;
> >       }
> >
> > +     /* Fill up the buffer */
> > +     next_dcb_buf = &tx->dcbs_buf[next_to_use];
> > +     next_dcb_buf->use_skb = false;
> > +     next_dcb_buf->xdp_ndo = dma_map;
> 
> a bit misleading that xdp_ndo is a bool :P

There are few other variables that are misleading :), I need to get to
this and clean it a little bit.

> 
> > +     next_dcb_buf->len = len + IFH_LEN_BYTES;
> > +     next_dcb_buf->used = true;
> > +     next_dcb_buf->ptp = false;
> > +     next_dcb_buf->dev = port->dev;
> > +
> >       /* Generate new IFH */
> >       if (dma_map) {
> >               if (xdpf->headroom < IFH_LEN_BYTES) {
diff mbox series

Patch

diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
index 2ed76bb61a731..7947259e67e4e 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
@@ -390,6 +390,7 @@  static void lan966x_fdma_stop_netdev(struct lan966x *lan966x)
 static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
 {
 	struct lan966x_tx *tx = &lan966x->tx;
+	struct lan966x_rx *rx = &lan966x->rx;
 	struct lan966x_tx_dcb_buf *dcb_buf;
 	struct xdp_frame_bulk bq;
 	struct lan966x_db *db;
@@ -432,7 +433,8 @@  static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
 			if (dcb_buf->xdp_ndo)
 				xdp_return_frame_bulk(dcb_buf->data.xdpf, &bq);
 			else
-				xdp_return_frame_rx_napi(dcb_buf->data.xdpf);
+				page_pool_recycle_direct(rx->page_pool,
+							 dcb_buf->data.page);
 		}
 
 		clear = true;
@@ -702,6 +704,7 @@  static void lan966x_fdma_tx_start(struct lan966x_tx *tx, int next_to_use)
 int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
 			   struct xdp_frame *xdpf,
 			   struct page *page,
+			   u32 len,
 			   bool dma_map)
 {
 	struct lan966x *lan966x = port->lan966x;
@@ -722,6 +725,15 @@  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
 		goto out;
 	}
 
+	/* Fill up the buffer */
+	next_dcb_buf = &tx->dcbs_buf[next_to_use];
+	next_dcb_buf->use_skb = false;
+	next_dcb_buf->xdp_ndo = dma_map;
+	next_dcb_buf->len = len + IFH_LEN_BYTES;
+	next_dcb_buf->used = true;
+	next_dcb_buf->ptp = false;
+	next_dcb_buf->dev = port->dev;
+
 	/* Generate new IFH */
 	if (dma_map) {
 		if (xdpf->headroom < IFH_LEN_BYTES) {
@@ -736,16 +748,18 @@  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
 
 		dma_addr = dma_map_single(lan966x->dev,
 					  xdpf->data - IFH_LEN_BYTES,
-					  xdpf->len + IFH_LEN_BYTES,
+					  len + IFH_LEN_BYTES,
 					  DMA_TO_DEVICE);
 		if (dma_mapping_error(lan966x->dev, dma_addr)) {
 			ret = NETDEV_TX_OK;
 			goto out;
 		}
 
+		next_dcb_buf->data.xdpf = xdpf;
+
 		/* Setup next dcb */
 		lan966x_fdma_tx_setup_dcb(tx, next_to_use,
-					  xdpf->len + IFH_LEN_BYTES,
+					  len + IFH_LEN_BYTES,
 					  dma_addr);
 	} else {
 		ifh = page_address(page) + XDP_PACKET_HEADROOM;
@@ -756,25 +770,18 @@  int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
 		dma_addr = page_pool_get_dma_addr(page);
 		dma_sync_single_for_device(lan966x->dev,
 					   dma_addr + XDP_PACKET_HEADROOM,
-					   xdpf->len + IFH_LEN_BYTES,
+					   len + IFH_LEN_BYTES,
 					   DMA_TO_DEVICE);
 
+		next_dcb_buf->data.page = page;
+
 		/* Setup next dcb */
 		lan966x_fdma_tx_setup_dcb(tx, next_to_use,
-					  xdpf->len + IFH_LEN_BYTES,
+					  len + IFH_LEN_BYTES,
 					  dma_addr + XDP_PACKET_HEADROOM);
 	}
 
-	/* Fill up the buffer */
-	next_dcb_buf = &tx->dcbs_buf[next_to_use];
-	next_dcb_buf->use_skb = false;
-	next_dcb_buf->data.xdpf = xdpf;
-	next_dcb_buf->xdp_ndo = dma_map;
-	next_dcb_buf->len = xdpf->len + IFH_LEN_BYTES;
 	next_dcb_buf->dma_addr = dma_addr;
-	next_dcb_buf->used = true;
-	next_dcb_buf->ptp = false;
-	next_dcb_buf->dev = port->dev;
 
 	/* Start the transmission */
 	lan966x_fdma_tx_start(tx, next_to_use);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index 851afb0166b19..59da35a2c93d4 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -243,6 +243,7 @@  struct lan966x_tx_dcb_buf {
 	union {
 		struct sk_buff *skb;
 		struct xdp_frame *xdpf;
+		struct page *page;
 	} data;
 	u32 len;
 	u32 used : 1;
@@ -544,6 +545,7 @@  int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device *dev);
 int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
 			   struct xdp_frame *frame,
 			   struct page *page,
+			   u32 len,
 			   bool dma_map);
 int lan966x_fdma_change_mtu(struct lan966x *lan966x);
 void lan966x_fdma_netdev_init(struct lan966x *lan966x, struct net_device *dev);
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
index 2e6f486ec67d7..a8ad1f4e431cb 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c
@@ -62,7 +62,7 @@  int lan966x_xdp_xmit(struct net_device *dev,
 		struct xdp_frame *xdpf = frames[i];
 		int err;
 
-		err = lan966x_fdma_xmit_xdpf(port, xdpf, NULL, true);
+		err = lan966x_fdma_xmit_xdpf(port, xdpf, NULL, xdpf->len, true);
 		if (err)
 			break;
 
@@ -76,7 +76,6 @@  int lan966x_xdp_run(struct lan966x_port *port, struct page *page, u32 data_len)
 {
 	struct bpf_prog *xdp_prog = port->xdp_prog;
 	struct lan966x *lan966x = port->lan966x;
-	struct xdp_frame *xdpf;
 	struct xdp_buff xdp;
 	u32 act;
 
@@ -90,11 +89,9 @@  int lan966x_xdp_run(struct lan966x_port *port, struct page *page, u32 data_len)
 	case XDP_PASS:
 		return FDMA_PASS;
 	case XDP_TX:
-		xdpf = xdp_convert_buff_to_frame(&xdp);
-		if (!xdpf)
-			return FDMA_DROP;
-
-		return lan966x_fdma_xmit_xdpf(port, xdpf, page, false) ?
+		return lan966x_fdma_xmit_xdpf(port, NULL, page,
+					      data_len - IFH_LEN_BYTES,
+					      false) ?
 		       FDMA_DROP : FDMA_TX;
 	case XDP_REDIRECT:
 		if (xdp_do_redirect(port->dev, &xdp, xdp_prog))