Skip to content

Commit aef3ed7

Browse files
hailan94kawasaki
authored andcommitted
blk-mq-debugfs: warn about possible deadlock
Creating new debugfs entries can trigger fs reclaim, hence we can't do this with queue frozen, meanwhile, other locks that can be held while queue is frozen should not be held as well. Signed-off-by: Yu Kuai <[email protected]> Reviewed-by: Nilay Shroff <[email protected]> Reviewed-by: Ming Lei <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]>
1 parent 59aae57 commit aef3ed7

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

block/blk-mq-debugfs.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -608,9 +608,23 @@ static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = {
608608
{},
609609
};
610610

611-
static void debugfs_create_files(struct dentry *parent, void *data,
611+
static void debugfs_create_files(struct request_queue *q, struct dentry *parent,
612+
void *data,
612613
const struct blk_mq_debugfs_attr *attr)
613614
{
615+
lockdep_assert_held(&q->debugfs_mutex);
616+
/*
617+
* Creating new debugfs entries with queue freezed has the risk of
618+
* deadlock.
619+
*/
620+
WARN_ON_ONCE(q->mq_freeze_depth != 0);
621+
/*
622+
* debugfs_mutex should not be nested under other locks that can be
623+
* grabbed while queue is frozen.
624+
*/
625+
lockdep_assert_not_held(&q->elevator_lock);
626+
lockdep_assert_not_held(&q->rq_qos_mutex);
627+
614628
if (IS_ERR_OR_NULL(parent))
615629
return;
616630

@@ -624,7 +638,7 @@ void blk_mq_debugfs_register(struct request_queue *q)
624638
struct blk_mq_hw_ctx *hctx;
625639
unsigned long i;
626640

627-
debugfs_create_files(q->debugfs_dir, q, blk_mq_debugfs_queue_attrs);
641+
debugfs_create_files(q, q->debugfs_dir, q, blk_mq_debugfs_queue_attrs);
628642

629643
queue_for_each_hw_ctx(q, hctx, i) {
630644
if (!hctx->debugfs_dir)
@@ -643,7 +657,8 @@ static void blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx,
643657
snprintf(name, sizeof(name), "cpu%u", ctx->cpu);
644658
ctx_dir = debugfs_create_dir(name, hctx->debugfs_dir);
645659

646-
debugfs_create_files(ctx_dir, ctx, blk_mq_debugfs_ctx_attrs);
660+
debugfs_create_files(hctx->queue, ctx_dir, ctx,
661+
blk_mq_debugfs_ctx_attrs);
647662
}
648663

649664
void blk_mq_debugfs_register_hctx(struct request_queue *q,
@@ -659,7 +674,8 @@ void blk_mq_debugfs_register_hctx(struct request_queue *q,
659674
snprintf(name, sizeof(name), "hctx%u", hctx->queue_num);
660675
hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir);
661676

662-
debugfs_create_files(hctx->debugfs_dir, hctx, blk_mq_debugfs_hctx_attrs);
677+
debugfs_create_files(q, hctx->debugfs_dir, hctx,
678+
blk_mq_debugfs_hctx_attrs);
663679

664680
hctx_for_each_ctx(hctx, ctx, i)
665681
blk_mq_debugfs_register_ctx(hctx, ctx);
@@ -712,7 +728,7 @@ void blk_mq_debugfs_register_sched(struct request_queue *q)
712728

713729
q->sched_debugfs_dir = debugfs_create_dir("sched", q->debugfs_dir);
714730

715-
debugfs_create_files(q->sched_debugfs_dir, q, e->queue_debugfs_attrs);
731+
debugfs_create_files(q, q->sched_debugfs_dir, q, e->queue_debugfs_attrs);
716732
}
717733

718734
void blk_mq_debugfs_unregister_sched(struct request_queue *q)
@@ -751,7 +767,8 @@ static void blk_mq_debugfs_register_rqos(struct rq_qos *rqos)
751767
q->debugfs_dir);
752768

753769
rqos->debugfs_dir = debugfs_create_dir(dir_name, q->rqos_debugfs_dir);
754-
debugfs_create_files(rqos->debugfs_dir, rqos, rqos->ops->debugfs_attrs);
770+
debugfs_create_files(q, rqos->debugfs_dir, rqos,
771+
rqos->ops->debugfs_attrs);
755772
}
756773

757774
void blk_mq_debugfs_register_rq_qos(struct request_queue *q)
@@ -788,7 +805,7 @@ void blk_mq_debugfs_register_sched_hctx(struct request_queue *q,
788805

789806
hctx->sched_debugfs_dir = debugfs_create_dir("sched",
790807
hctx->debugfs_dir);
791-
debugfs_create_files(hctx->sched_debugfs_dir, hctx,
808+
debugfs_create_files(q, hctx->sched_debugfs_dir, hctx,
792809
e->hctx_debugfs_attrs);
793810
}
794811

0 commit comments

Comments
 (0)