Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <yukuai@fnnas.com>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Yu Kuai and committed by
Jens Axboe
65d466b6 9d20fd6c

+24 -7
+24 -7
block/blk-mq-debugfs.c
··· 608 608 {}, 609 609 }; 610 610 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, 612 613 const struct blk_mq_debugfs_attr *attr) 613 614 { 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 + 614 628 if (IS_ERR_OR_NULL(parent)) 615 629 return; 616 630 ··· 638 624 struct blk_mq_hw_ctx *hctx; 639 625 unsigned long i; 640 626 641 - debugfs_create_files(q->debugfs_dir, q, blk_mq_debugfs_queue_attrs); 627 + debugfs_create_files(q, q->debugfs_dir, q, blk_mq_debugfs_queue_attrs); 642 628 643 629 queue_for_each_hw_ctx(q, hctx, i) { 644 630 if (!hctx->debugfs_dir) ··· 657 643 snprintf(name, sizeof(name), "cpu%u", ctx->cpu); 658 644 ctx_dir = debugfs_create_dir(name, hctx->debugfs_dir); 659 645 660 - debugfs_create_files(ctx_dir, ctx, blk_mq_debugfs_ctx_attrs); 646 + debugfs_create_files(hctx->queue, ctx_dir, ctx, 647 + blk_mq_debugfs_ctx_attrs); 661 648 } 662 649 663 650 void blk_mq_debugfs_register_hctx(struct request_queue *q, ··· 674 659 snprintf(name, sizeof(name), "hctx%u", hctx->queue_num); 675 660 hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir); 676 661 677 - debugfs_create_files(hctx->debugfs_dir, hctx, blk_mq_debugfs_hctx_attrs); 662 + debugfs_create_files(q, hctx->debugfs_dir, hctx, 663 + blk_mq_debugfs_hctx_attrs); 678 664 679 665 hctx_for_each_ctx(hctx, ctx, i) 680 666 blk_mq_debugfs_register_ctx(hctx, ctx); ··· 728 712 729 713 q->sched_debugfs_dir = debugfs_create_dir("sched", q->debugfs_dir); 730 714 731 - debugfs_create_files(q->sched_debugfs_dir, q, e->queue_debugfs_attrs); 715 + debugfs_create_files(q, q->sched_debugfs_dir, q, e->queue_debugfs_attrs); 732 716 } 733 717 734 718 void blk_mq_debugfs_unregister_sched(struct request_queue *q) ··· 767 751 q->debugfs_dir); 768 752 769 753 rqos->debugfs_dir = debugfs_create_dir(dir_name, q->rqos_debugfs_dir); 770 - debugfs_create_files(rqos->debugfs_dir, rqos, rqos->ops->debugfs_attrs); 754 + debugfs_create_files(q, rqos->debugfs_dir, rqos, 755 + rqos->ops->debugfs_attrs); 771 756 } 772 757 773 758 void blk_mq_debugfs_register_rq_qos(struct request_queue *q) ··· 805 788 806 789 hctx->sched_debugfs_dir = debugfs_create_dir("sched", 807 790 hctx->debugfs_dir); 808 - debugfs_create_files(hctx->sched_debugfs_dir, hctx, 791 + debugfs_create_files(q, hctx->sched_debugfs_dir, hctx, 809 792 e->hctx_debugfs_attrs); 810 793 } 811 794