EROFS: Detecting atomic contexts

Sandeep Dhavale dhavale at google.com
Wed Jun 21 06:38:53 AEST 2023


Hi,
I think we are under RCU read lock in the stack at
blk_mq_flush_plug_list+0x2b0/0x354

blk_mq_flush_plug_list calls blk_mq_run_dispatch_ops
which is a macro in block/blk-mq.h

/* run the code block in @dispatch_ops with rcu/srcu read lock held */
#define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops) \
do {                                                            \
        if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) {          \
                struct blk_mq_tag_set *__tag_set = (q)->tag_set; \
                int srcu_idx;                                   \
                                                                \
                might_sleep_if(check_sleep);                    \
                srcu_idx = srcu_read_lock(__tag_set->srcu);     \
                (dispatch_ops);                                 \
                srcu_read_unlock(__tag_set->srcu, srcu_idx);    \
        } else {                                                \
                rcu_read_lock();                                \
                (dispatch_ops);                                 \
                rcu_read_unlock();                              \
        }                                                       \
} while (0)

#define blk_mq_run_dispatch_ops(q, dispatch_ops)                \
        __blk_mq_run_dispatch_ops(q, true, dispatch_ops)        \

As you can see if BLK_MQ_F_BLOCKING is not set then dispatch_ops is
called with rcu_read_lock().

rcu_read_lock()
        __rcu_read_lock()
                rcu_preempt_read_enter()

In rcu_preempt_read_enter() increments the rcu_read_lock_nesting which
is detected later during mutex_lock() as a warning.

Regarding use of !in_task(), that cannot detect rcu_read_lock_nesting
as far as I can tell so that may not be sufficient.

Thanks,
Sandeep.


More information about the Linux-erofs mailing list