1320ae51fSJens Axboe #include <linux/kernel.h> 2320ae51fSJens Axboe #include <linux/module.h> 3320ae51fSJens Axboe #include <linux/backing-dev.h> 4320ae51fSJens Axboe #include <linux/bio.h> 5320ae51fSJens Axboe #include <linux/blkdev.h> 6320ae51fSJens Axboe #include <linux/mm.h> 7320ae51fSJens Axboe #include <linux/init.h> 8320ae51fSJens Axboe #include <linux/slab.h> 9320ae51fSJens Axboe #include <linux/workqueue.h> 10320ae51fSJens Axboe #include <linux/smp.h> 11320ae51fSJens Axboe 12320ae51fSJens Axboe #include <linux/blk-mq.h> 13320ae51fSJens Axboe #include "blk-mq.h" 14320ae51fSJens Axboe #include "blk-mq-tag.h" 15320ae51fSJens Axboe 16320ae51fSJens Axboe static void blk_mq_sysfs_release(struct kobject *kobj) 17320ae51fSJens Axboe { 18320ae51fSJens Axboe } 19320ae51fSJens Axboe 20320ae51fSJens Axboe struct blk_mq_ctx_sysfs_entry { 21320ae51fSJens Axboe struct attribute attr; 22320ae51fSJens Axboe ssize_t (*show)(struct blk_mq_ctx *, char *); 23320ae51fSJens Axboe ssize_t (*store)(struct blk_mq_ctx *, const char *, size_t); 24320ae51fSJens Axboe }; 25320ae51fSJens Axboe 26320ae51fSJens Axboe struct blk_mq_hw_ctx_sysfs_entry { 27320ae51fSJens Axboe struct attribute attr; 28320ae51fSJens Axboe ssize_t (*show)(struct blk_mq_hw_ctx *, char *); 29320ae51fSJens Axboe ssize_t (*store)(struct blk_mq_hw_ctx *, const char *, size_t); 30320ae51fSJens Axboe }; 31320ae51fSJens Axboe 32320ae51fSJens Axboe static ssize_t blk_mq_sysfs_show(struct kobject *kobj, struct attribute *attr, 33320ae51fSJens Axboe char *page) 34320ae51fSJens Axboe { 35320ae51fSJens Axboe struct blk_mq_ctx_sysfs_entry *entry; 36320ae51fSJens Axboe struct blk_mq_ctx *ctx; 37320ae51fSJens Axboe struct request_queue *q; 38320ae51fSJens Axboe ssize_t res; 39320ae51fSJens Axboe 40320ae51fSJens Axboe entry = container_of(attr, struct blk_mq_ctx_sysfs_entry, attr); 41320ae51fSJens Axboe ctx = container_of(kobj, struct blk_mq_ctx, kobj); 42320ae51fSJens Axboe q = ctx->queue; 43320ae51fSJens Axboe 44320ae51fSJens Axboe if (!entry->show) 45320ae51fSJens Axboe return -EIO; 46320ae51fSJens Axboe 47320ae51fSJens Axboe res = -ENOENT; 48320ae51fSJens Axboe mutex_lock(&q->sysfs_lock); 49320ae51fSJens Axboe if (!blk_queue_dying(q)) 50320ae51fSJens Axboe res = entry->show(ctx, page); 51320ae51fSJens Axboe mutex_unlock(&q->sysfs_lock); 52320ae51fSJens Axboe return res; 53320ae51fSJens Axboe } 54320ae51fSJens Axboe 55320ae51fSJens Axboe static ssize_t blk_mq_sysfs_store(struct kobject *kobj, struct attribute *attr, 56320ae51fSJens Axboe const char *page, size_t length) 57320ae51fSJens Axboe { 58320ae51fSJens Axboe struct blk_mq_ctx_sysfs_entry *entry; 59320ae51fSJens Axboe struct blk_mq_ctx *ctx; 60320ae51fSJens Axboe struct request_queue *q; 61320ae51fSJens Axboe ssize_t res; 62320ae51fSJens Axboe 63320ae51fSJens Axboe entry = container_of(attr, struct blk_mq_ctx_sysfs_entry, attr); 64320ae51fSJens Axboe ctx = container_of(kobj, struct blk_mq_ctx, kobj); 65320ae51fSJens Axboe q = ctx->queue; 66320ae51fSJens Axboe 67320ae51fSJens Axboe if (!entry->store) 68320ae51fSJens Axboe return -EIO; 69320ae51fSJens Axboe 70320ae51fSJens Axboe res = -ENOENT; 71320ae51fSJens Axboe mutex_lock(&q->sysfs_lock); 72320ae51fSJens Axboe if (!blk_queue_dying(q)) 73320ae51fSJens Axboe res = entry->store(ctx, page, length); 74320ae51fSJens Axboe mutex_unlock(&q->sysfs_lock); 75320ae51fSJens Axboe return res; 76320ae51fSJens Axboe } 77320ae51fSJens Axboe 78320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_show(struct kobject *kobj, 79320ae51fSJens Axboe struct attribute *attr, char *page) 80320ae51fSJens Axboe { 81320ae51fSJens Axboe struct blk_mq_hw_ctx_sysfs_entry *entry; 82320ae51fSJens Axboe struct blk_mq_hw_ctx *hctx; 83320ae51fSJens Axboe struct request_queue *q; 84320ae51fSJens Axboe ssize_t res; 85320ae51fSJens Axboe 86320ae51fSJens Axboe entry = container_of(attr, struct blk_mq_hw_ctx_sysfs_entry, attr); 87320ae51fSJens Axboe hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj); 88320ae51fSJens Axboe q = hctx->queue; 89320ae51fSJens Axboe 90320ae51fSJens Axboe if (!entry->show) 91320ae51fSJens Axboe return -EIO; 92320ae51fSJens Axboe 93320ae51fSJens Axboe res = -ENOENT; 94320ae51fSJens Axboe mutex_lock(&q->sysfs_lock); 95320ae51fSJens Axboe if (!blk_queue_dying(q)) 96320ae51fSJens Axboe res = entry->show(hctx, page); 97320ae51fSJens Axboe mutex_unlock(&q->sysfs_lock); 98320ae51fSJens Axboe return res; 99320ae51fSJens Axboe } 100320ae51fSJens Axboe 101320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_store(struct kobject *kobj, 102320ae51fSJens Axboe struct attribute *attr, const char *page, 103320ae51fSJens Axboe size_t length) 104320ae51fSJens Axboe { 105320ae51fSJens Axboe struct blk_mq_hw_ctx_sysfs_entry *entry; 106320ae51fSJens Axboe struct blk_mq_hw_ctx *hctx; 107320ae51fSJens Axboe struct request_queue *q; 108320ae51fSJens Axboe ssize_t res; 109320ae51fSJens Axboe 110320ae51fSJens Axboe entry = container_of(attr, struct blk_mq_hw_ctx_sysfs_entry, attr); 111320ae51fSJens Axboe hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj); 112320ae51fSJens Axboe q = hctx->queue; 113320ae51fSJens Axboe 114320ae51fSJens Axboe if (!entry->store) 115320ae51fSJens Axboe return -EIO; 116320ae51fSJens Axboe 117320ae51fSJens Axboe res = -ENOENT; 118320ae51fSJens Axboe mutex_lock(&q->sysfs_lock); 119320ae51fSJens Axboe if (!blk_queue_dying(q)) 120320ae51fSJens Axboe res = entry->store(hctx, page, length); 121320ae51fSJens Axboe mutex_unlock(&q->sysfs_lock); 122320ae51fSJens Axboe return res; 123320ae51fSJens Axboe } 124320ae51fSJens Axboe 125320ae51fSJens Axboe static ssize_t blk_mq_sysfs_dispatched_show(struct blk_mq_ctx *ctx, char *page) 126320ae51fSJens Axboe { 127320ae51fSJens Axboe return sprintf(page, "%lu %lu\n", ctx->rq_dispatched[1], 128320ae51fSJens Axboe ctx->rq_dispatched[0]); 129320ae51fSJens Axboe } 130320ae51fSJens Axboe 131320ae51fSJens Axboe static ssize_t blk_mq_sysfs_merged_show(struct blk_mq_ctx *ctx, char *page) 132320ae51fSJens Axboe { 133320ae51fSJens Axboe return sprintf(page, "%lu\n", ctx->rq_merged); 134320ae51fSJens Axboe } 135320ae51fSJens Axboe 136320ae51fSJens Axboe static ssize_t blk_mq_sysfs_completed_show(struct blk_mq_ctx *ctx, char *page) 137320ae51fSJens Axboe { 138320ae51fSJens Axboe return sprintf(page, "%lu %lu\n", ctx->rq_completed[1], 139320ae51fSJens Axboe ctx->rq_completed[0]); 140320ae51fSJens Axboe } 141320ae51fSJens Axboe 142320ae51fSJens Axboe static ssize_t sysfs_list_show(char *page, struct list_head *list, char *msg) 143320ae51fSJens Axboe { 144320ae51fSJens Axboe char *start_page = page; 145320ae51fSJens Axboe struct request *rq; 146320ae51fSJens Axboe 147320ae51fSJens Axboe page += sprintf(page, "%s:\n", msg); 148320ae51fSJens Axboe 149320ae51fSJens Axboe list_for_each_entry(rq, list, queuelist) 150320ae51fSJens Axboe page += sprintf(page, "\t%p\n", rq); 151320ae51fSJens Axboe 152320ae51fSJens Axboe return page - start_page; 153320ae51fSJens Axboe } 154320ae51fSJens Axboe 155320ae51fSJens Axboe static ssize_t blk_mq_sysfs_rq_list_show(struct blk_mq_ctx *ctx, char *page) 156320ae51fSJens Axboe { 157320ae51fSJens Axboe ssize_t ret; 158320ae51fSJens Axboe 159320ae51fSJens Axboe spin_lock(&ctx->lock); 160320ae51fSJens Axboe ret = sysfs_list_show(page, &ctx->rq_list, "CTX pending"); 161320ae51fSJens Axboe spin_unlock(&ctx->lock); 162320ae51fSJens Axboe 163320ae51fSJens Axboe return ret; 164320ae51fSJens Axboe } 165320ae51fSJens Axboe 166320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_queued_show(struct blk_mq_hw_ctx *hctx, 167320ae51fSJens Axboe char *page) 168320ae51fSJens Axboe { 169320ae51fSJens Axboe return sprintf(page, "%lu\n", hctx->queued); 170320ae51fSJens Axboe } 171320ae51fSJens Axboe 172320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_run_show(struct blk_mq_hw_ctx *hctx, char *page) 173320ae51fSJens Axboe { 174320ae51fSJens Axboe return sprintf(page, "%lu\n", hctx->run); 175320ae51fSJens Axboe } 176320ae51fSJens Axboe 177320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_dispatched_show(struct blk_mq_hw_ctx *hctx, 178320ae51fSJens Axboe char *page) 179320ae51fSJens Axboe { 180320ae51fSJens Axboe char *start_page = page; 181320ae51fSJens Axboe int i; 182320ae51fSJens Axboe 183320ae51fSJens Axboe page += sprintf(page, "%8u\t%lu\n", 0U, hctx->dispatched[0]); 184320ae51fSJens Axboe 185320ae51fSJens Axboe for (i = 1; i < BLK_MQ_MAX_DISPATCH_ORDER; i++) { 186320ae51fSJens Axboe unsigned long d = 1U << (i - 1); 187320ae51fSJens Axboe 188320ae51fSJens Axboe page += sprintf(page, "%8lu\t%lu\n", d, hctx->dispatched[i]); 189320ae51fSJens Axboe } 190320ae51fSJens Axboe 191320ae51fSJens Axboe return page - start_page; 192320ae51fSJens Axboe } 193320ae51fSJens Axboe 194320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_rq_list_show(struct blk_mq_hw_ctx *hctx, 195320ae51fSJens Axboe char *page) 196320ae51fSJens Axboe { 197320ae51fSJens Axboe ssize_t ret; 198320ae51fSJens Axboe 199320ae51fSJens Axboe spin_lock(&hctx->lock); 200320ae51fSJens Axboe ret = sysfs_list_show(page, &hctx->dispatch, "HCTX pending"); 201320ae51fSJens Axboe spin_unlock(&hctx->lock); 202320ae51fSJens Axboe 203320ae51fSJens Axboe return ret; 204320ae51fSJens Axboe } 205320ae51fSJens Axboe 206320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_ipi_show(struct blk_mq_hw_ctx *hctx, char *page) 207320ae51fSJens Axboe { 208320ae51fSJens Axboe ssize_t ret; 209320ae51fSJens Axboe 210320ae51fSJens Axboe spin_lock(&hctx->lock); 211320ae51fSJens Axboe ret = sprintf(page, "%u\n", !!(hctx->flags & BLK_MQ_F_SHOULD_IPI)); 212320ae51fSJens Axboe spin_unlock(&hctx->lock); 213320ae51fSJens Axboe 214320ae51fSJens Axboe return ret; 215320ae51fSJens Axboe } 216320ae51fSJens Axboe 217320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_ipi_store(struct blk_mq_hw_ctx *hctx, 218320ae51fSJens Axboe const char *page, size_t len) 219320ae51fSJens Axboe { 220320ae51fSJens Axboe struct blk_mq_ctx *ctx; 221320ae51fSJens Axboe unsigned long ret; 222320ae51fSJens Axboe unsigned int i; 223320ae51fSJens Axboe 224320ae51fSJens Axboe if (kstrtoul(page, 10, &ret)) { 225320ae51fSJens Axboe pr_err("blk-mq-sysfs: invalid input '%s'\n", page); 226320ae51fSJens Axboe return -EINVAL; 227320ae51fSJens Axboe } 228320ae51fSJens Axboe 229320ae51fSJens Axboe spin_lock(&hctx->lock); 230320ae51fSJens Axboe if (ret) 231320ae51fSJens Axboe hctx->flags |= BLK_MQ_F_SHOULD_IPI; 232320ae51fSJens Axboe else 233320ae51fSJens Axboe hctx->flags &= ~BLK_MQ_F_SHOULD_IPI; 234320ae51fSJens Axboe spin_unlock(&hctx->lock); 235320ae51fSJens Axboe 236320ae51fSJens Axboe hctx_for_each_ctx(hctx, ctx, i) 237320ae51fSJens Axboe ctx->ipi_redirect = !!ret; 238320ae51fSJens Axboe 239320ae51fSJens Axboe return len; 240320ae51fSJens Axboe } 241320ae51fSJens Axboe 242320ae51fSJens Axboe static ssize_t blk_mq_hw_sysfs_tags_show(struct blk_mq_hw_ctx *hctx, char *page) 243320ae51fSJens Axboe { 244320ae51fSJens Axboe return blk_mq_tag_sysfs_show(hctx->tags, page); 245320ae51fSJens Axboe } 246320ae51fSJens Axboe 247320ae51fSJens Axboe static struct blk_mq_ctx_sysfs_entry blk_mq_sysfs_dispatched = { 248320ae51fSJens Axboe .attr = {.name = "dispatched", .mode = S_IRUGO }, 249320ae51fSJens Axboe .show = blk_mq_sysfs_dispatched_show, 250320ae51fSJens Axboe }; 251320ae51fSJens Axboe static struct blk_mq_ctx_sysfs_entry blk_mq_sysfs_merged = { 252320ae51fSJens Axboe .attr = {.name = "merged", .mode = S_IRUGO }, 253320ae51fSJens Axboe .show = blk_mq_sysfs_merged_show, 254320ae51fSJens Axboe }; 255320ae51fSJens Axboe static struct blk_mq_ctx_sysfs_entry blk_mq_sysfs_completed = { 256320ae51fSJens Axboe .attr = {.name = "completed", .mode = S_IRUGO }, 257320ae51fSJens Axboe .show = blk_mq_sysfs_completed_show, 258320ae51fSJens Axboe }; 259320ae51fSJens Axboe static struct blk_mq_ctx_sysfs_entry blk_mq_sysfs_rq_list = { 260320ae51fSJens Axboe .attr = {.name = "rq_list", .mode = S_IRUGO }, 261320ae51fSJens Axboe .show = blk_mq_sysfs_rq_list_show, 262320ae51fSJens Axboe }; 263320ae51fSJens Axboe 264320ae51fSJens Axboe static struct attribute *default_ctx_attrs[] = { 265320ae51fSJens Axboe &blk_mq_sysfs_dispatched.attr, 266320ae51fSJens Axboe &blk_mq_sysfs_merged.attr, 267320ae51fSJens Axboe &blk_mq_sysfs_completed.attr, 268320ae51fSJens Axboe &blk_mq_sysfs_rq_list.attr, 269320ae51fSJens Axboe NULL, 270320ae51fSJens Axboe }; 271320ae51fSJens Axboe 272320ae51fSJens Axboe static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_queued = { 273320ae51fSJens Axboe .attr = {.name = "queued", .mode = S_IRUGO }, 274320ae51fSJens Axboe .show = blk_mq_hw_sysfs_queued_show, 275320ae51fSJens Axboe }; 276320ae51fSJens Axboe static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_run = { 277320ae51fSJens Axboe .attr = {.name = "run", .mode = S_IRUGO }, 278320ae51fSJens Axboe .show = blk_mq_hw_sysfs_run_show, 279320ae51fSJens Axboe }; 280320ae51fSJens Axboe static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_dispatched = { 281320ae51fSJens Axboe .attr = {.name = "dispatched", .mode = S_IRUGO }, 282320ae51fSJens Axboe .show = blk_mq_hw_sysfs_dispatched_show, 283320ae51fSJens Axboe }; 284320ae51fSJens Axboe static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_pending = { 285320ae51fSJens Axboe .attr = {.name = "pending", .mode = S_IRUGO }, 286320ae51fSJens Axboe .show = blk_mq_hw_sysfs_rq_list_show, 287320ae51fSJens Axboe }; 288320ae51fSJens Axboe static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_ipi = { 289320ae51fSJens Axboe .attr = {.name = "ipi_redirect", .mode = S_IRUGO | S_IWUSR}, 290320ae51fSJens Axboe .show = blk_mq_hw_sysfs_ipi_show, 291320ae51fSJens Axboe .store = blk_mq_hw_sysfs_ipi_store, 292320ae51fSJens Axboe }; 293320ae51fSJens Axboe static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_tags = { 294320ae51fSJens Axboe .attr = {.name = "tags", .mode = S_IRUGO }, 295320ae51fSJens Axboe .show = blk_mq_hw_sysfs_tags_show, 296320ae51fSJens Axboe }; 297320ae51fSJens Axboe 298320ae51fSJens Axboe static struct attribute *default_hw_ctx_attrs[] = { 299320ae51fSJens Axboe &blk_mq_hw_sysfs_queued.attr, 300320ae51fSJens Axboe &blk_mq_hw_sysfs_run.attr, 301320ae51fSJens Axboe &blk_mq_hw_sysfs_dispatched.attr, 302320ae51fSJens Axboe &blk_mq_hw_sysfs_pending.attr, 303320ae51fSJens Axboe &blk_mq_hw_sysfs_ipi.attr, 304320ae51fSJens Axboe &blk_mq_hw_sysfs_tags.attr, 305320ae51fSJens Axboe NULL, 306320ae51fSJens Axboe }; 307320ae51fSJens Axboe 308320ae51fSJens Axboe static const struct sysfs_ops blk_mq_sysfs_ops = { 309320ae51fSJens Axboe .show = blk_mq_sysfs_show, 310320ae51fSJens Axboe .store = blk_mq_sysfs_store, 311320ae51fSJens Axboe }; 312320ae51fSJens Axboe 313320ae51fSJens Axboe static const struct sysfs_ops blk_mq_hw_sysfs_ops = { 314320ae51fSJens Axboe .show = blk_mq_hw_sysfs_show, 315320ae51fSJens Axboe .store = blk_mq_hw_sysfs_store, 316320ae51fSJens Axboe }; 317320ae51fSJens Axboe 318320ae51fSJens Axboe static struct kobj_type blk_mq_ktype = { 319320ae51fSJens Axboe .sysfs_ops = &blk_mq_sysfs_ops, 320320ae51fSJens Axboe .release = blk_mq_sysfs_release, 321320ae51fSJens Axboe }; 322320ae51fSJens Axboe 323320ae51fSJens Axboe static struct kobj_type blk_mq_ctx_ktype = { 324320ae51fSJens Axboe .sysfs_ops = &blk_mq_sysfs_ops, 325320ae51fSJens Axboe .default_attrs = default_ctx_attrs, 326320ae51fSJens Axboe .release = blk_mq_sysfs_release, 327320ae51fSJens Axboe }; 328320ae51fSJens Axboe 329320ae51fSJens Axboe static struct kobj_type blk_mq_hw_ktype = { 330320ae51fSJens Axboe .sysfs_ops = &blk_mq_hw_sysfs_ops, 331320ae51fSJens Axboe .default_attrs = default_hw_ctx_attrs, 332320ae51fSJens Axboe .release = blk_mq_sysfs_release, 333320ae51fSJens Axboe }; 334320ae51fSJens Axboe 335320ae51fSJens Axboe void blk_mq_unregister_disk(struct gendisk *disk) 336320ae51fSJens Axboe { 337320ae51fSJens Axboe struct request_queue *q = disk->queue; 338*85157366SAndrey Vagin struct blk_mq_hw_ctx *hctx; 339*85157366SAndrey Vagin struct blk_mq_ctx *ctx; 340*85157366SAndrey Vagin int i, j; 341*85157366SAndrey Vagin 342*85157366SAndrey Vagin queue_for_each_hw_ctx(q, hctx, i) { 343*85157366SAndrey Vagin hctx_for_each_ctx(hctx, ctx, j) { 344*85157366SAndrey Vagin kobject_del(&ctx->kobj); 345*85157366SAndrey Vagin kobject_put(&ctx->kobj); 346*85157366SAndrey Vagin } 347*85157366SAndrey Vagin kobject_del(&hctx->kobj); 348*85157366SAndrey Vagin kobject_put(&hctx->kobj); 349*85157366SAndrey Vagin } 350320ae51fSJens Axboe 351320ae51fSJens Axboe kobject_uevent(&q->mq_kobj, KOBJ_REMOVE); 352320ae51fSJens Axboe kobject_del(&q->mq_kobj); 353*85157366SAndrey Vagin kobject_put(&q->mq_kobj); 354320ae51fSJens Axboe 355320ae51fSJens Axboe kobject_put(&disk_to_dev(disk)->kobj); 356320ae51fSJens Axboe } 357320ae51fSJens Axboe 358320ae51fSJens Axboe int blk_mq_register_disk(struct gendisk *disk) 359320ae51fSJens Axboe { 360320ae51fSJens Axboe struct device *dev = disk_to_dev(disk); 361320ae51fSJens Axboe struct request_queue *q = disk->queue; 362320ae51fSJens Axboe struct blk_mq_hw_ctx *hctx; 363320ae51fSJens Axboe struct blk_mq_ctx *ctx; 364320ae51fSJens Axboe int ret, i, j; 365320ae51fSJens Axboe 366320ae51fSJens Axboe kobject_init(&q->mq_kobj, &blk_mq_ktype); 367320ae51fSJens Axboe 368320ae51fSJens Axboe ret = kobject_add(&q->mq_kobj, kobject_get(&dev->kobj), "%s", "mq"); 369320ae51fSJens Axboe if (ret < 0) 370320ae51fSJens Axboe return ret; 371320ae51fSJens Axboe 372320ae51fSJens Axboe kobject_uevent(&q->mq_kobj, KOBJ_ADD); 373320ae51fSJens Axboe 374320ae51fSJens Axboe queue_for_each_hw_ctx(q, hctx, i) { 375320ae51fSJens Axboe kobject_init(&hctx->kobj, &blk_mq_hw_ktype); 376320ae51fSJens Axboe ret = kobject_add(&hctx->kobj, &q->mq_kobj, "%u", i); 377320ae51fSJens Axboe if (ret) 378320ae51fSJens Axboe break; 379320ae51fSJens Axboe 380320ae51fSJens Axboe if (!hctx->nr_ctx) 381320ae51fSJens Axboe continue; 382320ae51fSJens Axboe 383320ae51fSJens Axboe hctx_for_each_ctx(hctx, ctx, j) { 384320ae51fSJens Axboe kobject_init(&ctx->kobj, &blk_mq_ctx_ktype); 385320ae51fSJens Axboe ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu); 386320ae51fSJens Axboe if (ret) 387320ae51fSJens Axboe break; 388320ae51fSJens Axboe } 389320ae51fSJens Axboe } 390320ae51fSJens Axboe 391320ae51fSJens Axboe if (ret) { 392320ae51fSJens Axboe blk_mq_unregister_disk(disk); 393320ae51fSJens Axboe return ret; 394320ae51fSJens Axboe } 395320ae51fSJens Axboe 396320ae51fSJens Axboe return 0; 397320ae51fSJens Axboe } 398