DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net/gve: fix redundant comparison of qpl_bufs with null
@ 2026-09-25 13:16 Konyukhov Aleksandr
  2026-09-26 16:58 ` Stephen Hemminger
  0 siblings, 1 reply; 2+ messages in thread
From: Konyukhov Aleksandr @ 2026-09-25 13:16 UTC (permalink / raw)
  To: Jeroen de Borst, Rushil Gupta, Joshua Washington,
	Praveen Kaligineedi
  Cc: dev, stable, Konyukhov Aleksandr

Memory allocation for qpl->mz and qpl->qpl_bufs occurs in the
gve_alloc_queue_page_list() function under the condition
if(is_rx) qpl_bufs = rte_zmalloc else mz = gve_alloc_using_mz.
Accordingly, if qpl->mz == NULL, then memory allocation
for qpl->qpl_bufs definitely occurred. That is, in line
gve_ethdev.c:127, an additional check if (qpl->qpl_bufs)
is not required.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 9873a135bfba ("net/gve: allocate Rx QPL pages using malloc")
Cc: pkaligineedi@google.com

Signed-off-by: Konyukhov Aleksandr <Alexander.Konyukhov@kaspersky.com>
---
 drivers/net/gve/gve_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index 3596a0236d..b72359a9af 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -124,7 +124,7 @@ gve_free_queue_page_list(struct gve_queue_page_list *qpl)
 	if (qpl->mz) {
 		rte_memzone_free(qpl->mz);
 		qpl->mz = NULL;
-	} else if (qpl->qpl_bufs) {
+	} else {
 		uint32_t i;
 
 		for (i = 0; i < qpl->num_entries; i++)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] net/gve: fix redundant comparison of qpl_bufs with null
  2026-09-25 13:16 [PATCH] net/gve: fix redundant comparison of qpl_bufs with null Konyukhov Aleksandr
@ 2026-09-26 16:58 ` Stephen Hemminger
  0 siblings, 0 replies; 2+ messages in thread
From: Stephen Hemminger @ 2026-09-26 16:58 UTC (permalink / raw)
  To: Konyukhov Aleksandr
  Cc: Jeroen de Borst, Rushil Gupta, Joshua Washington,
	Praveen Kaligineedi, dev, stable

On Fri, 25 Sep 2026 16:16:41 +0300
Konyukhov Aleksandr <Alexander.Konyukhov@kaspersky.com> wrote:

> Memory allocation for qpl->mz and qpl->qpl_bufs occurs in the
> gve_alloc_queue_page_list() function under the condition
> if(is_rx) qpl_bufs = rte_zmalloc else mz = gve_alloc_using_mz.
> Accordingly, if qpl->mz == NULL, then memory allocation
> for qpl->qpl_bufs definitely occurred. That is, in line
> gve_ethdev.c:127, an additional check if (qpl->qpl_bufs)
> is not required.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: 9873a135bfba ("net/gve: allocate Rx QPL pages using malloc")
> Cc: pkaligineedi@google.com
> 
> Signed-off-by: Konyukhov Aleksandr <Alexander.Konyukhov@kaspersky.com>
> ---

NAK

AI review with better tooling finds this patch is bogus.

Review: [PATCH] net/gve: fix redundant comparison of qpl_bufs with null
Patchwork 170040

Error
-----

The premise of the patch is wrong. mz and qpl_bufs are members of an
anonymous union in struct gve_queue_page_list (gve_ethdev.h:76):

	union {
		const struct rte_memzone *mz; /* memzone allocated for TX queue */
		void **qpl_bufs; /* RX qpl-buffer list allocated using malloc*/
	};

They are the same word. That is what SVACE is reporting: in the else
branch qpl->mz == NULL already means qpl->qpl_bufs == NULL, so the
test is always false. The commit message has this backwards; the
allocation logic in gve_alloc_queue_page_list() is not what makes the
comparison redundant.

After the patch:

	} else {
		uint32_t i;

		for (i = 0; i < qpl->num_entries; i++)
			rte_free(qpl->qpl_bufs[i]);

qpl->qpl_bufs is NULL in that branch, so every iteration dereferences
NULL. The branch is unreachable today (a successful alloc always leaves
the union non-NULL), so runtime behaviour is unchanged, but the patch
codifies a wrong reading of the struct and leaves the real bug in place
(see Info). Not a fix. Should be replaced by the union removal below.

Warning
-------

Fixes: 9873a135bfba does not exist in the upstream tree. The commit
"net/gve: allocate Rx QPL pages using malloc" is a71168a775e6 (v25.03).
Cc: stable@dpdk.org is on the mail but not in the commit body.

Info (pre-existing, introduced by a71168a775e6, not by this patch)
------------------------------------------------------------------

Because of the union, gve_free_queue_page_list() never frees Rx pages.
For an Rx QPL, qpl_bufs is non-NULL, so qpl->mz reads non-NULL and the
first branch runs:

	if (qpl->mz) {
		rte_memzone_free(qpl->mz);
		qpl->mz = NULL;

rte_memzone_free() is handed the rte_zmalloc'd pointer array;
rte_fbarray_find_idx() rejects it, the call returns -EINVAL (ignored),
and qpl->mz = NULL also clears qpl_bufs. The following
if (qpl->qpl_bufs) is then false. Every 4K page from
gve_alloc_using_malloc() and the qpl_bufs array itself leak on each Rx
queue release / teardown, and the per-page free loop is dead code.

Fix is to drop the union so the two pointers are independent:

	dma_addr_t *page_buses; /* the dma addrs of the pages */
	const struct rte_memzone *mz; /* Tx: memzone backing the pages */
	void **qpl_bufs;              /* Rx: per-page buffers from rte_malloc */

and simplify the free path:

	if (qpl->mz) {
		rte_memzone_free(qpl->mz);
		qpl->mz = NULL;
	}
	if (qpl->qpl_bufs) {
		for (i = 0; i < qpl->num_entries; i++)
			rte_free(qpl->qpl_bufs[i]);
		rte_free(qpl->qpl_bufs);
		qpl->qpl_bufs = NULL;
	}

Costs 8 bytes per QPL. That fix is the one that should carry the
Fixes: a71168a775e6 tag and Cc: stable@dpdk.org, since v25.03 and later
leak Rx QPL memory.

Review-Result: ERROR

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-26 16:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-25 13:16 [PATCH] net/gve: fix redundant comparison of qpl_bufs with null Konyukhov Aleksandr
2026-09-26 16:58 ` Stephen Hemminger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox