EROFS: Detecting atomic contexts
Gao Xiang
hsiangkao at linux.alibaba.com
Wed Jun 21 10:38:29 AEST 2023
Hi Sandeep,
On 2023/6/21 04:38, Sandeep Dhavale wrote:
> 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.
Thanks for your analysis. That is much helpful to me.
So it seems a new path which calls end_io under rcu read lock.
>
> Regarding use of !in_task(), that cannot detect rcu_read_lock_nesting
> as far as I can tell so that may not be sufficient.
rcu_preempt_depth is a too low level api, I'm not sure if it's a good
way but we really don't want to trigger another workqueue here,
could we just use:
"!in_task() || irqs_disabled() || rcu_read_lock_any_held()"
Or do you have better ideas?
Thanks,
Gao Xiang
>
> Thanks,
> Sandeep.
More information about the Linux-erofs
mailing list