This reverts commit e8eef69a99f185e75909adb24ab93d706e07bf27. While DO_ONCE_SLEEPABLE() is used from sleepable/process context, callers may still be holding arbitrary subsystem locks. For instance, __inet_hash_connect() uses get_random_sleepable_once() which invokes DO_ONCE_SLEEPABLE() while holding the socket lock (sk_lock): lock_sock(sk) __inet_hash_connect() get_random_sleepable_once() DO_ONCE_SLEEPABLE() __do_once_sleepable_done() static_branch_disable() static_key_disable() cpus_read_lock() Calling static_branch_disable() directly from __do_once_sleepable_done() causes static_key_disable() to synchronously acquire cpus_read_lock() (cpu_hotplug_lock) and jump_label_mutex inside the caller's lock context. This introduces an unwanted lockdep dependency: sk_lock -> cpu_hotplug_lock Because cpu_hotplug_lock depends on fs_reclaim (via workqueue CPU bringup allocating memory with GFP_KERNEL), and storage/block layers (such as NVMe-TCP) acquire sk_lock during I/O dispatch, lockdep reports circular locking dependencies: set->srcu -> sk_lock -> cpu_hotplug_lock -> fs_reclaim -> q_usage_counter -> elevator_lock -> set->srcu This false positive previously prompted commit 19bdb70c77d3 ("nvme-tcp: lockdep: use dynamic lockdep keys per socket instance") to work around the warning using per-socket dynamic keys in NVMe-TCP. That in turn broke asynchronous socket teardown and caused syzbot warnings in tcp_tsq_handler(). Restoring once_disable_jump() in __do_once_sleepable_done() ensures that static_branch_disable() is executed asynchronously from a system workqueue without holding the caller's locks. Fixes: e8eef69a99f1 ("once: don't use a work queue to reset sleepable static key") Cc: stable@vger.kernel.org Closes: https://lore.kernel.org/lkml/ao0mwtt8ePAINFni@shinhome/ Reported-by: Shin'ichiro Kawasaki Signed-off-by: Eric Dumazet Cc: Tony Luck Cc: Reinette Chatre Cc: Keith Busch Cc: Nilay Shroff --- lib/once.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/once.c b/lib/once.c index d801bfa945e6..0a0a919156e0 100644 --- a/lib/once.c +++ b/lib/once.c @@ -93,6 +93,6 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, { *done = true; mutex_unlock(&once_mutex); - static_branch_disable(once_key); + once_disable_jump(once_key, mod); } EXPORT_SYMBOL(__do_once_sleepable_done); base-commit: 66498c75b4f8017f62d720d9b59675bdf3abce91 -- 2.55.0.860.g4b6b3295ed-goog