On Tue, Jun 20, 2023 at 5:38 PM Gao Xiang <[email protected]> wrote: > > 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()" > I think this looks good. rcu_read_lock_any_held() can detect this.
Thanks, Sandeep. > Or do you have better ideas? > > Thanks, > Gao Xiang > > > > > Thanks, > > Sandeep.
