Skip to content

Commit 9c1051a

Browse files
osandovaxboe
authored andcommitted
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 <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent d173a25 commit 9c1051a

File tree

8 files changed

+94
-71
lines changed

8 files changed

+94
-71
lines changed

block/blk-core.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040

4141
#include "blk.h"
4242
#include "blk-mq.h"
43-
#include "blk-mq-debugfs.h"
4443
#include "blk-mq-sched.h"
4544
#include "blk-wbt.h"
4645

@@ -562,13 +561,9 @@ void blk_cleanup_queue(struct request_queue *q)
562561
* prevent that q->request_fn() gets invoked after draining finished.
563562
*/
564563
blk_freeze_queue(q);
565-
if (!q->mq_ops) {
566-
spin_lock_irq(lock);
564+
spin_lock_irq(lock);
565+
if (!q->mq_ops)
567566
__blk_drain_queue(q, true);
568-
} else {
569-
blk_mq_debugfs_unregister_mq(q);
570-
spin_lock_irq(lock);
571-
}
572567
queue_flag_set(QUEUE_FLAG_DEAD, q);
573568
spin_unlock_irq(lock);
574569

block/blk-mq-debugfs.c

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -687,19 +687,46 @@ static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = {
687687
{},
688688
};
689689

690+
static 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+
690703
int blk_mq_debugfs_register(struct request_queue *q)
691704
{
705+
struct blk_mq_hw_ctx *hctx;
706+
int i;
707+
692708
if (!blk_debugfs_root)
693709
return -ENOENT;
694710

695711
q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent),
696712
blk_debugfs_root);
697713
if (!q->debugfs_dir)
698-
goto err;
714+
return -ENOMEM;
699715

700-
if (blk_mq_debugfs_register_mq(q))
716+
if (!debugfs_create_files(q->debugfs_dir, q,
717+
blk_mq_debugfs_queue_attrs))
701718
goto err;
702719

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+
703730
return 0;
704731

705732
err:
@@ -710,32 +737,17 @@ int blk_mq_debugfs_register(struct request_queue *q)
710737
void blk_mq_debugfs_unregister(struct request_queue *q)
711738
{
712739
debugfs_remove_recursive(q->debugfs_dir);
713-
q->mq_debugfs_dir = NULL;
714740
q->debugfs_dir = NULL;
715741
}
716742

717-
static bool debugfs_create_files(struct dentry *parent, void *data,
718-
const struct blk_mq_debugfs_attr *attr)
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-
730-
static int blk_mq_debugfs_register_ctx(struct request_queue *q,
731-
struct blk_mq_ctx *ctx,
732-
struct dentry *hctx_dir)
743+
static int blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx,
744+
struct blk_mq_ctx *ctx)
733745
{
734746
struct dentry *ctx_dir;
735747
char name[20];
736748

737749
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);
739751
if (!ctx_dir)
740752
return -ENOMEM;
741753

@@ -745,59 +757,61 @@ static int blk_mq_debugfs_register_ctx(struct request_queue *q,
745757
return 0;
746758
}
747759

748-
static int blk_mq_debugfs_register_hctx(struct request_queue *q,
749-
struct blk_mq_hw_ctx *hctx)
760+
int blk_mq_debugfs_register_hctx(struct request_queue *q,
761+
struct blk_mq_hw_ctx *hctx)
750762
{
751763
struct blk_mq_ctx *ctx;
752-
struct dentry *hctx_dir;
753764
char name[20];
754765
int i;
755766

767+
if (!q->debugfs_dir)
768+
return -ENOENT;
769+
756770
snprintf(name, sizeof(name), "hctx%u", hctx->queue_num);
757-
hctx_dir = debugfs_create_dir(name, q->mq_debugfs_dir);
758-
if (!hctx_dir)
771+
hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir);
772+
if (!hctx->debugfs_dir)
759773
return -ENOMEM;
760774

761-
if (!debugfs_create_files(hctx_dir, hctx, blk_mq_debugfs_hctx_attrs))
762-
return -ENOMEM;
775+
if (!debugfs_create_files(hctx->debugfs_dir, hctx,
776+
blk_mq_debugfs_hctx_attrs))
777+
goto err;
763778

764779
hctx_for_each_ctx(hctx, ctx, i) {
765-
if (blk_mq_debugfs_register_ctx(q, ctx, hctx_dir))
766-
return -ENOMEM;
780+
if (blk_mq_debugfs_register_ctx(hctx, ctx))
781+
goto err;
767782
}
768783

769784
return 0;
785+
786+
err:
787+
blk_mq_debugfs_unregister_hctx(hctx);
788+
return -ENOMEM;
789+
}
790+
791+
void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
792+
{
793+
debugfs_remove_recursive(hctx->debugfs_dir);
794+
hctx->debugfs_dir = NULL;
770795
}
771796

772-
int blk_mq_debugfs_register_mq(struct request_queue *q)
797+
int blk_mq_debugfs_register_hctxs(struct request_queue *q)
773798
{
774799
struct blk_mq_hw_ctx *hctx;
775800
int i;
776801

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-
787802
queue_for_each_hw_ctx(q, hctx, i) {
788803
if (blk_mq_debugfs_register_hctx(q, hctx))
789-
goto err;
804+
return -ENOMEM;
790805
}
791806

792807
return 0;
793-
794-
err:
795-
blk_mq_debugfs_unregister_mq(q);
796-
return -ENOMEM;
797808
}
798809

799-
void blk_mq_debugfs_unregister_mq(struct request_queue *q)
810+
void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
800811
{
801-
debugfs_remove_recursive(q->mq_debugfs_dir);
802-
q->mq_debugfs_dir = NULL;
812+
struct blk_mq_hw_ctx *hctx;
813+
int i;
814+
815+
queue_for_each_hw_ctx(q, hctx, i)
816+
blk_mq_debugfs_unregister_hctx(hctx);
803817
}

block/blk-mq-debugfs.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
#ifdef CONFIG_BLK_DEBUG_FS
55
int blk_mq_debugfs_register(struct request_queue *q);
66
void blk_mq_debugfs_unregister(struct request_queue *q);
7-
int blk_mq_debugfs_register_mq(struct request_queue *q);
8-
void blk_mq_debugfs_unregister_mq(struct request_queue *q);
7+
int blk_mq_debugfs_register_hctx(struct request_queue *q,
8+
struct blk_mq_hw_ctx *hctx);
9+
void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx);
10+
int blk_mq_debugfs_register_hctxs(struct request_queue *q);
11+
void blk_mq_debugfs_unregister_hctxs(struct request_queue *q);
912
#else
1013
static inline int blk_mq_debugfs_register(struct request_queue *q)
1114
{
@@ -16,12 +19,22 @@ static inline void blk_mq_debugfs_unregister(struct request_queue *q)
1619
{
1720
}
1821

19-
static inline int blk_mq_debugfs_register_mq(struct request_queue *q)
22+
static inline int blk_mq_debugfs_register_hctx(struct request_queue *q,
23+
struct blk_mq_hw_ctx *hctx)
2024
{
2125
return 0;
2226
}
2327

24-
static inline void blk_mq_debugfs_unregister_mq(struct request_queue *q)
28+
static inline void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
29+
{
30+
}
31+
32+
static inline int blk_mq_debugfs_register_hctxs(struct request_queue *q)
33+
{
34+
return 0;
35+
}
36+
37+
static inline void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
2538
{
2639
}
2740
#endif

block/blk-mq-sysfs.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include <linux/blk-mq.h>
1313
#include "blk-mq.h"
14-
#include "blk-mq-debugfs.h"
1514
#include "blk-mq-tag.h"
1615

1716
static 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)
259258
queue_for_each_hw_ctx(q, hctx, i)
260259
blk_mq_unregister_hctx(hctx);
261260

262-
blk_mq_debugfs_unregister_mq(q);
263-
264261
kobject_uevent(&q->mq_kobj, KOBJ_REMOVE);
265262
kobject_del(&q->mq_kobj);
266263
kobject_put(&dev->kobj);
@@ -319,8 +316,6 @@ int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
319316

320317
kobject_uevent(&q->mq_kobj, KOBJ_ADD);
321318

