Commit fb6221a2 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'dpaa_eth-a050385-erratum-workaround-fixes-under-xdp'

Camelia Groza says:

====================
dpaa_eth: A050385 erratum workaround fixes under XDP

This series addresses issue with the current workaround for the A050385
erratum in XDP scenarios.

The first patch makes sure the xdp_frame structure stored at the start of
new buffers isn't overwritten.

The second patch decreases the required data alignment value, thus
preventing unnecessary realignments.

The third patch moves the data in place to align it, instead of allocating
a new buffer for each frame that breaks the alignment rules, thus bringing
an up to 40% performance increase. With this change, the impact of the
erratum workaround is reduced in many cases to a single digit decrease, and
to lower double digits in single flow scenarios.

Changes in v2:
- guarantee enough tailroom is available for the shared_info in 1/3
====================

Link: https://lore.kernel.org/r/cover.1612456902.git.camelia.groza@nxp.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 8dc1c444 0a9946cc
...@@ -2180,8 +2180,10 @@ static int dpaa_a050385_wa_xdpf(struct dpaa_priv *priv, ...@@ -2180,8 +2180,10 @@ static int dpaa_a050385_wa_xdpf(struct dpaa_priv *priv,
struct xdp_frame **init_xdpf) struct xdp_frame **init_xdpf)
{ {
struct xdp_frame *new_xdpf, *xdpf = *init_xdpf; struct xdp_frame *new_xdpf, *xdpf = *init_xdpf;
void *new_buff; void *new_buff, *aligned_data;
struct page *p; struct page *p;
u32 data_shift;
int headroom;
/* Check the data alignment and make sure the headroom is large /* Check the data alignment and make sure the headroom is large
* enough to store the xdpf backpointer. Use an aligned headroom * enough to store the xdpf backpointer. Use an aligned headroom
...@@ -2191,25 +2193,57 @@ static int dpaa_a050385_wa_xdpf(struct dpaa_priv *priv, ...@@ -2191,25 +2193,57 @@ static int dpaa_a050385_wa_xdpf(struct dpaa_priv *priv,
* byte frame headroom. If the XDP program uses all of it, copy the * byte frame headroom. If the XDP program uses all of it, copy the
* data to a new buffer and make room for storing the backpointer. * data to a new buffer and make room for storing the backpointer.
*/ */
if (PTR_IS_ALIGNED(xdpf->data, DPAA_A050385_ALIGN) && if (PTR_IS_ALIGNED(xdpf->data, DPAA_FD_DATA_ALIGNMENT) &&
xdpf->headroom >= priv->tx_headroom) { xdpf->headroom >= priv->tx_headroom) {
xdpf->headroom = priv->tx_headroom; xdpf->headroom = priv->tx_headroom;
return 0; 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
* guarantee the data's alignment in the buffer.
*/
headroom = ALIGN(sizeof(*new_xdpf) + priv->tx_headroom,
DPAA_FD_DATA_ALIGNMENT);
/* Assure the extended headroom and data don't overflow the buffer,
* while maintaining the mandatory tailroom.
*/
if (headroom + xdpf->len > DPAA_BP_RAW_SIZE -
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
return -ENOMEM;
p = dev_alloc_pages(0); p = dev_alloc_pages(0);
if (unlikely(!p)) if (unlikely(!p))
return -ENOMEM; return -ENOMEM;
/* Copy the data to the new buffer at a properly aligned offset */ /* Copy the data to the new buffer at a properly aligned offset */
new_buff = page_address(p); new_buff = page_address(p);
memcpy(new_buff + priv->tx_headroom, xdpf->data, xdpf->len); memcpy(new_buff + headroom, xdpf->data, xdpf->len);
/* Create an XDP frame around the new buffer in a similar fashion /* Create an XDP frame around the new buffer in a similar fashion
* to xdp_convert_buff_to_frame. * to xdp_convert_buff_to_frame.
*/ */
new_xdpf = new_buff; new_xdpf = new_buff;
new_xdpf->data = new_buff + priv->tx_headroom; new_xdpf->data = new_buff + headroom;
new_xdpf->len = xdpf->len; new_xdpf->len = xdpf->len;
new_xdpf->headroom = priv->tx_headroom; new_xdpf->headroom = priv->tx_headroom;
new_xdpf->frame_sz = DPAA_BP_RAW_SIZE; new_xdpf->frame_sz = DPAA_BP_RAW_SIZE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment