Commit 45919fbf authored by Bart Van Assche's avatar Bart Van Assche Committed by Jens Axboe
Browse files

null_blk: Enable modifying 'submit_queues' after an instance has been configured



This patch makes it possible to test blk_mq_update_nr_hw_queues() from
inside a VM.

Cc: Christoph Hellwig <hch@infradead.org>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent e29158b4
Loading
Loading
Loading
Loading
+50 −25
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ static ssize_t nullb_device_uint_attr_store(unsigned int *val,
	int result;

	result = kstrtouint(page, 0, &tmp);
	if (result)
	if (result < 0)
		return result;

	*val = tmp;
@@ -241,7 +241,7 @@ static ssize_t nullb_device_ulong_attr_store(unsigned long *val,
	unsigned long tmp;

	result = kstrtoul(page, 0, &tmp);
	if (result)
	if (result < 0)
		return result;

	*val = tmp;
@@ -255,7 +255,7 @@ static ssize_t nullb_device_bool_attr_store(bool *val, const char *page,
	int result;

	result = kstrtobool(page,  &tmp);
	if (result)
	if (result < 0)
		return result;

	*val = tmp;
@@ -263,7 +263,7 @@ static ssize_t nullb_device_bool_attr_store(bool *val, const char *page,
}

/* The following macro should only be used with TYPE = {uint, ulong, bool}. */
#define NULLB_DEVICE_ATTR(NAME, TYPE)						\
#define NULLB_DEVICE_ATTR(NAME, TYPE, APPLY)					\
static ssize_t									\
nullb_device_##NAME##_show(struct config_item *item, char *page)		\
{										\
@@ -274,32 +274,57 @@ static ssize_t \
nullb_device_##NAME##_store(struct config_item *item, const char *page,		\
			    size_t count)					\
{										\
	int (*apply_fn)(struct nullb_device *dev, TYPE new_value) = APPLY;	\
	struct nullb_device *dev = to_nullb_device(item);			\
	TYPE new_value;								\
	int ret;								\
										\
	if (test_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags))			\
		return -EBUSY;							\
	return nullb_device_##TYPE##_attr_store(&dev->NAME, page, count);	\
	ret = nullb_device_##TYPE##_attr_store(&new_value, page, count);	\
	if (ret < 0)								\
		return ret;							\
	if (apply_fn)								\
		ret = apply_fn(dev, new_value);					\
	else if (test_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags)) 		\
		ret = -EBUSY;							\
	if (ret < 0)								\
		return ret;							\
	dev->NAME = new_value;							\
	return count;								\
}										\
CONFIGFS_ATTR(nullb_device_, NAME);

NULLB_DEVICE_ATTR(size, ulong);
NULLB_DEVICE_ATTR(completion_nsec, ulong);
NULLB_DEVICE_ATTR(submit_queues, uint);
NULLB_DEVICE_ATTR(home_node, uint);
NULLB_DEVICE_ATTR(queue_mode, uint);
NULLB_DEVICE_ATTR(blocksize, uint);
NULLB_DEVICE_ATTR(irqmode, uint);
NULLB_DEVICE_ATTR(hw_queue_depth, uint);
NULLB_DEVICE_ATTR(index, uint);
NULLB_DEVICE_ATTR(blocking, bool);
NULLB_DEVICE_ATTR(use_per_node_hctx, bool);
NULLB_DEVICE_ATTR(memory_backed, bool);
NULLB_DEVICE_ATTR(discard, bool);
NULLB_DEVICE_ATTR(mbps, uint);
NULLB_DEVICE_ATTR(cache_size, ulong);
NULLB_DEVICE_ATTR(zoned, bool);
NULLB_DEVICE_ATTR(zone_size, ulong);
NULLB_DEVICE_ATTR(zone_nr_conv, uint);
static int nullb_apply_submit_queues(struct nullb_device *dev,
				     unsigned int submit_queues)
{
	struct nullb *nullb = dev->nullb;
	struct blk_mq_tag_set *set;

	if (!nullb)
		return 0;

	set = nullb->tag_set;
	blk_mq_update_nr_hw_queues(set, submit_queues);
	return set->nr_hw_queues == submit_queues ? 0 : -ENOMEM;
}

NULLB_DEVICE_ATTR(size, ulong, NULL);
NULLB_DEVICE_ATTR(completion_nsec, ulong, NULL);
NULLB_DEVICE_ATTR(submit_queues, uint, nullb_apply_submit_queues);
NULLB_DEVICE_ATTR(home_node, uint, NULL);
NULLB_DEVICE_ATTR(queue_mode, uint, NULL);
NULLB_DEVICE_ATTR(blocksize, uint, NULL);
NULLB_DEVICE_ATTR(irqmode, uint, NULL);
NULLB_DEVICE_ATTR(hw_queue_depth, uint, NULL);
NULLB_DEVICE_ATTR(index, uint, NULL);
NULLB_DEVICE_ATTR(blocking, bool, NULL);
NULLB_DEVICE_ATTR(use_per_node_hctx, bool, NULL);
NULLB_DEVICE_ATTR(memory_backed, bool, NULL);
NULLB_DEVICE_ATTR(discard, bool, NULL);
NULLB_DEVICE_ATTR(mbps, uint, NULL);
NULLB_DEVICE_ATTR(cache_size, ulong, NULL);
NULLB_DEVICE_ATTR(zoned, bool, NULL);
NULLB_DEVICE_ATTR(zone_size, ulong, NULL);
NULLB_DEVICE_ATTR(zone_nr_conv, uint, NULL);

static ssize_t nullb_device_power_show(struct config_item *item, char *page)
{