On Sat, Sep 12, 2026 at 12:04:57AM +0800, Hao Zhang wrote: > From: Hao Zhang <[email protected]> > > bio_set_dev() associates the bio with a blkg through bio_associate_blkg(). > If the blkg lookup misses, blkg_tryget_closest() takes q->queue_lock with > spin_lock_irq() and releases it with spin_unlock_irq(), which > unconditionally enables local interrupts. > > Callers may call bio_set_dev() with interrupts already disabled, e.g. > dm-thin's pool_map() does so while holding pool->lock taken with > spin_lock_irq(). The nested spin_unlock_irq() then enables interrupts > while pool->lock is still held, so an I/O completion softirq can run on > the same CPU, re-acquire pool->lock (thin_endio(), or overwrite_endio() > -> complete_mapping_preparation()) and deadlock. lockdep reports this > as inconsistent SOFTIRQ-ON-W to IN-SOFTIRQ-W usage. > > Commit 3a762de55b4e ("block: save irq state in blkg_lookup_create()") > fixed the same problem while the lock lived in blkg_lookup_create(), but > commit 9327a865e395 ("blk-cgroup: don't nest queue_lock under rcu in > blkg_lookup_create()") moved the locking into blkg_tryget_closest() and > reverted it to spin_lock_irq(). > > Save and restore the caller's IRQ state instead. > > Fixes: 9327a865e395 ("blk-cgroup: don't nest queue_lock under rcu in > blkg_lookup_create()") > Cc: Ming Lei <[email protected]> > Signed-off-by: Hao Zhang <[email protected]>
Acked-by: Tejun Heo <[email protected]> Thanks. -- tejun

