Commit d4f9b884 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'fix-rx-fatal-errors'

Jiawen Wu says:

====================
Fix Rx fatal errors

There are some fatal errors on the Rx NAPI path, which can cause
the kernel to crash. Fix known issues and potential risks.

The part of the patches has been mentioned before[1].

[1]: https://lore.kernel.org/all/C8A23A11DB646E60+20250630094102.22265-1-jiawenwu@trustnetic.com/

v1: https://lore.kernel.org/20250709064025.19436-1-jiawenwu@trustnetic.com
====================

Link: https://patch.msgid.link/20250714024755.17512-1-jiawenwu@trustnetic.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents e6176ab1 d992ed7e
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -1912,7 +1912,6 @@ static void wx_configure_rx_ring(struct wx *wx,
				 struct wx_ring *ring)
{
	u16 reg_idx = ring->reg_idx;
	union wx_rx_desc *rx_desc;
	u64 rdba = ring->dma;
	u32 rxdctl;

@@ -1942,9 +1941,9 @@ static void wx_configure_rx_ring(struct wx *wx,
	memset(ring->rx_buffer_info, 0,
	       sizeof(struct wx_rx_buffer) * ring->count);

	/* initialize Rx descriptor 0 */
	rx_desc = WX_RX_DESC(ring, 0);
	rx_desc->wb.upper.length = 0;
	/* reset ntu and ntc to place SW in sync with hardware */
	ring->next_to_clean = 0;
	ring->next_to_use = 0;

	/* enable receive descriptor ring */
	wr32m(wx, WX_PX_RR_CFG(reg_idx),
+7 −13
Original line number Diff line number Diff line
@@ -174,10 +174,6 @@ static void wx_dma_sync_frag(struct wx_ring *rx_ring,
				      skb_frag_off(frag),
				      skb_frag_size(frag),
				      DMA_FROM_DEVICE);

	/* If the page was released, just unmap it. */
	if (unlikely(WX_CB(skb)->page_released))
		page_pool_put_full_page(rx_ring->page_pool, rx_buffer->page, false);
}

static struct wx_rx_buffer *wx_get_rx_buffer(struct wx_ring *rx_ring,
@@ -227,10 +223,6 @@ static void wx_put_rx_buffer(struct wx_ring *rx_ring,
			     struct sk_buff *skb,
			     int rx_buffer_pgcnt)
{
	if (!IS_ERR(skb) && WX_CB(skb)->dma == rx_buffer->dma)
		/* the page has been released from the ring */
		WX_CB(skb)->page_released = true;

	/* clear contents of rx_buffer */
	rx_buffer->page = NULL;
	rx_buffer->skb = NULL;
@@ -315,7 +307,7 @@ static bool wx_alloc_mapped_page(struct wx_ring *rx_ring,
		return false;
	dma = page_pool_get_dma_addr(page);

	bi->page_dma = dma;
	bi->dma = dma;
	bi->page = page;
	bi->page_offset = 0;

@@ -352,7 +344,7 @@ void wx_alloc_rx_buffers(struct wx_ring *rx_ring, u16 cleaned_count)
						 DMA_FROM_DEVICE);

		rx_desc->read.pkt_addr =
			cpu_to_le64(bi->page_dma + bi->page_offset);
			cpu_to_le64(bi->dma + bi->page_offset);

		rx_desc++;
		bi++;
@@ -365,6 +357,8 @@ void wx_alloc_rx_buffers(struct wx_ring *rx_ring, u16 cleaned_count)

		/* clear the status bits for the next_to_use descriptor */
		rx_desc->wb.upper.status_error = 0;
		/* clear the length for the next_to_use descriptor */
		rx_desc->wb.upper.length = 0;

		cleaned_count--;
	} while (cleaned_count);
@@ -2423,9 +2417,6 @@ static void wx_clean_rx_ring(struct wx_ring *rx_ring)
		if (rx_buffer->skb) {
			struct sk_buff *skb = rx_buffer->skb;

			if (WX_CB(skb)->page_released)
				page_pool_put_full_page(rx_ring->page_pool, rx_buffer->page, false);

			dev_kfree_skb(skb);
		}

@@ -2449,6 +2440,9 @@ static void wx_clean_rx_ring(struct wx_ring *rx_ring)
		}
	}

	/* Zero out the descriptor ring */
	memset(rx_ring->desc, 0, rx_ring->size);

	rx_ring->next_to_alloc = 0;
	rx_ring->next_to_clean = 0;
	rx_ring->next_to_use = 0;
+0 −2
Original line number Diff line number Diff line
@@ -909,7 +909,6 @@ enum wx_reset_type {
struct wx_cb {
	dma_addr_t dma;
	u16     append_cnt;      /* number of skb's appended */
	bool    page_released;
	bool    dma_released;
};

@@ -998,7 +997,6 @@ struct wx_tx_buffer {
struct wx_rx_buffer {
	struct sk_buff *skb;
	dma_addr_t dma;
	dma_addr_t page_dma;
	struct page *page;
	unsigned int page_offset;
};