Skip to contentSkip to conversation

padata: fix lockdep warning in padata_find_next()

PATCH In review Tristan Madani 3 participants 4 messages Nov 2 – Nov 3

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 padata: fix lockdep warning in padata_find_next()

padata_find_next() acquires reorder->lock while the caller padata_reorder() already holds squeue->serial.lock. Both locks are of type struct padata_list and thus share the same lockdep class, which triggers a false positive recursive locking warning even though the two instances always protect different data.

Annotate the inner lock with spin_lock_nested() to tell lockdep about the valid nesting.

Fixes 16295bec6398 ("padata: Generic parallelization/serialization interface")
---
 kernel/padata.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/padata.c +1 -1
index 0d3ea1b68b1f7..2f769ba7dfa99 100644
@@ -253,7 +253,7 @@ static struct padata_priv *padata_find_next(struct parallel_data *pd, int cpu,
 
 	reorder = per_cpu_ptr(pd->reorder_list, cpu);
 
-	spin_lock(&reorder->lock);
+	spin_lock_nested(&reorder->lock, SINGLE_DEPTH_NESTING);
 	if (list_empty(&reorder->list))
 		goto notfound;
 
Signature · 1 line
2.47.3
#1 lore raw
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] padata: redundant spin_lock_nested() in padata_find_next() splits lock class --

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] padata: redundant spin_lock_nested() in padata_find_next() splits lock class --

commit d8de136037d32da1b6bd4096b78d163c014e8d23
Author: Tristan Madani <[email protected]>

padata: fix lockdep warning in padata_find_next()

This commit replaces spin_lock() with spin_lock_nested() in padata_find_next() to annotate acquiring reorder->lock while padata_reorder() holds squeue->serial.lock.

kernel/padata.c static struct padata_priv *padata_find_next(struct parallel_data *pd, int cpu, · line 256

Quoted 10 lines
kernel/padata.c +1 -1
index 5a113c667d4cb..94d7880a001c4 100644
@@ -253,7 +253,7 @@ static struct padata_priv *padata_find_next(struct parallel_data *pd, int cpu,
 
 	reorder = per_cpu_ptr(pd->reorder_list, cpu);
 
-	spin_lock(&reorder->lock);
+	spin_lock_nested(&reorder->lock, SINGLE_DEPTH_NESTING);

[Severity: Medium]
Is this spin_lock_nested() annotation still needed here, and does it split reorder->lock across two lockdep subclasses?

In Linux, spin_lock_init() assigns a lock_class_key per macro expansion site rather than per C struct type. Historically, squeue->serial.lock and reorder->lock shared a lockdep class because both were initialized via a common helper __padata_list_init() (and padata_find_next() was moved inside squeue->serial.lock in commit 71203f68c774 ("padata: Fix list-related race in padata_find_next"), rather than commit 16295bec6398).

However, commit af3852cda347 ("padata: remove __padata_list_init()") removed that helper and initialized the two locks at separate spin_lock_init() call sites in kernel/padata.c:

padata_init_squeues()

	INIT_LIST_HEAD(&squeue->serial.list);
	spin_lock_init(&squeue->serial.lock);

padata_init_reorder_list()

	INIT_LIST_HEAD(&list->list);
	spin_lock_init(&list->lock);

Because squeue->serial.lock and reorder->lock already have distinct lockdep classes, acquiring reorder->lock inside squeue->serial.lock does not trigger a recursive locking warning on current kernels.

Meanwhile, padata_do_serial() acquires the same reorder->lock at the default subclass 0 before calling padata_reorder():

padata_do_serial()

	spin_lock(&reorder->lock);
	...
	spin_unlock(&reorder->lock);

	if (gotit)
		padata_reorder(padata);
			spin_lock(&squeue->serial.lock);
			padata_find_next()
				spin_lock_nested(&reorder->lock, SINGLE_DEPTH_NESTING);

Won't annotating reorder->lock with SINGLE_DEPTH_NESTING in padata_find_next() while padata_do_serial() acquires it at subclass 0 cause lockdep to track the same physical lock as two separate subclasses, hiding lock ordering dependencies between padata_do_serial() and padata_find_next()?

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
#2 lore raw
In reply to Tristan Madani
Quoted 1 line · On Mon, 02 Nov 2026, [email protected] wrote:

[Medium] padata: redundant spin_lock_nested() in padata_find_next() splits lock class

You are right. Commit af3852cda347 ("padata: remove __padata_list_init()") already resolved this by giving squeue->serial.lock and reorder->lock separate lock_class_key via separate spin_lock_init() call sites.

The spin_lock_nested() annotation is redundant and would incorrectly split the subclass.

Please drop this patch.

Thanks,
Tristan

Reviewed-by on v1 1/1
#3 lore raw
In reply to Tristan Madani
Quoted 21 lines · Tristan Madani

padata_find_next() acquires reorder->lock while the caller padata_reorder() already holds squeue->serial.lock. Both locks are of type struct padata_list and thus share the same lockdep class, which triggers a false positive recursive locking warning even though the two instances always protect different data.

Annotate the inner lock with spin_lock_nested() to tell lockdep about the valid nesting.

Fixes 16295bec6398 ("padata: Generic parallelization/serialization interface")

---
kernel/padata.c | 2 +-

1 file changed, 1 insertion(+), 1 deletion(-)
kernel/padata.c +0 -0
index 0d3ea1b68b1f7..2f769ba7dfa99 100644

kernel/padata.c static struct padata_priv *padata_find_next(struct parallel_data *pd, int cpu, · line 256

Quoted 5 lines
kernel/padata.c +1 -1
@@ -253,7 +253,7 @@ static struct padata_priv *padata_find_next(struct parallel_data *pd, int cpu,
 
 	reorder = per_cpu_ptr(pd->reorder_list, cpu);
 
-	spin_lock(&reorder->lock);
+	spin_lock_nested(&reorder->lock, SINGLE_DEPTH_NESTING);

I'll bite.

kernel/padata.c static struct padata_priv *padata_find_next(struct parallel_data *pd, int cpu, · line 259

Quoted 4 lines
kernel/padata.c +0 -0
 	if (list_empty(&reorder->list))
 		goto notfound;
 

--- Thanks!