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

Commit bf09ce56 authored by Damien Le Moal's avatar Damien Le Moal Committed by Jens Axboe
Browse files

mq-deadline: Introduce dispatch helpers



Avoid directly referencing the next_rq and fifo_list arrays using the
helper functions deadline_next_request() and deadline_fifo_request() to
facilitate changes in the dispatch request selection in
__dd_dispatch_request() for zoned block devices.

Signed-off-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: default avatarBart Van Assche <Bart.VanAssche@wdc.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 6cc77e9c
Loading
Loading
Loading
Loading
+37 −8
Original line number Original line Diff line number Diff line
@@ -191,6 +191,35 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
	return 0;
	return 0;
}
}


/*
 * For the specified data direction, return the next request to
 * dispatch using arrival ordered lists.
 */
static struct request *
deadline_fifo_request(struct deadline_data *dd, int data_dir)
{
	if (WARN_ON_ONCE(data_dir != READ && data_dir != WRITE))
		return NULL;

	if (list_empty(&dd->fifo_list[data_dir]))
		return NULL;

	return rq_entry_fifo(dd->fifo_list[data_dir].next);
}

/*
 * For the specified data direction, return the next request to
 * dispatch using sector position sorted lists.
 */
static struct request *
deadline_next_request(struct deadline_data *dd, int data_dir)
{
	if (WARN_ON_ONCE(data_dir != READ && data_dir != WRITE))
		return NULL;

	return dd->next_rq[data_dir];
}

/*
/*
 * deadline_dispatch_requests selects the best request according to
 * deadline_dispatch_requests selects the best request according to
 * read/write expire, fifo_batch, etc
 * read/write expire, fifo_batch, etc
@@ -198,7 +227,7 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
static struct request *__dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
static struct request *__dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
{
{
	struct deadline_data *dd = hctx->queue->elevator->elevator_data;
	struct deadline_data *dd = hctx->queue->elevator->elevator_data;
	struct request *rq;
	struct request *rq, *next_rq;
	bool reads, writes;
	bool reads, writes;
	int data_dir;
	int data_dir;


@@ -214,10 +243,9 @@ static struct request *__dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
	/*
	/*
	 * batches are currently reads XOR writes
	 * batches are currently reads XOR writes
	 */
	 */
	if (dd->next_rq[WRITE])
	rq = deadline_next_request(dd, WRITE);
		rq = dd->next_rq[WRITE];
	if (!rq)
	else
		rq = deadline_next_request(dd, READ);
		rq = dd->next_rq[READ];


	if (rq && dd->batching < dd->fifo_batch)
	if (rq && dd->batching < dd->fifo_batch)
		/* we have a next request are still entitled to batch */
		/* we have a next request are still entitled to batch */
@@ -260,19 +288,20 @@ static struct request *__dd_dispatch_request(struct blk_mq_hw_ctx *hctx)
	/*
	/*
	 * we are not running a batch, find best request for selected data_dir
	 * we are not running a batch, find best request for selected data_dir
	 */
	 */
	if (deadline_check_fifo(dd, data_dir) || !dd->next_rq[data_dir]) {
	next_rq = deadline_next_request(dd, data_dir);
	if (deadline_check_fifo(dd, data_dir) || !next_rq) {
		/*
		/*
		 * A deadline has expired, the last request was in the other
		 * A deadline has expired, the last request was in the other
		 * direction, or we have run out of higher-sectored requests.
		 * direction, or we have run out of higher-sectored requests.
		 * Start again from the request with the earliest expiry time.
		 * Start again from the request with the earliest expiry time.
		 */
		 */
		rq = rq_entry_fifo(dd->fifo_list[data_dir].next);
		rq = deadline_fifo_request(dd, data_dir);
	} else {
	} else {
		/*
		/*
		 * The last req was the same dir and we have a next request in
		 * The last req was the same dir and we have a next request in
		 * sort order. No expired requests so continue on from here.
		 * sort order. No expired requests so continue on from here.
		 */
		 */
		rq = dd->next_rq[data_dir];
		rq = next_rq;
	}
	}


	dd->batching = 0;
	dd->batching = 0;