diff options
author | Jens Axboe <axboe@fb.com> | 2014-05-30 10:25:36 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-05-30 10:25:36 -0400 |
commit | 67aec14ce87fe25bdfff7dbf468556333df11c4e (patch) | |
tree | 85857d82abc91996bfdf054774f46e5aa519acec /block/blk-mq-sysfs.c | |
parent | 2230237500821aedfcf2bba2a79d9cbca389233c (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.c | 102 |
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 | ||
330 | void 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 | |||
344 | int 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 | |||
330 | void blk_mq_unregister_disk(struct gendisk *disk) | 366 | void 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 | ||
389 | static 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 | |||
353 | int blk_mq_register_disk(struct gendisk *disk) | 405 | int 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 | |||
435 | void 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 | |||
444 | int 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 | } | ||