All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: muhammad.nazim.amirul.nazle.asmade@altera.com
Cc: robh@kernel.org, devicetree@vger.kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH net-next 2/3] net: stmmac: Use pagepool instead of streaming buffers for Tx
Date: Tue, 04 Aug 2026 07:05:34 +0000	[thread overview]
Message-ID: <20260804070535.194A51F00A3E@smtp.kernel.org> (raw)
In-Reply-To: <20260803070513.4657-3-muhammad.nazim.amirul.nazle.asmade@altera.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [High] `page_pool_recycle_direct()` is called outside of NAPI context, leading to potential lockless ring corruption.
- [Medium] Unnecessary `PP_FLAG_DMA_SYNC_DEV` flag causes redundant full-page DMA syncs, defeating performance goals.

Pre-existing issues:
- [High] Unconditional NULL pointer dereference in `dma_free_tx_skbufs` if `tx_skbuff_dma` allocation fails.
- [High] DMA mapping and `page_pool` memory leak when `skb_frag_dma_map()` fails during transmission.
- [High] Double free and Use-After-Free of TX queue resources due to dangling pointers on teardown.
--

--- Patch [2]: [PATCH net-next 2/3] net: stmmac: Use pagepool instead of streaming buffers for Tx ---
commit a91ef91a303112e59c32621c9138a02b37e37769
Author: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Subject: net: stmmac: Use pagepool instead of streaming buffers for Tx

Use page pool buffers instead of streaming skb buffers in stmmac_xmit
when snps,pagepool-tx-buf-quirk is enabled. As page pool buffers are
recycled, the overhead of dma map/unmap for each transmit can be avoided.

> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index ee44bd6f4d48e..4aa6b1d1507bf 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1712,7 +1712,10 @@ static void stmmac_free_tx_buffer(struct stmmac_priv *priv,
>  
>  	if (tx_q->tx_skbuff_dma[i].buf &&
>  	    tx_q->tx_skbuff_dma[i].buf_type != STMMAC_TXBUF_T_XDP_TX) {

[Severity: High]
This is a pre-existing issue, but is it possible for this code to trigger a
NULL pointer dereference?

If the memory allocation for tx_q->tx_skbuff_dma fails in
__alloc_dma_tx_desc_resources() (in stmmac_main.c), it returns -ENOMEM. The
error path then calls free_dma_tx_desc_resources(), which loops over the
queues and calls __free_dma_tx_desc_resources(). This ultimately calls
dma_free_tx_skbufs(), which unconditionally indexes into
tx_q->tx_skbuff_dma[i] via stmmac_free_tx_buffer().

Since tx_q->tx_skbuff_dma is NULL, would this result in a panic during
device setup or XDP re-initialization on memory pressure?

> -		if (tx_q->tx_skbuff_dma[i].map_as_page)
> +		if (tx_q->tx_skbuff_dma[i].buf_type == STMMAC_TXBUF_T_DMA)
> +			page_pool_recycle_direct(tx_q->page_pool,
> +						 tx_q->tx_skbuff_dma[i].page);

[Severity: High]
Is it safe to call page_pool_recycle_direct() here outside of NAPI context?

The page_pool_recycle_direct() API requires execution in NAPI softirq context
on the same CPU, as it bypasses locking (allow_direct=true). However,
stmmac_free_tx_buffer() is called by dma_free_tx_skbufs() during device
teardown (process context) and by stmmac_tx_err(), which is triggered from
stmmac_napi_check() directly inside the hardirq handler when a TX error
occurs.

Could calling this lockless API from hardirq or process contexts race with
NAPI polling and lead to internal page pool ring corruption?

> +		else if (tx_q->tx_skbuff_dma[i].map_as_page)
>  			dma_unmap_page(priv->device,
>  				       tx_q->tx_skbuff_dma[i].buf,
>  				       tx_q->tx_skbuff_dma[i].len,
[ ... ]
> @@ -2201,6 +2205,8 @@ static void __free_dma_tx_desc_resources(struct stmmac_priv *priv,
>  
>  	kfree(tx_q->tx_skbuff_dma);
>  	kfree(tx_q->tx_skbuff);
> +	if (tx_q->page_pool)
> +		page_pool_destroy(tx_q->page_pool);

[Severity: High]
This is a pre-existing issue, but does this code leave dangling pointers that
could cause a double free or use-after-free on teardown?

Memory arrays (tx_q->tx_skbuff, tx_q->tx_skbuff_dma) and the newly added
tx_q->page_pool are freed or destroyed, but their pointers are not nullified.
If a subsequent resource allocation fails (e.g. during stmmac_xdp_open()),
the error path calls free_dma_tx_desc_resources(), which loops over all
queues.

For queues that were not successfully re-initialized, it re-executes kfree()
and page_pool_destroy() on the stale, dangling pointers.

>  }
>  
>  static void free_dma_tx_desc_resources(struct stmmac_priv *priv,
[ ... ]
> @@ -2335,12 +2341,32 @@ static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv,
>  					 u32 queue)
>  {
>  	struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
> +	struct page_pool_params pp_params = { 0 };
> +	unsigned int num_pages;
>  	size_t size;
>  	void *addr;
> +	int ret;
>  
>  	tx_q->queue_index = queue;
>  	tx_q->priv_data = priv;
>  
> +	pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;

[Severity: Medium]
Does using PP_FLAG_DMA_SYNC_DEV cause redundant full-page DMA syncs?

This flag instructs the page pool to automatically synchronize the entire
allocated size (up to 16KB) for the device. However, as seen later in
stmmac_xmit(), the driver manually calls dma_sync_single_for_cpu() and
dma_sync_single_for_device() on just the packet payload length (nopaged_len).

Would this result in double-syncing where the page pool redundantly syncs the
full page on every allocation, reducing the intended performance benefit?

> +	pp_params.pool_size = dma_conf->dma_tx_size;
> +	num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE);
[ ... ]
> @@ -4742,12 +4773,14 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
>  	bool enh_desc, has_vlan, set_ic, is_jumbo = false;
>  	struct stmmac_priv *priv = netdev_priv(dev);
>  	unsigned int nopaged_len = skb_headlen(skb);
> +	gfp_t gfp = GFP_ATOMIC | __GFP_NOWARN;
>  	u32 queue = skb_get_queue_mapping(skb);
>  	int nfrags = skb_shinfo(skb)->nr_frags;
>  	unsigned int first_entry, tx_packets;
>  	struct stmmac_txq_stats *txq_stats;
>  	struct dma_desc *desc, *first_desc;
>  	struct stmmac_tx_queue *tx_q;
> +	struct page *tx_buf_page;
>  	int i, csum_insertion = 0;
>  	int entry, first_tx;
>  	dma_addr_t dma_addr;
> @@ -4814,13 +4847,33 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
>  	} else {
>  		bool last_segment = (nfrags == 0);
>  
> -		dma_addr = dma_map_single(priv->device, skb->data,
> -					  nopaged_len, DMA_TO_DEVICE);
> -		if (dma_mapping_error(priv->device, dma_addr))
> -			goto dma_map_err;
> +		if (!(last_segment && priv->plat->tx_buf_quirk)) {
> +			dma_addr = dma_map_single(priv->device, skb->data,
> +						  nopaged_len, DMA_TO_DEVICE);
> +			if (dma_mapping_error(priv->device, dma_addr))
> +				goto dma_map_err;
>  
> -		stmmac_set_tx_skb_dma_entry(tx_q, first_entry, dma_addr,
> -					    nopaged_len, false);
> +			stmmac_set_tx_skb_dma_entry(tx_q, first_entry, dma_addr,
> +						    nopaged_len, false);
> +		} else {
> +			tx_buf_page = page_pool_alloc_pages(tx_q->page_pool, gfp);
> +			if (!tx_buf_page)
> +				goto dma_map_err;
> +
> +			dma_addr = page_pool_get_dma_addr(tx_buf_page);
> +			stmmac_set_tx_dma_entry(tx_q, first_entry,
> +						STMMAC_TXBUF_T_DMA, dma_addr,
> +						nopaged_len, false);
> +			tx_q->tx_skbuff_dma[first_entry].page = tx_buf_page;
> +
> +			dma_sync_single_for_cpu(priv->device, dma_addr,
> +						nopaged_len, DMA_BIDIRECTIONAL);
> +			skb_copy_from_linear_data(skb, page_address(tx_buf_page),
> +						  nopaged_len);
> +			dma_sync_single_for_device(priv->device, dma_addr,
> +						   nopaged_len,
> +						   DMA_BIDIRECTIONAL);
> +		}
>  
>  		stmmac_set_desc_addr(priv, first_desc, dma_addr);
>  

[Severity: High]
This isn't a bug introduced by this patch, but does the error path in
stmmac_xmit() leak DMA mappings and memory when skb_frag_dma_map() fails?

If mapping an SKB fragment fails lower down in stmmac_xmit() via
skb_frag_dma_map(), the code jumps to the dma_map_err label, frees the SKB,
and returns. However, it fails to unmap previously mapped fragments or the
linear segment, and does not advance the tx_q->cur_tx ring index.

Because the index is not advanced, stmmac_tx_clean() will never process these
leaked entries, and the next packet transmitted will silently overwrite
tx_q->tx_skbuff_dma[first_entry]. For the newly added page pool buffer, this
permanently leaks the underlying physical page allocated from
page_pool_alloc_pages(), which could deplete system memory over time.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260803070513.4657-1-muhammad.nazim.amirul.nazle.asmade@altera.com?part=2

  parent reply	other threads:[~2026-08-04  7:05 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-03  7:05 [PATCH net-next 0/3] net: stmmac: page pool Tx buffer quirk muhammad.nazim.amirul.nazle.asmade
2026-08-03  7:05 ` [PATCH net-next 1/3] dt-bindings: net: snps,dwmac: Add snps,pagepool-tx-buf-quirk muhammad.nazim.amirul.nazle.asmade
2026-08-04  7:05   ` sashiko-bot
2026-08-04  8:37   ` Krzysztof Kozlowski
2026-08-03  7:05 ` [PATCH net-next 2/3] net: stmmac: Use pagepool instead of streaming buffers for Tx muhammad.nazim.amirul.nazle.asmade
2026-08-03 18:39   ` Mina Almasry
2026-08-03 18:53     ` Mina Almasry
2026-08-04  7:05   ` sashiko-bot [this message]
2026-08-03  7:05 ` [PATCH 3/3] arm64: dts: agilex5: Enable pagepool Tx buffer quirk muhammad.nazim.amirul.nazle.asmade
2026-08-04  7:05   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260804070535.194A51F00A3E@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=muhammad.nazim.amirul.nazle.asmade@altera.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.