All of lore.kernel.org
 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 9/9] locking/lockdep: Migrate and compact boot-time dependency graph from __initdata
Date: Mon, 17 Aug 2026 17:45:31 +0000	[thread overview]
Message-ID: <20260817174531.B119D1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260817-folio-pool-v1-v1-9-0c1d230aa3af@gmail.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Invalid Wait Context on PREEMPT_RT and potential buddy allocator recursion.
- [High] Use-After-Free triggered by reading /proc/lockdep after boot compaction failure.
- [High] Permanent memory leak of dynamically allocated lock graph edges on module unload.
- [Medium] Integer underflow in global active edge counter `nr_list_entries`.
--

--- Patch [9]: [PATCH 9/9] locking/lockdep: Migrate and compact boot-time dependency graph from __initdata ---
commit f7e00f7b01be3f305f806e2c70e4d05c87137496
Author: Jim Cromie <jim.cromie@gmail.com>

locking/lockdep: Migrate and compact boot-time dependency graph from __initdata

This commit moves early boot lockdep nodes to __initdata and compacts them
into folio_pool allocations during late_initcall to save memory.

> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 5968a976bf8ea..d9541207b342b 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c

[ ... ]

> @@ -6295,30 +6308,26 @@ static void zap_class(struct pending_free *pf, struct lock_class *class)
>  	list_for_each_entry_safe(entry, tmp, &class->locks_after, entry) {
>  		list_for_each_entry_safe(other, other_tmp, &entry->links_to->locks_before, entry) {
>  			if (other->links_to == class) {
> -				if (is_bootstrap_entry(other))
> -					__clear_bit(other - list_entries, list_entries_in_use);
> +				clear_bootstrap_entry_bit(other);
>  				nr_list_entries--;
>  				list_del_rcu(&other->entry);

[Severity: High]
Does this leak the dynamically allocated edges?

When lock classes are dynamically destroyed during module unload, zap_class()
unlinks their graph edges using list_del_rcu(). With folio_pool allocations,
there is no explicit kfree() or folio_pool_free_obj() called. Discarding the
pointers leaves the memory stranded, leading to a permanent memory leak until
the bump allocator is exhausted.

[ ... ]

> @@ -6733,12 +6745,101 @@ void __init lockdep_init(void)
>  static int __init lockdep_boot_report(void)

[ ... ]

> +static int __init lockdep_compact_boot_graph(void)
> +{
> +	struct lock_class *class;
> +	struct lock_list *entry, *tmp, *new_entry;
> +	unsigned long flags;
> +	unsigned long migrated = 0;

[ ... ]

> +	raw_local_irq_save(flags);
> +	if (!graph_lock()) {
> +		raw_local_irq_restore(flags);
> +		return 0;
> +	}
> +
> +	list_for_each_entry(class, &all_lock_classes, lock_entry) {
> +		list_for_each_entry_safe(entry, tmp, &class->locks_after, entry) {
> +			if (is_bootstrap_entry(entry)) {
> +				if (new_entry) {
> +					*new_entry = *entry;
> +					list_replace_rcu(&entry->entry, &new_entry->entry);
> +					new_entry = NULL;
> +				} else {
> +					struct lock_list *slot;
> +
> +					slot = folio_pool_alloc_type(&lockdep_pool,
> +								     struct lock_list,
> +								     GFP_ATOMIC);

[Severity: High]
Can this cause an invalid wait context panic on PREEMPT_RT?

The folio_pool_alloc_type() function is called here while holding
graph_lock(). Because graph_lock() acquires a raw spinlock with local IRQs
disabled, it cannot safely call into folio_pool_alloc_type().

Internally, folio_pool_alloc_type() acquires a standard spinlock_t, which
maps to a sleepable rt_mutex on PREEMPT_RT. Acquiring a sleeping lock inside
a raw spinlock context violates the wait context rules.

Additionally, if the pre-allocated chunk is exhausted, this could call
folio_alloc(), which takes sleepable MM zone locks and triggers the exact
recursion the pre-allocation was intended to avoid.

> +					if (!slot) {
> +						debug_locks_off_graph_unlock();
> +						raw_local_irq_restore(flags);
> +						pr_err("lockdep: folio chunk exhausted during boot compaction\n");
> +						return -ENOMEM;

[Severity: High]
Could this lead to a use-after-free when reading /proc/lockdep?

If folio_pool_alloc_type() fails, this error path disables lockdep and
aborts. However, the partially migrated dependency graph still contains
pointers to early_list_entries, which resides in the __initdata section.

When free_initmem() later reclaims the __initdata section, these pointers
become dangling.

If /proc/lockdep is read, l_show() unconditionally traverses the
class->locks_after list without checking if debug_locks is enabled, which
would dereference the freed init memory.

[ ... ]

> +		}
> +	}
> +
> +	/* Adjust counter so compaction does not double-count migrated nodes */
> +	nr_list_entries -= migrated;

[Severity: Medium]
Is this subtraction correct?

The compaction loop replaces boot nodes with new allocations directly from
folio_pool without incrementing nr_list_entries. Subtracting migrated from
nr_list_entries here reduces the counter even though the active edge count
remains unchanged.

When these dynamically allocated lock classes are later freed during module
unload, zap_class() unconditionally decrements nr_list_entries--, which will
cause the global counter to underflow.

> +
> +	bootstrap_entries = NULL;

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

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

Thread overview: 32+ 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 ` Jim Cromie
2026-08-17 17:22 ` [PATCH 1/9] lib/folio_pool: Introduce " Jim Cromie via B4 Relay
2026-08-17 17:22   ` Jim Cromie
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:22   ` Jim Cromie
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:22   ` Jim Cromie
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:22   ` Jim Cromie
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:22   ` Jim Cromie
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:22   ` Jim Cromie
2026-08-17 17:36   ` sashiko-bot
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:22   ` Jim Cromie
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:22   ` Jim Cromie
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:22   ` Jim Cromie
2026-08-17 17:45   ` sashiko-bot [this message]
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=20260817174531.B119D1F000E9@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 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.