Kmemleak periodically produces a false positive report that resembles the following: unreferenced object 0xffff0000c105ed08 (size 576): comm "swapper/0", pid 1, jiffies 4294937478 hex dump (first 32 bytes): 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ d8 e7 0a 8b 00 80 ff ff 20 ed 05 c1 00 00 ff ff ........ ....... backtrace (crc 69e99671): kmemleak_alloc+0xb4/0xc4 kmem_cache_alloc_lru+0x1f0/0x244 xas_alloc+0x2a0/0x3a0 xas_expand.constprop.0+0x144/0x4dc xas_create+0x2b0/0x484 xas_store+0x60/0xa00 __xa_alloc+0x194/0x280 __xa_alloc_cyclic+0x104/0x2e0 dev_index_reserve+0xd8/0x18c register_netdevice+0x5e8/0xf90 register_netdev+0x28/0x50 loopback_net_init+0x68/0x114 ops_init+0x90/0x2c0 register_pernet_operations+0x20c/0x554 register_pernet_device+0x3c/0x8c net_dev_init+0x5cc/0x7d8 This transient leak can be traced to xas_shrink(): when the xarray's head is reassigned, kmemleak may have already started scanning the xarray. When this happens, if kmemleak fails to scan the new xa_head before it moves, kmemleak will see it as a leak until the xarray is scanned again. The report can be reproduced by running the xdp_bonding BPF selftest, although it doesn't appear consistently due to the bug's transience. In my testing, the following script has reliably triggered the report in under an hour on a debug kernel with kmemleak enabled, where KSELFTESTS is set to the install path for the kernel selftests: #!/bin/sh set -eu echo 1 >/sys/module/kmemleak/parameters/verbose echo scan=1 >/sys/kernel/debug/kmemleak while :; do $KSELFTESTS/bpf/test_progs -t xdp_bonding done To prevent this false positive report, mark the new xa_head in xas_shrink() as a transient leak. Signed-off-by: Jared Kangas <jkangas@xxxxxxxxxx> --- lib/xarray.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/xarray.c b/lib/xarray.c index 9644b18af18d1..51314fa157b31 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -8,6 +8,7 @@ #include <linux/bitmap.h> #include <linux/export.h> +#include <linux/kmemleak.h> #include <linux/list.h> #include <linux/slab.h> #include <linux/xarray.h> @@ -476,6 +477,7 @@ static void xas_shrink(struct xa_state *xas) break; node = xa_to_node(entry); node->parent = NULL; + kmemleak_transient_leak(node); } } -- 2.49.0