Devicetree
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox