Commit 8023e144 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: move the poll flag to queue_limits



Move the poll flag into the queue_limits feature field so that it can
be set atomically with the queue frozen.

Stacking drivers are simplified in that they now can simply set the
flag, and blk_stack_limits will clear it when the features is not
supported by any of the underlying devices.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDamien Le Moal <dlemoal@kernel.org>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Link: https://lore.kernel.org/r/20240617060532.127975-22-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent f467fee4
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -791,7 +791,7 @@ void submit_bio_noacct(struct bio *bio)
		}
	}

	if (!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
	if (!(q->limits.features & BLK_FEAT_POLL))
		bio_clear_polled(bio);

	switch (bio_op(bio)) {
@@ -915,8 +915,7 @@ int bio_poll(struct bio *bio, struct io_comp_batch *iob, unsigned int flags)
		return 0;

	q = bdev_get_queue(bdev);
	if (cookie == BLK_QC_T_NONE ||
	    !test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
	if (cookie == BLK_QC_T_NONE || !(q->limits.features & BLK_FEAT_POLL))
		return 0;

	blk_flush_plug(current->plug, false);
+0 −1
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@ static const char *const blk_queue_flag_name[] = {
	QUEUE_FLAG_NAME(NOXMERGES),
	QUEUE_FLAG_NAME(SAME_FORCE),
	QUEUE_FLAG_NAME(INIT_DONE),
	QUEUE_FLAG_NAME(POLL),
	QUEUE_FLAG_NAME(STATS),
	QUEUE_FLAG_NAME(REGISTERED),
	QUEUE_FLAG_NAME(QUIESCED),
+18 −13
Original line number Diff line number Diff line
@@ -4109,6 +4109,12 @@ void blk_mq_release(struct request_queue *q)
	blk_mq_sysfs_deinit(q);
}

static bool blk_mq_can_poll(struct blk_mq_tag_set *set)
{
	return set->nr_maps > HCTX_TYPE_POLL &&
		set->map[HCTX_TYPE_POLL].nr_queues;
}

struct request_queue *blk_mq_alloc_queue(struct blk_mq_tag_set *set,
		struct queue_limits *lim, void *queuedata)
{
@@ -4119,6 +4125,8 @@ struct request_queue *blk_mq_alloc_queue(struct blk_mq_tag_set *set,
	if (!lim)
		lim = &default_lim;
	lim->features |= BLK_FEAT_IO_STAT | BLK_FEAT_NOWAIT;
	if (blk_mq_can_poll(set))
		lim->features |= BLK_FEAT_POLL;

	q = blk_alloc_queue(lim, set->numa_node);
	if (IS_ERR(q))
@@ -4273,17 +4281,6 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
	mutex_unlock(&q->sysfs_lock);
}

static void blk_mq_update_poll_flag(struct request_queue *q)
{
	struct blk_mq_tag_set *set = q->tag_set;

	if (set->nr_maps > HCTX_TYPE_POLL &&
	    set->map[HCTX_TYPE_POLL].nr_queues)
		blk_queue_flag_set(QUEUE_FLAG_POLL, q);
	else
		blk_queue_flag_clear(QUEUE_FLAG_POLL, q);
}

int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
		struct request_queue *q)
{
@@ -4311,7 +4308,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
	q->tag_set = set;

	q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
	blk_mq_update_poll_flag(q);

	INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work);
	INIT_LIST_HEAD(&q->flush_list);
@@ -4798,8 +4794,10 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
fallback:
	blk_mq_update_queue_map(set);
	list_for_each_entry(q, &set->tag_list, tag_set_list) {
		struct queue_limits lim;

		blk_mq_realloc_hw_ctxs(set, q);
		blk_mq_update_poll_flag(q);

		if (q->nr_hw_queues != set->nr_hw_queues) {
			int i = prev_nr_hw_queues;

@@ -4811,6 +4809,13 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
			set->nr_hw_queues = prev_nr_hw_queues;
			goto fallback;
		}
		lim = queue_limits_start_update(q);
		if (blk_mq_can_poll(set))
			lim.features |= BLK_FEAT_POLL;
		else
			lim.features &= ~BLK_FEAT_POLL;
		if (queue_limits_commit_update(q, &lim) < 0)
			pr_warn("updating the poll flag failed\n");
		blk_mq_map_swqueue(q);
	}

+6 −4
Original line number Diff line number Diff line
@@ -460,13 +460,15 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
	t->features |= (b->features & BLK_FEAT_INHERIT_MASK);

	/*
	 * BLK_FEAT_NOWAIT needs to be supported both by the stacking driver
	 * and all underlying devices.  The stacking driver sets the flag
	 * before stacking the limits, and this will clear the flag if any
	 * of the underlying devices does not support it.
	 * BLK_FEAT_NOWAIT and BLK_FEAT_POLL need to be supported both by the
	 * stacking driver and all underlying devices.  The stacking driver sets
	 * the flags before stacking the limits, and this will clear the flags
	 * if any of the underlying devices does not support it.
	 */
	if (!(b->features & BLK_FEAT_NOWAIT))
		t->features &= ~BLK_FEAT_NOWAIT;
	if (!(b->features & BLK_FEAT_POLL))
		t->features &= ~BLK_FEAT_POLL;

	t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
	t->max_user_sectors = min_not_zero(t->max_user_sectors,
+2 −2
Original line number Diff line number Diff line
@@ -394,13 +394,13 @@ static ssize_t queue_poll_delay_store(struct request_queue *q, const char *page,

static ssize_t queue_poll_show(struct request_queue *q, char *page)
{
	return queue_var_show(test_bit(QUEUE_FLAG_POLL, &q->queue_flags), page);
	return queue_var_show(q->limits.features & BLK_FEAT_POLL, page);
}

static ssize_t queue_poll_store(struct request_queue *q, const char *page,
				size_t count)
{
	if (!test_bit(QUEUE_FLAG_POLL, &q->queue_flags))
	if (!(q->limits.features & BLK_FEAT_POLL))
		return -EINVAL;
	pr_info_ratelimited("writes to the poll attribute are ignored.\n");
	pr_info_ratelimited("please use driver specific parameters instead.\n");
Loading