From: sashiko-bot@kernel.org
To: "Vlastimil Babka (SUSE)" <vbabka@kernel.org>
Cc: media-ci@linuxtv.org, bpf@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev,
dri-devel@lists.freedesktop.org
Subject: Re: [PATCH RFC 4/5] mm/slab: handle large_kmalloc objects in kfree_nolock()
Date: Fri, 07 Aug 2026 15:06:09 +0000 [thread overview]
Message-ID: <20260807150609.CDED21F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260807-kfree_nolock_kmalloc-v1-4-ba993cbf7a60@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Synchronous execution of __free_large_kmalloc_page in kfree_nolock() violates NMI wait-context and corrupts vmstat counters
- [High] Deferred clearing of PageLargeKmalloc bypasses double-free protection, causing infinite loops
--
--- Patch [4]: [PATCH RFC 4/5] mm/slab: handle large_kmalloc objects in kfree_nolock() ---
commit 9af1d6506b418b2d9de0922f293e12ee55babdd3
Author: Vlastimil Babka (SUSE) <vbabka@kernel.org>
mm/slab: handle large_kmalloc objects in kfree_nolock()
Large kmalloc objects is the only remaining case that kfree_nolock()
cannot handle from kmalloc() allocations. Note kmalloc_nolock() does not
return large kmalloc objects.
> diff --git a/mm/slub.c b/mm/slub.c
> index 423b5bdb910bd..3be98faa9f0de 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
[ ... ]
> @@ -6365,6 +6367,21 @@ static void free_to_pcs_bulk(struct kmem_cache *s, size_t size, void **p)
> }
> }
>
> +static inline void
> +__free_large_kmalloc_page(struct page *page, unsigned int free_flags)
> +{
> + unsigned int order = compound_order(page);
> +
> + mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B,
> + -(PAGE_SIZE << order));
> + __ClearPageLargeKmalloc(page);
> +
> + if (free_flags & SLAB_FREE_NOLOCK)
> + free_frozen_pages_nolock(page, order);
[Severity: High]
Is it safe to execute this synchronously in NMI context on PREEMPT_RT kernels?
When kmemleak is disabled, kmemleak_may_need_free() returns false, which
causes free_large_kmalloc() to call __free_large_kmalloc_page() synchronously
from kfree_nolock(), even in NMI context.
This results in free_frozen_pages_nolock() attempting to acquire the zone
lock, which is an rt_mutex (sleeping lock) on PREEMPT_RT, leading to a panic
when called from NMI.
Additionally, mod_lruvec_page_state() uses a non-atomic read-modify-write
protected by local_irq_save() on architectures without
CONFIG_HAVE_CMPXCHG_LOCAL. This fails to mask NMIs and can silently corrupt
vmstat counters.
Would it be better to always defer freeing large kmalloc pages in
kfree_nolock() to avoid these issues?
> + else
> + free_frozen_pages(page, order);
> +}
> +
[ ... ]
> @@ -6712,9 +6756,11 @@ size_t ksize(const void *objp)
> }
> EXPORT_SYMBOL(ksize);
>
> -static void free_large_kmalloc(struct page *page, void *object)
> +static void free_large_kmalloc(struct page *page, void *object,
> + unsigned int free_flags)
> {
> unsigned int order = compound_order(page);
> + bool nolock = free_flags & SLAB_FREE_NOLOCK;
>
> if (WARN_ON_ONCE(!PageLargeKmalloc(page))) {
> dump_page(page, "Not a kmalloc allocation");
> @@ -6724,14 +6770,16 @@ static void free_large_kmalloc(struct page *page, void *object)
> if (WARN_ON_ONCE(order == 0))
> pr_warn_once("object pointer: 0x%p\n", object);
>
> - kmemleak_free(object);
> + if (!nolock)
> + kmemleak_free(object);
> +
> kasan_kfree_large(object);
> kmsan_kfree_large(object);
>
> - mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B,
> - -(PAGE_SIZE << order));
> - __ClearPageLargeKmalloc(page);
> - free_frozen_pages(page, order);
> + if (unlikely(nolock && kmemleak_may_need_free(object)))
> + defer_free_large_kmalloc(object);
[Severity: High]
Could moving the __ClearPageLargeKmalloc() call to the asynchronous
__free_large_kmalloc_page() bypass double-free protection?
When a free is deferred via defer_free_large_kmalloc(), the PageLargeKmalloc
flag remains set until the IRQ work executes. If the caller has a double-free
bug and kfree_nolock() is called again on the same object during this window,
the WARN_ON_ONCE(!PageLargeKmalloc(page)) check at the start of
free_large_kmalloc() will pass.
This allows the second free to proceed and call defer_free_large_kmalloc()
again. Since this uses llist_add() with the same llnode, it creates a circular
linked list (llnode->next = llnode). When deferred_percpu_work_fn() later
processes this list with llist_for_each_safe(), it will loop infinitely and
cause a hard lockup.
> + else
> + __free_large_kmalloc_page(page, free_flags);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260807-kfree_nolock_kmalloc-v1-0-ba993cbf7a60@kernel.org?part=4
next prev parent reply other threads:[~2026-08-07 15:06 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 13:50 [PATCH RFC 0/5] allow kfree_nolock() handle kmalloc() objects Vlastimil Babka (SUSE)
2026-08-07 13:50 ` [PATCH RFC 1/5] mm/slab: cleanup deferred free handling Vlastimil Babka (SUSE)
2026-08-07 13:50 ` [PATCH RFC 2/5] mm/slab, kfence: support kfence objects in kfree_nolock() Vlastimil Babka (SUSE)
2026-08-07 14:16 ` sashiko-bot
2026-08-07 13:50 ` [PATCH RFC 3/5] mm/slab, kmemleak: handle kmemleak freeing " Vlastimil Babka (SUSE)
2026-08-07 13:50 ` [PATCH RFC 4/5] mm/slab: handle large_kmalloc objects " Vlastimil Babka (SUSE)
2026-08-07 15:06 ` sashiko-bot [this message]
2026-08-07 13:50 ` [PATCH RFC 5/5] sched: use kfree_nolock() instead of kfree_rcu() Vlastimil Babka (SUSE)
2026-08-07 15:22 ` sashiko-bot
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=20260807150609.CDED21F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=media-ci@linuxtv.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vbabka@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.