322-
blk_mq_debugfs_register(q);
323-
324319
queue_for_each_hw_ctx(q, hctx, i) {
325320
ret = blk_mq_register_hctx(hctx);
326321
if (ret)
@@ -336,8 +331,6 @@ int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
336331
while (--i >= 0)
337332
blk_mq_unregister_hctx(q->queue_hw_ctx[i]);
338333

339-
blk_mq_debugfs_unregister_mq(q);
340-
341334
kobject_uevent(&q->mq_kobj, KOBJ_REMOVE);
342335
kobject_del(&q->mq_kobj);
343336
kobject_put(&dev->kobj);
@@ -365,8 +358,6 @@ void blk_mq_sysfs_unregister(struct request_queue *q)
365358
if (!q->mq_sysfs_init_done)
366359
goto unlock;
367360

368-
blk_mq_debugfs_unregister_mq(q);
369-
370361
queue_for_each_hw_ctx(q, hctx, i)
371362
blk_mq_unregister_hctx(hctx);
372363

@@ -383,8 +374,6 @@ int blk_mq_sysfs_register(struct request_queue *q)
383374
if (!q->mq_sysfs_init_done)
384375
goto unlock;
385376

386-
blk_mq_debugfs_register_mq(q);
387-
388377
queue_for_each_hw_ctx(q, hctx, i) {
389378
ret = blk_mq_register_hctx(hctx);
390379
if (ret)

block/blk-mq.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <linux/blk-mq.h>
3232
#include "blk.h"
3333
#include "blk-mq.h"
34+
#include "blk-mq-debugfs.h"
3435
#include "blk-mq-tag.h"
3536
#include "blk-stat.h"
3637
#include "blk-wbt.h"
@@ -1862,6 +1863,8 @@ static void blk_mq_exit_hctx(struct request_queue *q,
18621863
struct blk_mq_tag_set *set,
18631864
struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx)
18641865
{
1866+
blk_mq_debugfs_unregister_hctx(hctx);
1867+
18651868
blk_mq_tag_idle(hctx);
18661869

18671870
if (set->ops->exit_request)
@@ -1948,6 +1951,8 @@ static int blk_mq_init_hctx(struct request_queue *q,
19481951
if (hctx->flags & BLK_MQ_F_BLOCKING)
19491952
init_srcu_struct(&hctx->queue_rq_srcu);
19501953

1954+
blk_mq_debugfs_register_hctx(q, hctx);
1955+
19511956
return 0;
19521957

19531958
free_fq:
@@ -2385,6 +2390,7 @@ static void blk_mq_queue_reinit(struct request_queue *q,
23852390
{
23862391
WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth));
23872392

2393+
blk_mq_debugfs_unregister_hctxs(q);
23882394
blk_mq_sysfs_unregister(q);
23892395

23902396
/*
@@ -2396,6 +2402,7 @@ static void blk_mq_queue_reinit(struct request_queue *q,
23962402
blk_mq_map_swqueue(q, online_mask);
23972403

23982404
blk_mq_sysfs_register(q);
2405+
blk_mq_debugfs_register_hctxs(q);
23992406
}
24002407

24012408
/*

block/blk-sysfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,8 @@ int blk_register_queue(struct gendisk *disk)
890890
if (q->mq_ops)
891891
__blk_mq_register_dev(dev, q);
892892

893+
blk_mq_debugfs_register(q);
894+
893895
kobject_uevent(&q->kobj, KOBJ_ADD);
894896

895897
wbt_enable_default(q);

include/linux/blk-mq.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ struct blk_mq_hw_ctx {
5757
unsigned long poll_considered;
5858
unsigned long poll_invoked;
5959
unsigned long poll_success;
60+
61+
#ifdef CONFIG_BLK_DEBUG_FS
62+
struct dentry *debugfs_dir;
63+
#endif
6064
};
6165

6266
struct blk_mq_tag_set {

include/linux/blkdev.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,6 @@ struct request_queue {
579579

580580
#ifdef CONFIG_BLK_DEBUG_FS
581581
struct dentry *debugfs_dir;
582-
struct dentry *mq_debugfs_dir;
583582
#endif
584583

585584
bool mq_sysfs_init_done;

0 commit comments

Comments
 (0)