Skip to content

Commit 432e629

Browse files
Saeed Mahameeddavem330
authored andcommitted
net/mlx4_en: Don't reuse RX page when XDP is set
When a new rx packet arrives, the rx path will decide whether to reuse the remainder of the page or not according to one of the below conditions: 1. frag_info->frag_stride == PAGE_SIZE / 2 2. frags->page_offset + frag_info->frag_size > PAGE_SIZE; The first condition is no met for when XDP is set. For XDP, page_offset is always set to priv->rx_headroom which is XDP_PACKET_HEADROOM and frag_info->frag_size is around mtu size + some padding, still the 2nd release condition will hold since XDP_PACKET_HEADROOM + 1536 < PAGE_SIZE, as a result the page will not be released and will be _wrongly_ reused for next free rx descriptor. In XDP there is an assumption to have a page per packet and reuse can break such assumption and might cause packet data corruptions. Fix this by adding an extra condition (!priv->rx_headroom) to the 2nd case to avoid page reuse when XDP is set, since rx_headroom is set to 0 for non XDP setup and set to XDP_PACKET_HEADROOM for XDP setup. No additional cache line is required for the new condition. Fixes: 34db548 ("mlx4: add page recycling in receive path") Signed-off-by: Saeed Mahameed <[email protected]> Signed-off-by: Tariq Toukan <[email protected]> Suggested-by: Martin KaFai Lau <[email protected]> CC: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c133459 commit 432e629

File tree

1 file changed

+6
-2
lines changed
  • drivers/net/ethernet/mellanox/mlx4

1 file changed

+6
-2
lines changed

drivers/net/ethernet/mellanox/mlx4/en_rx.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,10 +474,10 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
474474
{
475475
const struct mlx4_en_frag_info *frag_info = priv->frag_info;
476476
unsigned int truesize = 0;
477+
bool release = true;
477478
int nr, frag_size;
478479
struct page *page;
479480
dma_addr_t dma;
480-
bool release;
481481

482482
/* Collect used fragments while replacing them in the HW descriptors */
483483
for (nr = 0;; frags++) {
@@ -500,7 +500,11 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
500500
release = page_count(page) != 1 ||
501501
page_is_pfmemalloc(page) ||
502502
page_to_nid(page) != numa_mem_id();
503-
} else {
503+
} else if (!priv->rx_headroom) {
504+
/* rx_headroom for non XDP setup is always 0.
505+
* When XDP is set, the above condition will
506+
* guarantee page is always released.
507+
*/
504508
u32 sz_align = ALIGN(frag_size, SMP_CACHE_BYTES);
505509

506510
frags->page_offset += sz_align;

0 commit comments

Comments
 (0)