BPF List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jim Cromie" <jim.cromie@gmail.com>
Cc: bpf@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 6/9] locking/lockdep: Fallback to folio_pool in alloc_list_entry when static pool is full
Date: Mon, 17 Aug 2026 17:36:14 +0000	[thread overview]
Message-ID: <20260817173614.C59EE1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260817-folio-pool-v1-v1-6-0c1d230aa3af@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Atomic context violation and RT-deadlock in lockdep dynamic allocation.
- [High] Use-After-Free and memory leak due to untracked dynamic lock dependencies.
- [Low] Undefined behavior in pointer arithmetic for dynamically allocated lock entries.
--

--- Patch [6]: [PATCH 6/9] locking/lockdep: Fallback to folio_pool in alloc_list_entry when static pool is full ---
commit 618b3b19dc7c789afe3ea0f17bf4c674f06ef1f3
Author: Jim Cromie <jim.cromie@gmail.com>

locking/lockdep: Fallback to folio_pool in alloc_list_entry when static pool is full

Use struct folio_pool to dynamically expand lock dependency storage when
the static list_entries pool is exhausted, avoiding premature lockdep
disabling.

> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 2d4c5bab5af88..f0f58db090fff 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
[ ... ]
> @@ -1404,11 +1429,19 @@ static struct lock_list *alloc_list_entry(void)
>  				      ARRAY_SIZE(list_entries));
>  
>  	if (idx >= ARRAY_SIZE(list_entries)) {
> +		struct lock_list *p;
> +
> +		p = folio_pool_alloc_type(&lockdep_pool, struct lock_list,
> +					  GFP_ATOMIC);

[Severity: High]
Does dynamically allocating via folio_pool while holding a raw spinlock
violate atomic context rules?

alloc_list_entry() is called by add_lock_to_list() during lockdep graph updates,
which always run under the raw lockdep_lock (via graph_lock()).

Even with GFP_ATOMIC, folio_pool_alloc_type() acquires a standard spinlock_t
(sp->lock) and can call into the page allocator. On PREEMPT_RT, acquiring a
sleepable spinlock_t or calling the page allocator from within a raw spinlock
section causes a kernel panic (sleeping in atomic context). On non-RT kernels,
calling the allocator inside lockdep's graph lock violates its strict
non-reentrancy rules, which risks deadlocks if the allocator triggers warnings
or console output.

> +		if (p) {
> +			nr_list_entries++;
> +			return p;
> +		}

[Severity: High]
Could these dynamically allocated lock entries cause a use-after-free and
memory leak when modules are unloaded?

Dynamically allocated dependencies are not tracked in the list_entries_in_use
bitmap.

When a module is unloaded, zap_class() unlinks dependencies:

kernel/locking/lockdep.c:zap_class() {
    ...
	for_each_set_bit(i, list_entries_in_use, ARRAY_SIZE(list_entries)) {
		entry = list_entries + i;
		if (entry->class != class && entry->links_to != class)
			continue;
		__clear_bit(i, list_entries_in_use);
		nr_list_entries--;
		list_del_rcu(&entry->entry);
	}
    ...
}

Because dynamic entries aren't in this bitmap, zap_class() will skip them
and fail to unlink them from class->locks_after and class->locks_before.
When the module's memory is freed, lockdep retains dangling pointers to
the module's lock structures. Furthermore, the folio_pool bump allocator
does not support freeing individual elements, making the leaked
dependencies permanently unrecoverable.

[Severity: Low]
Could this result in undefined behavior when logging lock errors?

When lockdep detects a structural mismatch, it prints an error using pointer
subtraction:

kernel/locking/lockdep.c:class_lock_list_valid() {
    ...
	list_for_each_entry(e, h, entry) {
		if (e->links_to != c) {
			printk(KERN_INFO "class %s: mismatch for lock entry %ld; class %s <> %s",
			       c->name ? : "(?)",
			       (unsigned long)(e - list_entries),
    ...
}

If the entry e was dynamically allocated via folio_pool, it does not reside
within the static list_entries array. Subtracting pointers from different
memory objects is undefined behavior and produces a nonsensical array
index in the log.

>  		if (!debug_locks_off_graph_unlock())
>  			return NULL;
>  
>  		nbcon_cpu_emergency_enter();
> -		print_lockdep_off("BUG: MAX_LOCKDEP_ENTRIES too low!");
> +		print_lockdep_off("BUG: MAX_LOCKDEP_ENTRIES too low and folio_pool exhausted!");
>  		dump_stack();
>  		nbcon_cpu_emergency_exit();
>  		return NULL;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260817-folio-pool-v1-v1-0-0c1d230aa3af@gmail.com?part=6

  reply	other threads:[~2026-08-17 17:36 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 17:22 [PATCH 0/9] lib/folio_pool: Direct-Map Large Folio Pool & Scratchpad bump allocators Jim Cromie via B4 Relay
2026-08-17 17:22 ` [PATCH 1/9] lib/folio_pool: Introduce " Jim Cromie via B4 Relay
2026-08-17 17:33   ` sashiko-bot
2026-08-17 17:22 ` [PATCH 2/9] netfilter/nf_tables: Add folio_scratchpad collector to struct nftables_pernet Jim Cromie via B4 Relay
2026-08-17 17:35   ` sashiko-bot
2026-08-17 17:22 ` [PATCH 3/9] bpf/verifier: Route verifier stack state node allocations to folio_pool Jim Cromie via B4 Relay
2026-08-17 17:35   ` sashiko-bot
2026-08-17 17:22 ` [PATCH 4/9] drm/gpuvm: Route gpuva_op allocations to folio_scratchpad Jim Cromie via B4 Relay
2026-08-17 17:31   ` sashiko-bot
2026-08-17 17:22 ` [PATCH 5/9] bpf/syscall: Route generic_map_update_batch key/value " Jim Cromie via B4 Relay
2026-08-17 17:32   ` sashiko-bot
2026-08-17 17:22 ` [PATCH 6/9] locking/lockdep: Fallback to folio_pool in alloc_list_entry when static pool is full Jim Cromie via B4 Relay
2026-08-17 17:36   ` sashiko-bot [this message]
2026-08-17 21:01   ` Peter Zijlstra
2026-08-17 17:22 ` [PATCH 7/9] locking/lockdep: Traverse adjacency lists directly in zap_class() Jim Cromie via B4 Relay
2026-08-17 17:39   ` sashiko-bot
2026-08-17 17:22 ` [PATCH 8/9] locking/lockdep: Shrink static list_entries array to early bootstrap buffer Jim Cromie via B4 Relay
2026-08-17 17:52   ` sashiko-bot
2026-08-17 17:22 ` [PATCH 9/9] locking/lockdep: Migrate and compact boot-time dependency graph from __initdata Jim Cromie via B4 Relay
2026-08-17 17:45   ` sashiko-bot
2026-08-17 18:17 ` [PATCH 0/9] lib/folio_pool: Direct-Map Large Folio Pool & Scratchpad bump allocators David Hildenbrand (Arm)
2026-08-17 18:34 ` Matthew Wilcox

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=20260817173614.C59EE1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jim.cromie@gmail.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /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