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 :(
next prev parent 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