Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67aec14c authored by Jens Axboe's avatar Jens Axboe
Browse files

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: default avatarJens Axboe <axboe@fb.com>
parent 22302375
Loading
Loading
Loading
Loading
+83 −19
Original line number Original line Diff line number Diff line
@@ -327,6 +327,42 @@ static struct kobj_type blk_mq_hw_ktype = {
	.release	= blk_mq_sysfs_release,
	.release	= blk_mq_sysfs_release,
};
};


void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx)
{
	struct blk_mq_ctx *ctx;
	int i;

	if (!hctx->nr_ctx || !(hctx->flags & BLK_MQ_F_SYSFS_UP))
		return;

	hctx_for_each_ctx(hctx, ctx, i)
		kobject_del(&ctx->kobj);

	kobject_del(&hctx->kobj);
}

int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
{
	struct request_queue *q = hctx->queue;
	struct blk_mq_ctx *ctx;
	int i, ret;

	if (!hctx->nr_ctx || !(hctx->flags & BLK_MQ_F_SYSFS_UP))
		return 0;

	ret = kobject_add(&hctx->kobj, &q->mq_kobj, "%u", hctx->queue_num);
	if (ret)
		return ret;

	hctx_for_each_ctx(hctx, ctx, i) {
		ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
		if (ret)
			break;
	}

	return ret;
}

void blk_mq_unregister_disk(struct gendisk *disk)
void blk_mq_unregister_disk(struct gendisk *disk)
{
{
	struct request_queue *q = disk->queue;
	struct request_queue *q = disk->queue;
@@ -335,11 +371,11 @@ void blk_mq_unregister_disk(struct gendisk *disk)
	int i, j;
	int i, j;


	queue_for_each_hw_ctx(q, hctx, i) {
	queue_for_each_hw_ctx(q, hctx, i) {
		hctx_for_each_ctx(hctx, ctx, j) {
		blk_mq_unregister_hctx(hctx);
			kobject_del(&ctx->kobj);

		hctx_for_each_ctx(hctx, ctx, j)
			kobject_put(&ctx->kobj);
			kobject_put(&ctx->kobj);
		}

		kobject_del(&hctx->kobj);
		kobject_put(&hctx->kobj);
		kobject_put(&hctx->kobj);
	}
	}


@@ -350,15 +386,30 @@ void blk_mq_unregister_disk(struct gendisk *disk)
	kobject_put(&disk_to_dev(disk)->kobj);
	kobject_put(&disk_to_dev(disk)->kobj);
}
}


static void blk_mq_sysfs_init(struct request_queue *q)
{
	struct blk_mq_hw_ctx *hctx;
	struct blk_mq_ctx *ctx;
	int i, j;

	kobject_init(&q->mq_kobj, &blk_mq_ktype);

	queue_for_each_hw_ctx(q, hctx, i) {
		kobject_init(&hctx->kobj, &blk_mq_hw_ktype);

		hctx_for_each_ctx(hctx, ctx, j)
			kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);
	}
}

int blk_mq_register_disk(struct gendisk *disk)
int blk_mq_register_disk(struct gendisk *disk)
{
{
	struct device *dev = disk_to_dev(disk);
	struct device *dev = disk_to_dev(disk);
	struct request_queue *q = disk->queue;
	struct request_queue *q = disk->queue;
	struct blk_mq_hw_ctx *hctx;
	struct blk_mq_hw_ctx *hctx;
	struct blk_mq_ctx *ctx;
	int ret, i;
	int ret, i, j;


	kobject_init(&q->mq_kobj, &blk_mq_ktype);
	blk_mq_sysfs_init(q);


	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)
@@ -367,21 +418,11 @@ int blk_mq_register_disk(struct gendisk *disk)
	kobject_uevent(&q->mq_kobj, KOBJ_ADD);
	kobject_uevent(&q->mq_kobj, KOBJ_ADD);


	queue_for_each_hw_ctx(q, hctx, i) {
	queue_for_each_hw_ctx(q, hctx, i) {
		kobject_init(&hctx->kobj, &blk_mq_hw_ktype);
		hctx->flags |= BLK_MQ_F_SYSFS_UP;
		ret = kobject_add(&hctx->kobj, &q->mq_kobj, "%u", i);
		ret = blk_mq_register_hctx(hctx);
		if (ret)
			break;

		if (!hctx->nr_ctx)
			continue;

		hctx_for_each_ctx(hctx, ctx, j) {
			kobject_init(&ctx->kobj, &blk_mq_ctx_ktype);
			ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
		if (ret)
		if (ret)
			break;
			break;
	}
	}
	}


	if (ret) {
	if (ret) {
		blk_mq_unregister_disk(disk);
		blk_mq_unregister_disk(disk);
@@ -390,3 +431,26 @@ int blk_mq_register_disk(struct gendisk *disk)


	return 0;
	return 0;
}
}

void blk_mq_sysfs_unregister(struct request_queue *q)
{
	struct blk_mq_hw_ctx *hctx;
	int i;

	queue_for_each_hw_ctx(q, hctx, i)
		blk_mq_unregister_hctx(hctx);
}

int blk_mq_sysfs_register(struct request_queue *q)
{
	struct blk_mq_hw_ctx *hctx;
	int i, ret = 0;

	queue_for_each_hw_ctx(q, hctx, i) {
		ret = blk_mq_register_hctx(hctx);
		if (ret)
			break;
	}

	return ret;
}
+4 −0
Original line number Original line Diff line number Diff line
@@ -1924,6 +1924,8 @@ static void blk_mq_queue_reinit(struct request_queue *q)
{
{
	blk_mq_freeze_queue(q);
	blk_mq_freeze_queue(q);


	blk_mq_sysfs_unregister(q);

	blk_mq_update_queue_map(q->mq_map, q->nr_hw_queues);
	blk_mq_update_queue_map(q->mq_map, q->nr_hw_queues);


	/*
	/*
@@ -1934,6 +1936,8 @@ static void blk_mq_queue_reinit(struct request_queue *q)


	blk_mq_map_swqueue(q);
	blk_mq_map_swqueue(q);


	blk_mq_sysfs_register(q);

	blk_mq_unfreeze_queue(q);
	blk_mq_unfreeze_queue(q);
}
}


+6 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,12 @@ extern unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set);
extern int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues);
extern int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues);
extern int blk_mq_hw_queue_to_node(unsigned int *map, unsigned int);
extern int blk_mq_hw_queue_to_node(unsigned int *map, unsigned int);


/*
 * sysfs helpers
 */
extern int blk_mq_sysfs_register(struct request_queue *q);
extern void blk_mq_sysfs_unregister(struct request_queue *q);

/*
/*
 * Basic implementation of sparser bitmap, allowing the user to spread
 * Basic implementation of sparser bitmap, allowing the user to spread
 * the bits over more cachelines.
 * the bits over more cachelines.
+1 −0
Original line number Original line Diff line number Diff line
@@ -130,6 +130,7 @@ enum {
	BLK_MQ_F_SHOULD_SORT	= 1 << 1,
	BLK_MQ_F_SHOULD_SORT	= 1 << 1,
	BLK_MQ_F_TAG_SHARED	= 1 << 2,
	BLK_MQ_F_TAG_SHARED	= 1 << 2,
	BLK_MQ_F_SG_MERGE	= 1 << 3,
	BLK_MQ_F_SG_MERGE	= 1 << 3,
	BLK_MQ_F_SYSFS_UP	= 1 << 4,


	BLK_MQ_S_STOPPED	= 0,
	BLK_MQ_S_STOPPED	= 0,
	BLK_MQ_S_TAG_ACTIVE	= 1,
	BLK_MQ_S_TAG_ACTIVE	= 1,