From: netdev-bot+sashiko@kernel.org
To: linusw@kernel.org
Cc: ulli.kroll@googlemail.com, andrew+netdev@lunn.ch,
davem@davemloft.net, kuba@kernel.org, pabeni@redhat.com,
mirq-linux@rere.qmqm.pl, mhun512@gmail.com, edumazet@kernel.org,
netdev@vger.kernel.org
Subject: Re: [PATCH net-next v5 07/14] net: ethernet: cortina: Preserve in-flight free queue pages
Date: Mon, 19 Oct 2026 17:28:47 +0000 [thread overview]
Message-ID: <179243092709.3135.17234520297875888006@kernel.org> (raw)
In-Reply-To: <20261015-gemini-ethernet-fixes-3-v5-7-b5c9e2f7b8a3@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider.
Critical: 0 · High: 0 · Medium: 1 · Low: 1 (1)
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] geth_setup_freeq() sets the software write pointer to the
hardware read pointer kept from the previous queue, using…
- [Low] geth_setup_freeq() allocates geth->freeq_pages with
kzalloc_objs() sized by page_slots.
Pre-existing issues:
- [Low] The kernel-doc for geth_fill_freeq() says 'Usually the interrupt
to refill the queue happens when the queue is half empty.' The SWFQ…
--
net: ethernet: cortina: Preserve in-flight free queue pages
This patch allocates free queue page metadata slots independently of free
queue positions. Occupied slots are tracked with a bitmap, and each fragment
DMA address stays in the XArray until its RX descriptor is claimed. The patch
also sizes the metadata pool for the free queue plus both RX rings, and
requires the initial fill to populate every usable entry.
> diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
> index c1c42e1f93f42..faab1bb865ab4 100644
> --- a/drivers/net/ethernet/cortina/gemini.c
> +++ b/drivers/net/ethernet/cortina/gemini.c
[ ... ]
> @@ -910,20 +952,20 @@ static struct page *geth_freeq_alloc_map_page(struct gemini_ethernet *geth,
[ ... ]
> /**
> * geth_fill_freeq() - Fill the freeq with empty fragments to use
> * @geth: the ethernet adapter
> - * @refill: whether to reset the queue by filling in all freeq entries or
> - * just refill it, usually the interrupt to refill the queue happens when
> - * the queue is half empty.
> + *
> + * Usually the interrupt to refill the queue happens when the queue is half
> + * empty.
> */
[Severity: Low]
This problem was not introduced by this patch. The "half empty" wording comes
from the old kernel-doc, and it doesn't seem to match the code.
geth_setup_freeq() programs the SWFQ empty interrupt with:
qt.bits.swfq_empty = 32;
gemini.h documents that field as the "Software Free Queue Empty Threshold".
Only the NAPI refill in gmac_napi_poll() uses a half-queue threshold:
freeq_threshold = 1 << (geth->freeq_order - 1);
gemini_port_irq_thread() has the same "half empty" comment. Could both
comments be fixed while this kernel-doc is being rewritten?
[ ... ]
> @@ -1003,27 +1106,22 @@ static int geth_setup_freeq(struct gemini_ethernet *geth)
> }
>
> /* Allocate page metadata referenced by the mapping index */
> - geth->freeq_pages = kzalloc_objs(*geth->freeq_pages, pages);
> + geth->freeq_pages = kzalloc_objs(*geth->freeq_pages, page_slots);
[Severity: Low]
Could this allocation become hard to satisfy at larger ring sizes?
page_slots now includes both RX ring sizes, added in
geth_freeq_page_slots():
if (geth->port0 && geth->port0->netdev)
slots += 1 << geth->port0->rxq_order;
if (geth->port1 && geth->port1->netdev)
slots += 1 << geth->port1->rxq_order;
struct gmac_queue_page has also grown to 12 bytes on 32-bit Gemini.
At the ethtool maximum (rxq_order 15 on both ports, freeq_order 15) this is
16384 + 32768 + 32768 = 81920 entries. That is about 960 KiB of physically
contiguous kmalloc memory (order 8). Before this patch it was 128 KiB.
With rxq_order 11 on both ports it needs 96 KiB (order 5). The old code
needed 32 KiB.
If the allocation fails under fragmentation, geth_resize_freeq() fails, and
gmac_open() or the ethtool -G request returns -ENOMEM. Only the CPU accesses
this array, so would kvcalloc() and kvfree() be a better fit?
> if (!geth->freeq_pages)
> goto err_freeq;
> - geth->num_freeq_pages = pages;
> -
[ ... ]
> + geth->freeq_page_bitmap = bitmap_zalloc(page_slots, GFP_KERNEL);
> + if (!geth->freeq_page_bitmap)
> + goto err_freeq_pages;
> + geth->num_freeq_pages = page_slots;
>
> /* Match the software pointer to the retained hardware pointer. */
> rptr = GET_RPTR(geth->base + GLOBAL_SWFQ_RWPTR_REG);
> SET_WPTR(geth->base + GLOBAL_SWFQ_RWPTR_REG, rptr & (len - 1));
>
> - filled = geth_fill_freeq(geth, false);
> - if (!filled)
> - goto err_freeq_alloc;
> + expected = len - (1 << fpp_order);
> + filled = geth_fill_freeq(geth);
> + if (filled != expected)
> + goto err_freeq_bitmap;
[Severity: Medium]
Can the first page posted here straddle the hardware read pointer?
rptr is the read-only hardware SWFQ read pointer left over from the previous
queue. geth_cleanup_freeq() only sets wptr = rptr, and geth_resize_freeq()
keeps rptr through:
new_order = max_t(unsigned int, new_order, fls(rptr));
If the hardware consumed an odd number of 2K fragments before the resize,
rptr is odd. geth_fill_freeq() then rounds the write pointer down to a page
index:
pn = (rw.bits.wptr >> fpp_order) & m_pn;
geth_freeq_add_page() writes both fragments at freeq_ring + (pn << fpp_order).
So fragment 0 ends up in entry rptr - 1, behind the hardware read pointer.
For example, take len = 16 and rptr = 5:
- Page A goes into entries 4 and 5, and the fill ends at wptr = 2.
- The hardware reads entries 5..15, then 0 and 1.
- A later refill at rptr >= 8 writes page B into entries 4 and 5.
- The fragment 0 address of page A never comes back in an RX descriptor.
geth_freeq_claim() is the only path that releases a slot, and only when
gpage->fragments drops to zero. Does page A then keep its XArray entry, DMA
mapping, page references and freeq_page_bitmap bit until the queue is torn
down?
The old position-indexed code dropped the stale page when that position was
refilled, so this looks new with this patch. The later recycle patch in the
series only recycles pages whose fragments count reaches 0, so the problem
seems to remain at the end of the series.
The check above also counts the fragment that the hardware cannot see:
expected = len - (1 << fpp_order);
So it passes in this case. Is this sentence in the commit message accurate
when rptr is not page aligned?
Require the initial fill to populate every usable
queue entry.
The impact looks bounded to one page and one slot per free queue lifetime.
Later refills always write page-aligned wptr values, and each setup gets a
fresh bitmap. It does use up one slot of the headroom computed by
geth_freeq_page_slots().
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261015-gemini-ethernet-fixes-3-v5-0-b5c9e2f7b8a3%40kernel.org
next prev parent reply other threads:[~2026-10-19 17:28 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 15:24 [PATCH net-next v5 00/14] net: ethernet: cortina: Fix Gemini RX buffer management Linus Walleij
2026-10-15 15:24 ` [PATCH net-next v5 01/14] net: ethernet: cortina: Keep shared free queue parent-owned Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
2026-10-15 15:24 ` [PATCH net-next v5 02/14] net: ethernet: cortina: Keep PHY-less port bound for shared IRQ Linus Walleij
2026-10-15 15:24 ` [PATCH net-next v5 03/14] net: ethernet: cortina: Drain free queue IRQ before resize Linus Walleij
2026-10-15 15:24 ` [PATCH net-next v5 04/14] net: ethernet: cortina: Normalize free queue pointers on rebuild Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
2026-10-15 15:24 ` [PATCH net-next v5 05/14] net: ethernet: cortina: Correct free queue DMA mappings Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
2026-10-15 15:24 ` [PATCH net-next v5 06/14] net: ethernet: cortina: Index free queue fragments with XArray Linus Walleij
2026-10-15 15:24 ` [PATCH net-next v5 07/14] net: ethernet: cortina: Preserve in-flight free queue pages Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko [this message]
2026-10-15 15:24 ` [PATCH net-next v5 08/14] net: ethernet: cortina: Rotate free queue page allocation Linus Walleij
2026-10-15 15:24 ` [PATCH net-next v5 09/14] net: ethernet: cortina: Recycle claimed free queue pages Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
2026-10-15 15:24 ` [PATCH net-next v5 10/14] net: ethernet: cortina: Validate RX fragment lengths Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
2026-10-15 15:24 ` [PATCH net-next v5 11/14] net: ethernet: cortina: Account RX buffer size in truesize Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
2026-10-15 15:24 ` [PATCH net-next v5 12/14] net: ethernet: cortina: Release partial RX frames on stop Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
2026-10-15 15:24 ` [PATCH net-next v5 13/14] net: ethernet: cortina: Scale Gemini RX queues to system memory Linus Walleij
2026-10-15 15:24 ` [PATCH net-next v5 14/14] net: ethernet: cortina: Scope RX statistics updates Linus Walleij
2026-10-19 17:28 ` netdev-bot+sashiko
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=179243092709.3135.17234520297875888006@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=kuba@kernel.org \
--cc=linusw@kernel.org \
--cc=mhun512@gmail.com \
--cc=mirq-linux@rere.qmqm.pl \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=ulli.kroll@googlemail.com \
/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