Commit 2d0364c8 authored by Bart Van Assche's avatar Bart Van Assche Committed by Jens Axboe

blk-mq: Register <dev>/queue/mq after having registered <dev>/queue

A later patch in this series will modify blk_mq_debugfs_register()
such that it uses q->kobj.parent to determine the name of a
request queue. Hence make sure that that pointer is initialized
before blk_mq_debugfs_register() is called. To avoid lock inversion,
protect sysfs / debugfs registration with the queue sysfs_lock
instead of the global mutex all_q_mutex.
Signed-off-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 1608fd1c
...@@ -253,6 +253,8 @@ static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q) ...@@ -253,6 +253,8 @@ static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
struct blk_mq_hw_ctx *hctx; struct blk_mq_hw_ctx *hctx;
int i; int i;
lockdep_assert_held(&q->sysfs_lock);
queue_for_each_hw_ctx(q, hctx, i) queue_for_each_hw_ctx(q, hctx, i)
blk_mq_unregister_hctx(hctx); blk_mq_unregister_hctx(hctx);
...@@ -267,9 +269,9 @@ static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q) ...@@ -267,9 +269,9 @@ static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
void blk_mq_unregister_dev(struct device *dev, struct request_queue *q) void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
{ {
blk_mq_disable_hotplug(); mutex_lock(&q->sysfs_lock);
__blk_mq_unregister_dev(dev, q); __blk_mq_unregister_dev(dev, q);
blk_mq_enable_hotplug(); mutex_unlock(&q->sysfs_lock);
} }
void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx) void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx)
...@@ -302,12 +304,13 @@ void blk_mq_sysfs_init(struct request_queue *q) ...@@ -302,12 +304,13 @@ void blk_mq_sysfs_init(struct request_queue *q)
} }
} }
int blk_mq_register_dev(struct device *dev, struct request_queue *q) int __blk_mq_register_dev(struct device *dev, struct request_queue *q)
{ {
struct blk_mq_hw_ctx *hctx; struct blk_mq_hw_ctx *hctx;
int ret, i; int ret, i;
blk_mq_disable_hotplug(); WARN_ON_ONCE(!q->kobj.parent);
lockdep_assert_held(&q->sysfs_lock);
ret = kobject_add(&q->mq_kobj, kobject_get(&dev->kobj), "%s", "mq"); ret = kobject_add(&q->mq_kobj, kobject_get(&dev->kobj), "%s", "mq");
if (ret < 0) if (ret < 0)
...@@ -327,8 +330,18 @@ int blk_mq_register_dev(struct device *dev, struct request_queue *q) ...@@ -327,8 +330,18 @@ int blk_mq_register_dev(struct device *dev, struct request_queue *q)
__blk_mq_unregister_dev(dev, q); __blk_mq_unregister_dev(dev, q);
else else
q->mq_sysfs_init_done = true; q->mq_sysfs_init_done = true;
out: out:
blk_mq_enable_hotplug(); return ret;
}
int blk_mq_register_dev(struct device *dev, struct request_queue *q)
{
int ret;
mutex_lock(&q->sysfs_lock);
ret = __blk_mq_register_dev(dev, q);
mutex_unlock(&q->sysfs_lock);
return ret; return ret;
} }
...@@ -339,13 +352,17 @@ void blk_mq_sysfs_unregister(struct request_queue *q) ...@@ -339,13 +352,17 @@ void blk_mq_sysfs_unregister(struct request_queue *q)
struct blk_mq_hw_ctx *hctx; struct blk_mq_hw_ctx *hctx;
int i; int i;
mutex_lock(&q->sysfs_lock);
if (!q->mq_sysfs_init_done) if (!q->mq_sysfs_init_done)
return; goto unlock;
blk_mq_debugfs_unregister_hctxs(q); blk_mq_debugfs_unregister_hctxs(q);
queue_for_each_hw_ctx(q, hctx, i) queue_for_each_hw_ctx(q, hctx, i)
blk_mq_unregister_hctx(hctx); blk_mq_unregister_hctx(hctx);
unlock:
mutex_unlock(&q->sysfs_lock);
} }
int blk_mq_sysfs_register(struct request_queue *q) int blk_mq_sysfs_register(struct request_queue *q)
...@@ -353,8 +370,9 @@ int blk_mq_sysfs_register(struct request_queue *q) ...@@ -353,8 +370,9 @@ int blk_mq_sysfs_register(struct request_queue *q)
struct blk_mq_hw_ctx *hctx; struct blk_mq_hw_ctx *hctx;
int i, ret = 0; int i, ret = 0;
mutex_lock(&q->sysfs_lock);
if (!q->mq_sysfs_init_done) if (!q->mq_sysfs_init_done)
return ret; goto unlock;
blk_mq_debugfs_register_hctxs(q); blk_mq_debugfs_register_hctxs(q);
...@@ -364,5 +382,8 @@ int blk_mq_sysfs_register(struct request_queue *q) ...@@ -364,5 +382,8 @@ int blk_mq_sysfs_register(struct request_queue *q)
break; break;
} }
unlock:
mutex_unlock(&q->sysfs_lock);
return ret; return ret;
} }
...@@ -78,6 +78,7 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *q, ...@@ -78,6 +78,7 @@ static inline struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *q,
*/ */
extern void blk_mq_sysfs_init(struct request_queue *q); extern void blk_mq_sysfs_init(struct request_queue *q);
extern void blk_mq_sysfs_deinit(struct request_queue *q); extern void blk_mq_sysfs_deinit(struct request_queue *q);
extern int __blk_mq_register_dev(struct device *dev, struct request_queue *q);
extern int blk_mq_sysfs_register(struct request_queue *q); extern int blk_mq_sysfs_register(struct request_queue *q);
extern void blk_mq_sysfs_unregister(struct request_queue *q); extern void blk_mq_sysfs_unregister(struct request_queue *q);
extern void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx); extern void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx);
......
...@@ -877,9 +877,6 @@ int blk_register_queue(struct gendisk *disk) ...@@ -877,9 +877,6 @@ int blk_register_queue(struct gendisk *disk)
if (ret) if (ret)
return ret; return ret;
if (q->mq_ops)
blk_mq_register_dev(dev, q);
/* Prevent changes through sysfs until registration is completed. */ /* Prevent changes through sysfs until registration is completed. */
mutex_lock(&q->sysfs_lock); mutex_lock(&q->sysfs_lock);
...@@ -889,6 +886,9 @@ int blk_register_queue(struct gendisk *disk) ...@@ -889,6 +886,9 @@ int blk_register_queue(struct gendisk *disk)
goto unlock; goto unlock;
} }
if (q->mq_ops)
__blk_mq_register_dev(dev, q);
kobject_uevent(&q->kobj, KOBJ_ADD); kobject_uevent(&q->kobj, KOBJ_ADD);
wbt_enable_default(q); wbt_enable_default(q);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment