On 11/16/18 11:28 AM, Ming Lei wrote: ... > > +struct blk_mq_kobj { > + struct kobject kobj; > +}; > + > static void blk_mq_sysfs_release(struct kobject *kobj) > { > + struct blk_mq_kobj *mq_kobj = container_of(kobj, struct blk_mq_kobj, > + kobj); > + kfree(mq_kobj); > +} > + ... > > -void blk_mq_sysfs_init(struct request_queue *q) > +int blk_mq_sysfs_init(struct request_queue *q) > { > struct blk_mq_ctx *ctx; > int cpu; > + struct blk_mq_kobj *mq_kobj; > + > + mq_kobj = kzalloc(sizeof(struct blk_mq_kobj), GFP_KERNEL); > + if (!mq_kobj) > + return -ENOMEM; > > - kobject_init(&q->mq_kobj, &blk_mq_ktype); > + kobject_init(&mq_kobj->kobj, &blk_mq_ktype); > > for_each_possible_cpu(cpu) { > - ctx = per_cpu_ptr(q->queue_ctx, cpu); > + ctx = kzalloc_node(sizeof(*ctx), GFP_KERNEL, cpu_to_node(cpu)); > + if (!ctx) > + goto fail; > + *per_cpu_ptr(q->queue_ctx, cpu) = ctx; > kobject_init(&ctx->kobj, &blk_mq_ctx_ktype); > } > + q->mq_kobj = &mq_kobj->kobj; > + return 0; > + > + fail: > + for_each_possible_cpu(cpu) { > + ctx = *per_cpu_ptr(q->queue_ctx, cpu); > + if (ctx) > + kobject_put(&ctx->kobj); > + } > + kobject_put(&mq_kobj->kobj); > + return -ENOMEM; > } blk_mq_kobj looks meaningless, why do we need it, or do I miss something ? And maybe we should allocate ctx in blk_mq_init_allocated_queue. Thanks Jianchao