Linux kernel -stable discussions
 help / color / mirror / Atom feed
From: Greg KH <greg@kroah.com>
To: Sasha Levin <sashal@kernel.org>
Cc: stable@vger.kernel.org, Dexuan Cui <decui@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Paolo Abeni <pabeni@redhat.com>
Subject: Re: [PATCH 6.18.y 2/2] net: mana: Sync page pool RX frags for CPU
Date: Thu, 30 Jul 2026 14:22:53 +0200	[thread overview]
Message-ID: <2026073048-curled-prison-0ebe@gregkh> (raw)
In-Reply-To: <20260728121110.3702926-2-sashal@kernel.org>

On Tue, Jul 28, 2026 at 08:11:10AM -0400, Sasha Levin wrote:
> From: Dexuan Cui <decui@microsoft.com>
> 
> [ Upstream commit c72a0f09c57f92113df69f9b902d11c9e4b132f5 ]
> 
> MANA allocates RX buffers from page pool fragments when frag_count is
> greater than 1. In that case the buffers remain DMA mapped by page pool
> and the RX completion path does not call dma_unmap_single(). As a result,
> the implicit sync-for-CPU normally performed by dma_unmap_single() is
> missing before the packet data is passed to the networking stack.
> 
> This breaks RX on configurations which require explicit DMA syncing, for
> example when booted with swiotlb=force.
> 
> Fix this by recording the page pool page and DMA sync offset when the RX
> buffer is allocated, and syncing the received packet range for CPU access
> before handing the RX buffer to the stack.
> 
> Fixes: 730ff06d3f5c ("net: mana: Use page pool fragments for RX buffers instead of full pages to improve memory efficiency.")
> Cc: stable@vger.kernel.org
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> Link: https://patch.msgid.link/20260702041237.617719-3-decui@microsoft.com
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>  drivers/net/ethernet/microsoft/mana/mana_en.c | 40 +++++++++++++++----
>  include/net/mana/mana.h                       |  8 ++++
>  2 files changed, 41 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index cbeb04ee727275..effee6c56c919d 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -2036,12 +2036,16 @@ static void mana_rx_skb(void *buf_va, bool from_pool,
>  }
>  
>  static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
> -			     dma_addr_t *da, bool *from_pool)
> +			     dma_addr_t *da, bool *from_pool,
> +			     struct page **pp_page, u32 *dma_sync_offset)
>  {
>  	struct page *page;
>  	u32 offset;
>  	void *va;
> +
>  	*from_pool = false;
> +	*pp_page = NULL;
> +	*dma_sync_offset = 0;
>  
>  	/* Don't use fragments for jumbo frames or XDP where it's 1 fragment
>  	 * per page.
> @@ -2079,31 +2083,47 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
>  	va  = page_to_virt(page) + offset;
>  	*da = page_pool_get_dma_addr(page) + offset + rxq->headroom;
>  	*from_pool = true;
> +	*pp_page = page;
> +	*dma_sync_offset = offset + rxq->headroom;
>  
>  	return va;
>  }
>  
>  /* Allocate frag for rx buffer, and save the old buf */
>  static void mana_refill_rx_oob(struct device *dev, struct mana_rxq *rxq,
> -			       struct mana_recv_buf_oob *rxoob, void **old_buf,
> -			       bool *old_fp)
> +			       struct mana_recv_buf_oob *rxoob, u32 pktlen,
> +			       void **old_buf, bool *old_fp)
>  {
> +	struct page *pp_page;
> +	u32 dma_sync_offset;
>  	bool from_pool;
>  	dma_addr_t da;
>  	void *va;
>  
> -	va = mana_get_rxfrag(rxq, dev, &da, &from_pool);
> +	va = mana_get_rxfrag(rxq, dev, &da, &from_pool, &pp_page,
> +			     &dma_sync_offset);
>  	if (!va)
>  		return;
> -	if (!rxoob->from_pool || rxq->frag_count == 1)
> +	if (!rxoob->from_pool || rxq->frag_count == 1) {
>  		dma_unmap_single(dev, rxoob->sgl[0].address, rxq->datasize,
>  				 DMA_FROM_DEVICE);
> +	} else {
> +		/* The page pool maps the whole page and only syncs for device
> +		 * automatically (PP_FLAG_DMA_SYNC_DEV). Sync the received bytes
> +		 * for the CPU before they are read: this is required if DMA
> +		 * is incoherent or bounce buffers are used.
> +		 */
> +		page_pool_dma_sync_for_cpu(rxq->page_pool, rxoob->pp_page,
> +					   rxoob->dma_sync_offset, pktlen);
> +	}
>  	*old_buf = rxoob->buf_va;
>  	*old_fp = rxoob->from_pool;
>  
>  	rxoob->buf_va = va;
>  	rxoob->sgl[0].address = da;
>  	rxoob->from_pool = from_pool;
> +	rxoob->pp_page = pp_page;
> +	rxoob->dma_sync_offset = dma_sync_offset;
>  }
>  
>  static void mana_process_rx_cqe(struct mana_rxq *rxq, struct mana_cq *cq,
> @@ -2172,7 +2192,8 @@ static void mana_process_rx_cqe(struct mana_rxq *rxq, struct mana_cq *cq,
>  		/* Reuse the RX buffer since rxbuf_oob is unchanged. */
>  	} else {
>  
> -		mana_refill_rx_oob(dev, rxq, rxbuf_oob, &old_buf, &old_fp);
> +		mana_refill_rx_oob(dev, rxq, rxbuf_oob, pktlen,
> +				   &old_buf, &old_fp);
>  
>  		/* Unsuccessful refill will have old_buf == NULL.
>  		 * In this case, mana_rx_skb() will drop the packet.
> @@ -2548,6 +2569,8 @@ static int mana_fill_rx_oob(struct mana_recv_buf_oob *rx_oob, u32 mem_key,
>  			    struct mana_rxq *rxq, struct device *dev)
>  {
>  	struct mana_port_context *mpc = netdev_priv(rxq->ndev);
> +	struct page *pp_page = NULL;
> +	u32 dma_sync_offset = 0;
>  	bool from_pool = false;
>  	dma_addr_t da;
>  	void *va;
> @@ -2555,13 +2578,16 @@ static int mana_fill_rx_oob(struct mana_recv_buf_oob *rx_oob, u32 mem_key,
>  	if (mpc->rxbufs_pre)
>  		va = mana_get_rxbuf_pre(rxq, &da);
>  	else
> -		va = mana_get_rxfrag(rxq, dev, &da, &from_pool);
> +		va = mana_get_rxfrag(rxq, dev, &da, &from_pool, &pp_page,
> +				     &dma_sync_offset);
>  
>  	if (!va)
>  		return -ENOMEM;
>  
>  	rx_oob->buf_va = va;
>  	rx_oob->from_pool = from_pool;
> +	rx_oob->pp_page = pp_page;
> +	rx_oob->dma_sync_offset = dma_sync_offset;
>  
>  	rx_oob->sgl[0].address = da;
>  	rx_oob->sgl[0].size = rxq->datasize;
> diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
> index e199f1d44c8e30..a134b123527971 100644
> --- a/include/net/mana/mana.h
> +++ b/include/net/mana/mana.h
> @@ -302,6 +302,14 @@ struct mana_recv_buf_oob {
>  
>  	void *buf_va;
>  	bool from_pool; /* allocated from a page pool */
> +	/* head page of the page_pool fragment; valid only when
> +	 * from_pool && frag_count > 1.
> +	 */
> +	struct page *pp_page;
> +	/* Fragment offset plus rxq->headroom, passed to
> +	 * page_pool_dma_sync_for_cpu().
> +	 */
> +	u32 dma_sync_offset;
>  
>  	/* SGL of the buffer going to be sent as part of the work request. */
>  	u32 num_sge;
> -- 
> 2.53.0
> 
> 

Does not apply :(

  reply	other threads:[~2026-07-30 12:23 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-20 15:50 FAILED: patch "[PATCH] net: mana: Sync page pool RX frags for CPU" failed to apply to 6.18-stable tree gregkh
2026-07-28 12:11 ` [PATCH 6.18.y 1/2] net: mana: Validate the packet length reported by the NIC Sasha Levin
2026-07-28 12:11   ` [PATCH 6.18.y 2/2] net: mana: Sync page pool RX frags for CPU Sasha Levin
2026-07-30 12:22     ` Greg KH [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-10-06 13:25 [PATCH 6.18.y 1/2] net: mana: remove double CQ cleanup in mana_create_rxq error path Hamza Mahfooz
2026-10-06 13:25 ` [PATCH 6.18.y 2/2] net: mana: Sync page pool RX frags for CPU Hamza Mahfooz
2026-10-07  6:34   ` Greg Kroah-Hartman
2026-10-07 21:03   ` Sasha Levin

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=2026073048-curled-prison-0ebe@gregkh \
    --to=greg@kroah.com \
    --cc=decui@microsoft.com \
    --cc=haiyangz@microsoft.com \
    --cc=pabeni@redhat.com \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /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