The XDP frame's headroom might be large enough to accommodate the
xdpf backpointer as well as shifting the data to an aligned address.

Try this first before resorting to allocating a new buffer and copying
the data.

Suggested-by: Maciej Fijalkowski <maciej.fijalkow...@intel.com>
Signed-off-by: Camelia Groza <camelia.gr...@nxp.com>
Acked-by: Maciej Fijalkowski <maciej.fijalkow...@intel.com>
---
 .../net/ethernet/freescale/dpaa/dpaa_eth.c    | 20 ++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 2a2c7db23407..6faa20bed488 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2180,8 +2180,9 @@ static int dpaa_a050385_wa_xdpf(struct dpaa_priv *priv,
                                struct xdp_frame **init_xdpf)
 {
        struct xdp_frame *new_xdpf, *xdpf = *init_xdpf;
-       void *new_buff;
+       void *new_buff, *aligned_data;
        struct page *p;
+       u32 data_shift;
        int headroom;
 
        /* Check the data alignment and make sure the headroom is large
@@ -2198,6 +2199,23 @@ static int dpaa_a050385_wa_xdpf(struct dpaa_priv *priv,
                return 0;
        }
 
+       /* Try to move the data inside the buffer just enough to align it and
+        * store the xdpf backpointer. If the available headroom isn't large
+        * enough, resort to allocating a new buffer and copying the data.
+        */
+       aligned_data = PTR_ALIGN_DOWN(xdpf->data, DPAA_FD_DATA_ALIGNMENT);
+       data_shift = xdpf->data - aligned_data;
+
+       /* The XDP frame's headroom needs to be large enough to accommodate
+        * shifting the data as well as storing the xdpf backpointer.
+        */
+       if (xdpf->headroom  >= data_shift + priv->tx_headroom) {
+               memmove(aligned_data, xdpf->data, xdpf->len);
+               xdpf->data = aligned_data;
+               xdpf->headroom = priv->tx_headroom;
+               return 0;
+       }
+
        /* The new xdp_frame is stored in the new buffer. Reserve enough space
         * in the headroom for storing it along with the driver's private
         * info. The headroom needs to be aligned to DPAA_FD_DATA_ALIGNMENT to
-- 
2.17.1

Reply via email to