aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-mq-sysfs.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-05-30 10:25:36 -0400
committerJens Axboe <axboe@fb.com>2014-05-30 10:25:36 -0400
commit67aec14ce87fe25bdfff7dbf468556333df11c4e (patch)
tree85857d82abc91996bfdf054774f46e5aa519acec /block/blk-mq-sysfs.c
parent2230237500821aedfcf2bba2a79d9cbca389233c (diff)
blk-mq: make the sysfs mq/ layout reflect current mappings
Currently blk-mq registers all the hardware queues in sysfs, regardless of whether it uses them (e.g. they have CPU mappings) or not. The unused hardware queues lack the cpux/ directories, and the other sysfs entries (like active, pending, etc) are all zeroes. Change this so that sysfs correctly reflects the current mappings of the hardware queues. Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/blk-mq-sysfs.c')
-rw-r--r--block/blk-mq-sysfs.c102
1 files changed, 83 insertions, 19 deletions
diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
index 99a60a829e69..e5f575ff0bf9 100644
--- a/block/blk-mq-sysfs.c
+++ b/block/blk-mq-sysfs.c
@@ -327,6 +327,42 @@ static struct kobj_type blk_mq_hw_ktype = {
327 .release = blk_mq_sysfs_release, 327 .release = blk_mq_sysfs_release,
328}; 328};
329 329
330void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx)
331{
332 struct blk_mq_ctx *ctx;
333 int i;
334
335 if (!hctx->nr_ctx || !(hctx->flags & BLK_MQ_F_SYSFS_UP))
336 return;
337
338 hctx_for_each_ctx(hctx, ctx, i)
339 kobject_del(&ctx->kobj);
340
341 kobject_del(&hctx->kobj);
342}
343
344int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
345{
346 struct request_queue *q = hctx->queue;
347 struct blk_mq_ctx *ctx;
348 int i, ret;
349
350 if (!hctx->nr_ctx || !(hctx->flags & BLK_MQ_F_SYSFS_UP))
351 return 0;
352
353 ret = kobject_add(&hctx->kobj, &q->mq_kobj, "%u", hctx->queue_num);
354 if (ret)
355 return ret;
356
357 hctx_for_each_ctx(hctx, ctx, i) {
358 ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
359 if (ret)
360 break;
361 }
362
363 return ret;
364}
365
330void blk_mq_unregister_disk(struct gendisk *disk) 366void blk_mq_unregister_disk(struct gendisk *disk)
331{ 367{
332 struct request_queue *q = disk->queue; 368 struct request_queue *q = disk->queue;
@@ -335,11 +371,11 @@ void blk_mq_unregister_disk(struct gendisk *disk)
335 int i, j; 371 int i, j;
336 372
337 queue_for_each_hw_ctx(q, hctx, i) { 373 queue_for_each_hw_ctx(q, hctx, i) {
338 hctx_for_each_ctx(hctx, ctx, j) { 374 blk_mq_unregister_hctx(hctx);
339 kobject_del(&ctx->kobj); 375
376 hctx_for_each_ctx(hctx, ctx, j)
340 kobject_put(&ctx->kobj); 377 kobject_put(&ctx->kobj);
341 } 378
342 kobject_del(&hctx->kobj);
343 kobject_put(&hctx->kobj); 379 kobject_put(&hctx->kobj);
344 } 380 }
345 381
@@ -350,15 +386,30 @@ void blk_mq_unregister_disk(struct gendisk *disk)
350 kobject_put(&disk_to_dev(disk)->kobj); 386 kobject_put(&disk_to_dev(disk)->kobj);
351} 387}
352 388
389static void blk_mq_sysfs_init(struct request_queue *q)
390{
391 struct blk_mq_hw_ctx *hctx;
392 struct blk_mq_ctx *ctx;
393 int i, j;
394
395 kobject_init(&q->mq_kobj, &blk_mq_ktype);
396
397 queue_for_each_hw_ctx(q, hctx, i) {
398 kobject_init(&hctx->kobj, &blk_mq_hw_ktype);
399
400 hctx_for_each_ctx(hctx, ctx, j)
401 kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);
402 }
403}
404
353int blk_mq_register_disk(struct gendisk *disk) 405int blk_mq_register_disk(struct gendisk *disk)
354{ 406{
355 struct device *dev = disk_to_dev(disk); 407 struct device *dev = disk_to_dev(disk);
356 struct request_queue *q = disk->queue; 408 struct request_queue *q = disk->queue;
357 struct blk_mq_hw_ctx *hctx; 409 struct blk_mq_hw_ctx *hctx;
358 struct blk_mq_ctx *ctx; 410 int ret, i;
359 int ret, i, j;
360 411
361 kobject_init(&q->mq_kobj, &blk_mq_ktype); 412 blk_mq_sysfs_init(q);
362 413
363 ret = kobject_add(&q->mq_kobj, kobject_get(&dev->kobj), "%s", "mq"); 414 ret = kobject_add(&q->mq_kobj, kobject_get(&dev->kobj), "%s", "mq");
364 if (ret < 0) 415 if (ret < 0)
@@ -367,20 +418,10 @@ int blk_mq_register_disk(struct gendisk *disk)
367 kobject_uevent(&q->mq_kobj, KOBJ_ADD); 418 kobject_uevent(&q->mq_kobj, KOBJ_ADD);
368 419
369 queue_for_each_hw_ctx(q, hctx, i) { 420 queue_for_each_hw_ctx(q, hctx, i) {
370 kobject_init(&hctx->kobj, &blk_mq_hw_ktype); 421 hctx->flags |= BLK_MQ_F_SYSFS_UP;
371 ret = kobject_add(&hctx->kobj, &q->mq_kobj, "%u", i); 422 ret = blk_mq_register_hctx(hctx);
372 if (ret) 423 if (ret)
373 break; 424 break;
374
375 if (!hctx->nr_ctx)
376 continue;
377
378 hctx_for_each_ctx(hctx, ctx, j) {
379 kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);
380 ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
381 if (ret)
382 break;
383 }
384 } 425 }
385 426
386 if (ret) { 427 if (ret) {
@@ -390,3 +431,26 @@ int blk_mq_register_disk(struct gendisk *disk)
390 431
391 return 0; 432 return 0;
392} 433}
434
435void blk_mq_sysfs_unregister(struct request_queue *q)
436{
437 struct blk_mq_hw_ctx *hctx;
438 int i;
439
440 queue_for_each_hw_ctx(q, hctx, i)
441 blk_mq_unregister_hctx(hctx);
442}
443
444int blk_mq_sysfs_register(struct request_queue *q)
445{
446 struct blk_mq_hw_ctx *hctx;
447 int i, ret = 0;
448
449 queue_for_each_hw_ctx(q, hctx, i) {
450 ret = blk_mq_register_hctx(hctx);
451 if (ret)
452 break;
453 }
454
455 return ret;
456}