* [PATCH] bio: fix kmemleak false positives from percpu bio alloc cache
@ 2026-03-24 9:00 Ming Lei
2026-03-26 13:29 ` Jens Axboe
0 siblings, 1 reply; 3+ messages in thread
From: Ming Lei @ 2026-03-24 9:00 UTC (permalink / raw)
To: Jens Axboe, linux-block; +Cc: Ming Lei, Yi Zhang
When a bio is allocated from the mempool with REQ_ALLOC_CACHE set and
later completed, bio_put() places it into the per-cpu bio_alloc_cache
via bio_put_percpu_cache() instead of freeing it back to the
mempool/slab. The slab allocation remains tracked by kmemleak, but the
only reference to the bio is through the percpu cache's free_list,
which kmemleak fails to trace through percpu memory. This causes
kmemleak to report the cached bios as unreferenced objects.
Use symmetric kmemleak_free()/kmemleak_alloc() calls to properly track
bios across percpu cache transitions:
- bio_put_percpu_cache: call kmemleak_free() when a bio enters the
cache, unregistering it from kmemleak tracking.
- bio_alloc_percpu_cache: call kmemleak_alloc() when a bio is taken
from the cache for reuse, re-registering it so that genuine leaks
of reused bios remain detectable.
- __bio_alloc_cache_prune: call kmemleak_alloc() before bio_free() so
that kmem_cache_free()'s internal kmemleak_free() has a matching
allocation to pair with.
Cc: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/bio.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/block/bio.c b/block/bio.c
index d80d5d26804e..093006e5aba0 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -18,6 +18,7 @@
#include <linux/highmem.h>
#include <linux/blk-crypto.h>
#include <linux/xarray.h>
+#include <linux/kmemleak.h>
#include <trace/events/block.h>
#include "blk.h"
@@ -504,6 +505,9 @@ static struct bio *bio_alloc_percpu_cache(struct block_device *bdev,
cache->nr--;
put_cpu();
+ kmemleak_alloc((void *)bio - bs->front_pad,
+ kmem_cache_size(bs->bio_slab), 1, gfp);
+
if (nr_vecs)
bio_init_inline(bio, bdev, nr_vecs, opf);
else
@@ -765,6 +769,9 @@ static int __bio_alloc_cache_prune(struct bio_alloc_cache *cache,
while ((bio = cache->free_list) != NULL) {
cache->free_list = bio->bi_next;
cache->nr--;
+ kmemleak_alloc((void *)bio - bio->bi_pool->front_pad,
+ kmem_cache_size(bio->bi_pool->bio_slab),
+ 1, GFP_KERNEL);
bio_free(bio);
if (++i == nr)
break;
@@ -828,6 +835,7 @@ static inline void bio_put_percpu_cache(struct bio *bio)
bio->bi_bdev = NULL;
cache->free_list = bio;
cache->nr++;
+ kmemleak_free((void *)bio - bio->bi_pool->front_pad);
} else if (in_hardirq()) {
lockdep_assert_irqs_disabled();
@@ -835,6 +843,7 @@ static inline void bio_put_percpu_cache(struct bio *bio)
bio->bi_next = cache->free_list_irq;
cache->free_list_irq = bio;
cache->nr_irq++;
+ kmemleak_free((void *)bio - bio->bi_pool->front_pad);
} else {
goto out_free;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] bio: fix kmemleak false positives from percpu bio alloc cache
2026-03-24 9:00 [PATCH] bio: fix kmemleak false positives from percpu bio alloc cache Ming Lei
@ 2026-03-26 13:29 ` Jens Axboe
2026-03-26 13:45 ` Ming Lei
0 siblings, 1 reply; 3+ messages in thread
From: Jens Axboe @ 2026-03-26 13:29 UTC (permalink / raw)
To: Ming Lei, linux-block; +Cc: Yi Zhang
On 3/24/26 3:00 AM, Ming Lei wrote:
> When a bio is allocated from the mempool with REQ_ALLOC_CACHE set and
> later completed, bio_put() places it into the per-cpu bio_alloc_cache
> via bio_put_percpu_cache() instead of freeing it back to the
> mempool/slab. The slab allocation remains tracked by kmemleak, but the
> only reference to the bio is through the percpu cache's free_list,
> which kmemleak fails to trace through percpu memory. This causes
> kmemleak to report the cached bios as unreferenced objects.
>
> Use symmetric kmemleak_free()/kmemleak_alloc() calls to properly track
> bios across percpu cache transitions:
>
> - bio_put_percpu_cache: call kmemleak_free() when a bio enters the
> cache, unregistering it from kmemleak tracking.
>
> - bio_alloc_percpu_cache: call kmemleak_alloc() when a bio is taken
> from the cache for reuse, re-registering it so that genuine leaks
> of reused bios remain detectable.
>
> - __bio_alloc_cache_prune: call kmemleak_alloc() before bio_free() so
> that kmem_cache_free()'s internal kmemleak_free() has a matching
> allocation to pair with.
Looks fine to me, but can you please do it against for-7.1/block
instead? It's not a huge issue, and I'd rather not introduce a merge
conflict by shoving it into 7.0 if that can be avoided.
--
Jens Axboe
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] bio: fix kmemleak false positives from percpu bio alloc cache
2026-03-26 13:29 ` Jens Axboe
@ 2026-03-26 13:45 ` Ming Lei
0 siblings, 0 replies; 3+ messages in thread
From: Ming Lei @ 2026-03-26 13:45 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block, Yi Zhang
On Thu, Mar 26, 2026 at 9:29 PM Jens Axboe <axboe@kernel.dk> wrote:
>
> On 3/24/26 3:00 AM, Ming Lei wrote:
> > When a bio is allocated from the mempool with REQ_ALLOC_CACHE set and
> > later completed, bio_put() places it into the per-cpu bio_alloc_cache
> > via bio_put_percpu_cache() instead of freeing it back to the
> > mempool/slab. The slab allocation remains tracked by kmemleak, but the
> > only reference to the bio is through the percpu cache's free_list,
> > which kmemleak fails to trace through percpu memory. This causes
> > kmemleak to report the cached bios as unreferenced objects.
> >
> > Use symmetric kmemleak_free()/kmemleak_alloc() calls to properly track
> > bios across percpu cache transitions:
> >
> > - bio_put_percpu_cache: call kmemleak_free() when a bio enters the
> > cache, unregistering it from kmemleak tracking.
> >
> > - bio_alloc_percpu_cache: call kmemleak_alloc() when a bio is taken
> > from the cache for reuse, re-registering it so that genuine leaks
> > of reused bios remain detectable.
> >
> > - __bio_alloc_cache_prune: call kmemleak_alloc() before bio_free() so
> > that kmem_cache_free()'s internal kmemleak_free() has a matching
> > allocation to pair with.
>
> Looks fine to me, but can you please do it against for-7.1/block
> instead? It's not a huge issue, and I'd rather not introduce a merge
> conflict by shoving it into 7.0 if that can be avoided.
Sure, will send v2 against for-7.1.
Thanks
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-03-26 13:45 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-24 9:00 [PATCH] bio: fix kmemleak false positives from percpu bio alloc cache Ming Lei
2026-03-26 13:29 ` Jens Axboe
2026-03-26 13:45 ` Ming Lei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox