aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2017-05-04 10:17:21 -0400
committerJens Axboe <axboe@fb.com>2017-05-04 10:24:13 -0400
commit9c1051aacde828073dbbab5e8e59c0fc802efa9a (patch)
treec0e06f43aaf1c1fa908ebe2f196d24a0f42992f5
parentd173a25165c124442182f6b21d0c2ec381a0eebe (diff)
blk-mq: untangle debugfs and sysfs
Originally, I tied debugfs registration/unregistration together with sysfs. There's no reason to do this, and it's getting in the way of letting schedulers define their own debugfs attributes. Instead, tie the debugfs registration to the lifetime of the structures themselves. The saner lifetimes mean we can also get rid of the extra mq directory and move everything one level up. I.e., nvme0n1/mq/hctx0/tags is now just nvme0n1/hctx0/tags. Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--block/blk-core.c9
-rw-r--r--block/blk-mq-debugfs.c110
-rw-r--r--block/blk-mq-debugfs.h21
-rw-r--r--block/blk-mq-sysfs.c11
-rw-r--r--block/blk-mq.c7
-rw-r--r--block/blk-sysfs.c2
-rw-r--r--include/linux/blk-mq.h4
-rw-r--r--include/linux/blkdev.h1
8 files changed, 94 insertions, 71 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index acdca6536562..c580b0138a7f 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -40,7 +40,6 @@
40 40
41#include "blk.h" 41#include "blk.h"
42#include "blk-mq.h" 42#include "blk-mq.h"
43#include "blk-mq-debugfs.h"
44#include "blk-mq-sched.h" 43#include "blk-mq-sched.h"
45#include "blk-wbt.h" 44#include "blk-wbt.h"
46 45
@@ -562,13 +561,9 @@ void blk_cleanup_queue(struct request_queue *q)
562 * prevent that q->request_fn() gets invoked after draining finished. 561 * prevent that q->request_fn() gets invoked after draining finished.
563 */ 562 */
564 blk_freeze_queue(q); 563 blk_freeze_queue(q);
565 if (!q->mq_ops) { 564 spin_lock_irq(lock);
566 spin_lock_irq(lock); 565 if (!q->mq_ops)
567 __blk_drain_queue(q, true); 566 __blk_drain_queue(q, true);
568 } else {
569 blk_mq_debugfs_unregister_mq(q);
570 spin_lock_irq(lock);
571 }
572 queue_flag_set(QUEUE_FLAG_DEAD, q); 567 queue_flag_set(QUEUE_FLAG_DEAD, q);
573 spin_unlock_irq(lock); 568 spin_unlock_irq(lock);
574 569
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index 1dc1847b5363..260cf76e0705 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -687,19 +687,46 @@ static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = {
687 {}, 687 {},
688}; 688};
689 689
690static bool debugfs_create_files(struct dentry *parent, void *data,
691 const struct blk_mq_debugfs_attr *attr)
692{
693 d_inode(parent)->i_private = data;
694
695 for (; attr->name; attr++) {
696 if (!debugfs_create_file(attr->name, attr->mode, parent,
697 (void *)attr, &blk_mq_debugfs_fops))
698 return false;
699 }
700 return true;
701}
702
690int blk_mq_debugfs_register(struct request_queue *q) 703int blk_mq_debugfs_register(struct request_queue *q)
691{ 704{
705 struct blk_mq_hw_ctx *hctx;
706 int i;
707
692 if (!blk_debugfs_root) 708 if (!blk_debugfs_root)
693 return -ENOENT; 709 return -ENOENT;
694 710
695 q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), 711 q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent),
696 blk_debugfs_root); 712 blk_debugfs_root);
697 if (!q->debugfs_dir) 713 if (!q->debugfs_dir)
698 goto err; 714 return -ENOMEM;
699 715
700 if (blk_mq_debugfs_register_mq(q)) 716 if (!debugfs_create_files(q->debugfs_dir, q,
717 blk_mq_debugfs_queue_attrs))
701 goto err; 718 goto err;
702 719
720 /*
721 * blk_mq_init_hctx() attempted to do this already, but q->debugfs_dir
722 * didn't exist yet (because we don't know what to name the directory
723 * until the queue is registered to a gendisk).
724 */
725 queue_for_each_hw_ctx(q, hctx, i) {
726 if (!hctx->debugfs_dir && blk_mq_debugfs_register_hctx(q, hctx))
727 goto err;
728 }
729
703 return 0; 730 return 0;
704 731
705err: 732err:
@@ -710,32 +737,17 @@ err:
710void blk_mq_debugfs_unregister(struct request_queue *q) 737void blk_mq_debugfs_unregister(struct request_queue *q)
711{ 738{
712 debugfs_remove_recursive(q->debugfs_dir); 739 debugfs_remove_recursive(q->debugfs_dir);
713 q->mq_debugfs_dir = NULL;
714 q->debugfs_dir = NULL; 740 q->debugfs_dir = NULL;
715} 741}
716 742
717static bool debugfs_create_files(struct dentry *parent, void *data, 743static int blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx,
718 const struct blk_mq_debugfs_attr *attr) 744 struct blk_mq_ctx *ctx)
719{
720 d_inode(parent)->i_private = data;
721
722 for (; attr->name; attr++) {
723 if (!debugfs_create_file(attr->name, attr->mode, parent,
724 (void *)attr, &blk_mq_debugfs_fops))
725 return false;
726 }
727 return true;
728}
729
730static int blk_mq_debugfs_register_ctx(struct request_queue *q,
731 struct blk_mq_ctx *ctx,
732 struct dentry *hctx_dir)
733{ 745{
734 struct dentry *ctx_dir; 746 struct dentry *ctx_dir;
735 char name[20]; 747 char name[20];
736 748
737 snprintf(name, sizeof(name), "cpu%u", ctx->cpu); 749 snprintf(name, sizeof(name), "cpu%u", ctx->cpu);
738 ctx_dir = debugfs_create_dir(name, hctx_dir); 750 ctx_dir = debugfs_create_dir(name, hctx->debugfs_dir);
739 if (!ctx_dir) 751 if (!ctx_dir)
740 return -ENOMEM; 752 return -ENOMEM;
741 753
@@ -745,59 +757,61 @@ static int blk_mq_debugfs_register_ctx(struct request_queue *q,
745 return 0; 757 return 0;
746} 758}
747 759
748static int blk_mq_debugfs_register_hctx(struct request_queue *q, 760int blk_mq_debugfs_register_hctx(struct request_queue *q,
749 struct blk_mq_hw_ctx *hctx) 761 struct blk_mq_hw_ctx *hctx)
750{ 762{
751 struct blk_mq_ctx *ctx; 763 struct blk_mq_ctx *ctx;
752 struct dentry *hctx_dir;
753 char name[20]; 764 char name[20];
754 int i; 765 int i;
755 766
767 if (!q->debugfs_dir)
768 return -ENOENT;
769
756 snprintf(name, sizeof(name), "hctx%u", hctx->queue_num); 770 snprintf(name, sizeof(name), "hctx%u", hctx->queue_num);
757 hctx_dir = debugfs_create_dir(name, q->mq_debugfs_dir); 771 hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir);
758 if (!hctx_dir) 772 if (!hctx->debugfs_dir)
759 return -ENOMEM; 773 return -ENOMEM;
760 774
761 if (!debugfs_create_files(hctx_dir, hctx, blk_mq_debugfs_hctx_attrs)) 775 if (!debugfs_create_files(hctx->debugfs_dir, hctx,
762 return -ENOMEM; 776 blk_mq_debugfs_hctx_attrs))
777 goto err;
763 778
764 hctx_for_each_ctx(hctx, ctx, i) { 779 hctx_for_each_ctx(hctx, ctx, i) {
765 if (blk_mq_debugfs_register_ctx(q, ctx, hctx_dir)) 780 if (blk_mq_debugfs_register_ctx(hctx, ctx))
766 return -ENOMEM; 781 goto err;
767 } 782 }
768 783
769 return 0; 784 return 0;
785
786err:
787 blk_mq_debugfs_unregister_hctx(hctx);
788 return -ENOMEM;
789}
790
791void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
792{
793 debugfs_remove_recursive(hctx->debugfs_dir);
794 hctx->debugfs_dir = NULL;
770} 795}
771 796
772int blk_mq_debugfs_register_mq(struct request_queue *q) 797int blk_mq_debugfs_register_hctxs(struct request_queue *q)
773{ 798{
774 struct blk_mq_hw_ctx *hctx; 799 struct blk_mq_hw_ctx *hctx;
775 int i; 800 int i;
776 801
777 if (!q->debugfs_dir)
778 return -ENOENT;
779
780 q->mq_debugfs_dir = debugfs_create_dir("mq", q->debugfs_dir);
781 if (!q->mq_debugfs_dir)
782 goto err;
783
784 if (!debugfs_create_files(q->mq_debugfs_dir, q, blk_mq_debugfs_queue_attrs))
785 goto err;
786
787 queue_for_each_hw_ctx(q, hctx, i) { 802 queue_for_each_hw_ctx(q, hctx, i) {
788 if (blk_mq_debugfs_register_hctx(q, hctx)) 803 if (blk_mq_debugfs_register_hctx(q, hctx))
789 goto err; 804 return -ENOMEM;
790 } 805 }
791 806
792 return 0; 807 return 0;
793
794err:
795 blk_mq_debugfs_unregister_mq(q);
796 return -ENOMEM;
797} 808}
798 809
799void blk_mq_debugfs_unregister_mq(struct request_queue *q) 810void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
800{ 811{
801 debugfs_remove_recursive(q->mq_debugfs_dir); 812 struct blk_mq_hw_ctx *hctx;
802 q->mq_debugfs_dir = NULL; 813 int i;
814
815 queue_for_each_hw_ctx(q, hctx, i)
816 blk_mq_debugfs_unregister_hctx(hctx);
803} 817}
diff --git a/block/blk-mq-debugfs.h b/block/blk-mq-debugfs.h
index 00b0f71d0ae9..596e9b16d3d1 100644
--- a/block/blk-mq-debugfs.h
+++ b/block/blk-mq-debugfs.h
@@ -4,8 +4,11 @@
4#ifdef CONFIG_BLK_DEBUG_FS 4#ifdef CONFIG_BLK_DEBUG_FS
5int blk_mq_debugfs_register(struct request_queue *q); 5int blk_mq_debugfs_register(struct request_queue *q);
6void blk_mq_debugfs_unregister(struct request_queue *q); 6void blk_mq_debugfs_unregister(struct request_queue *q);
7int blk_mq_debugfs_register_mq(struct request_queue *q); 7int blk_mq_debugfs_register_hctx(struct request_queue *q,
8void blk_mq_debugfs_unregister_mq(struct request_queue *q); 8 struct blk_mq_hw_ctx *hctx);
9void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx);
10int blk_mq_debugfs_register_hctxs(struct request_queue *q);
11void blk_mq_debugfs_unregister_hctxs(struct request_queue *q);
9#else 12#else
10static inline int blk_mq_debugfs_register(struct request_queue *q) 13static inline int blk_mq_debugfs_register(struct request_queue *q)
11{ 14{
@@ -16,12 +19,22 @@ static inline void blk_mq_debugfs_unregister(struct request_queue *q)
16{ 19{
17} 20}
18 21
19static inline int blk_mq_debugfs_register_mq(struct request_queue *q) 22static inline int blk_mq_debugfs_register_hctx(struct request_queue *q,
23 struct blk_mq_hw_ctx *hctx)
20{ 24{
21 return 0; 25 return 0;
22} 26}
23 27
24static inline void blk_mq_debugfs_unregister_mq(struct request_queue *q) 28static inline void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
29{
30}
31
32static inline int blk_mq_debugfs_register_hctxs(struct request_queue *q)
33{
34 return 0;
35}
36
37static inline void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
25{ 38{
26} 39}
27#endif 40#endif
diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
index 71a237a90d43..79969c3c234f 100644
--- a/block/blk-mq-sysfs.c
+++ b/block/blk-mq-sysfs.c
@@ -11,7 +11,6 @@
11 11
12#include <linux/blk-mq.h> 12#include <linux/blk-mq.h>
13#include "blk-mq.h" 13#include "blk-mq.h"
14#include "blk-mq-debugfs.h"
15#include "blk-mq-tag.h" 14#include "blk-mq-tag.h"
16 15
17static void blk_mq_sysfs_release(struct kobject *kobj) 16static void blk_mq_sysfs_release(struct kobject *kobj)
@@ -259,8 +258,6 @@ static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
259 queue_for_each_hw_ctx(q, hctx, i) 258 queue_for_each_hw_ctx(q, hctx, i)
260 blk_mq_unregister_hctx(hctx); 259 blk_mq_unregister_hctx(hctx);
261 260
262 blk_mq_debugfs_unregister_mq(q);
263
264 kobject_uevent(&q->mq_kobj, KOBJ_REMOVE); 261 kobject_uevent(&q->mq_kobj, KOBJ_REMOVE);
265 kobject_del(&q->mq_kobj); 262 kobject_del(&q->mq_kobj);
266 kobject_put(&dev->kobj); 263 kobject_put(&dev->kobj);
@@ -319,8 +316,6 @@ int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
319 316
320 kobject_uevent(&q->mq_kobj, KOBJ_ADD); 317 kobject_uevent(&q->mq_kobj, KOBJ_ADD);
321 318
322 blk_mq_debugfs_register(q);
323
324 queue_for_each_hw_ctx(q, hctx, i) { 319 queue_for_each_hw_ctx(q, hctx, i) {
325 ret = blk_mq_register_hctx(hctx); 320 ret = blk_mq_register_hctx(hctx);
326 if (ret) 321 if (ret)
@@ -336,8 +331,6 @@ unreg:
336 while (--i >= 0) 331 while (--i >= 0)
337 blk_mq_unregister_hctx(q->queue_hw_ctx[i]); 332 blk_mq_unregister_hctx(q->queue_hw_ctx[i]);
338 333
339 blk_mq_debugfs_unregister_mq(q);
340
341 kobject_uevent(&q->mq_kobj, KOBJ_REMOVE); 334 kobject_uevent(&q->mq_kobj, KOBJ_REMOVE);
342 kobject_del(&q->mq_kobj); 335 kobject_del(&q->mq_kobj);
343 kobject_put(&dev->kobj); 336 kobject_put(&dev->kobj);
@@ -365,8 +358,6 @@ void blk_mq_sysfs_unregister(struct request_queue *q)
365 if (!q->mq_sysfs_init_done) 358 if (!q->mq_sysfs_init_done)
366 goto unlock; 359 goto unlock;
367 360
368 blk_mq_debugfs_unregister_mq(q);
369
370 queue_for_each_hw_ctx(q, hctx, i) 361 queue_for_each_hw_ctx(q, hctx, i)
371 blk_mq_unregister_hctx(hctx); 362 blk_mq_unregister_hctx(hctx);
372 363
@@ -383,8 +374,6 @@ int blk_mq_sysfs_register(struct request_queue *q)
383 if (!q->mq_sysfs_init_done) 374 if (!q->mq_sysfs_init_done)
384 goto unlock; 375 goto unlock;
385 376
386 blk_mq_debugfs_register_mq(q);
387
388 queue_for_each_hw_ctx(q, hctx, i) { 377 queue_for_each_hw_ctx(q, hctx, i) {
389 ret = blk_mq_register_hctx(hctx); 378 ret = blk_mq_register_hctx(hctx);
390 if (ret) 379 if (ret)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 03a747105682..5d4ce7eb8dbf 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -31,6 +31,7 @@
31#include <linux/blk-mq.h> 31#include <linux/blk-mq.h>
32#include "blk.h" 32#include "blk.h"
33#include "blk-mq.h" 33#include "blk-mq.h"
34#include "blk-mq-debugfs.h"
34#include "blk-mq-tag.h" 35#include "blk-mq-tag.h"
35#include "blk-stat.h" 36#include "blk-stat.h"
36#include "blk-wbt.h" 37#include "blk-wbt.h"
@@ -1862,6 +1863,8 @@ static void blk_mq_exit_hctx(struct request_queue *q,
1862 struct blk_mq_tag_set *set, 1863 struct blk_mq_tag_set *set,
1863 struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) 1864 struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx)
1864{ 1865{
1866 blk_mq_debugfs_unregister_hctx(hctx);
1867
1865 blk_mq_tag_idle(hctx); 1868 blk_mq_tag_idle(hctx);
1866 1869
1867 if (set->ops->exit_request) 1870 if (set->ops->exit_request)
@@ -1948,6 +1951,8 @@ static int blk_mq_init_hctx(struct request_queue *q,
1948 if (hctx->flags & BLK_MQ_F_BLOCKING) 1951 if (hctx->flags & BLK_MQ_F_BLOCKING)
1949 init_srcu_struct(&hctx->queue_rq_srcu); 1952 init_srcu_struct(&hctx->queue_rq_srcu);
1950 1953
1954 blk_mq_debugfs_register_hctx(q, hctx);
1955
1951 return 0; 1956 return 0;
1952 1957
1953 free_fq: 1958 free_fq:
@@ -2385,6 +2390,7 @@ static void blk_mq_queue_reinit(struct request_queue *q,
2385{ 2390{
2386 WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth)); 2391 WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth));
2387 2392
2393 blk_mq_debugfs_unregister_hctxs(q);
2388 blk_mq_sysfs_unregister(q); 2394 blk_mq_sysfs_unregister(q);
2389 2395
2390 /* 2396 /*
@@ -2396,6 +2402,7 @@ static void blk_mq_queue_reinit(struct request_queue *q,
2396 blk_mq_map_swqueue(q, online_mask); 2402 blk_mq_map_swqueue(q, online_mask);
2397 2403
2398 blk_mq_sysfs_register(q); 2404 blk_mq_sysfs_register(q);
2405 blk_mq_debugfs_register_hctxs(q);
2399} 2406}
2400 2407
2401/* 2408/*
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 9995355121d7..504fee940052 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -890,6 +890,8 @@ int blk_register_queue(struct gendisk *disk)
890 if (q->mq_ops) 890 if (q->mq_ops)
891 __blk_mq_register_dev(dev, q); 891 __blk_mq_register_dev(dev, q);
892 892
893 blk_mq_debugfs_register(q);
894
893 kobject_uevent(&q->kobj, KOBJ_ADD); 895 kobject_uevent(&q->kobj, KOBJ_ADD);
894 896
895 wbt_enable_default(q); 897 wbt_enable_default(q);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index a104832e7ae5..de8ed9aaa156 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -57,6 +57,10 @@ struct blk_mq_hw_ctx {
57 unsigned long poll_considered; 57 unsigned long poll_considered;
58 unsigned long poll_invoked; 58 unsigned long poll_invoked;
59 unsigned long poll_success; 59 unsigned long poll_success;
60
61#ifdef CONFIG_BLK_DEBUG_FS
62 struct dentry *debugfs_dir;
63#endif
60}; 64};
61 65
62struct blk_mq_tag_set { 66struct blk_mq_tag_set {
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 83d28623645f..b49a79a29e58 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -579,7 +579,6 @@ struct request_queue {
579 579
580#ifdef CONFIG_BLK_DEBUG_FS 580#ifdef CONFIG_BLK_DEBUG_FS
581 struct dentry *debugfs_dir; 581 struct dentry *debugfs_dir;
582 struct dentry *mq_debugfs_dir;
583#endif 582#endif
584 583
585 bool mq_sysfs_init_done; 584 bool mq_sysfs_init_done;