Re: The difference of request dir between AS and Deadline I/O scheduler?

From: 谢纲
Date: Mon Mar 02 2009 - 23:52:53 EST


On Tue, Mar 3, 2009 at 12:21 PM, Aaron Carroll <aaronc@xxxxxxxxxxxxxxx> wrote:
> ï wrote:
>> Hi,
>>
>> I'm little confused about the defination of request dir in AS and
>> Deadline I/O scheduler.
>> In AS, the request dir is defined by wheher it's sync:
>>
>> data_dir = rq_is_sync(rq);
>>
>> But in Deadline, the requests are grouped by read and write.
>>
>> Why is there the difference since AS is an extension of Deadline?
>> what's the consideration?
>
> I also thought it was silly to have different behaviours, so I tried
> the following patch that makes deadline use sync/async instead of
> read/write. ÂAll the benchmarks I tried showed that performance
> dropped or remained constant at best, so I didn't propose it.
> Maybe you will have more luck...
Hello,
Which benchmark tool do you use? I'd like to have a try. I think the
I/O behavior is an important factor which can affect the performance.

Thanks,
>
> --
>
> From: Aaron Carroll <aaronc@xxxxxxxxxxxxxxx>
> Date: Sat, 4 Oct 2008 11:58:23 +1000
> Subject: [PATCH] deadline-iosched: support SYNC bio/request flag
>
> Support sync/async requests in deadline rather than read/write, as is
> done in AS and CFQ.
>
> Signed-off-by: Aaron Carroll <aaronc@xxxxxxxxxxxxxxx>
> ---
> Âblock/deadline-iosched.c | Â 63 ++++++++++++++++++++++++---------------------
> Â1 files changed, 34 insertions(+), 29 deletions(-)
>
> diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
> index 342448c..b2cfd47 100644
> --- a/block/deadline-iosched.c
> +++ b/block/deadline-iosched.c
> @@ -23,6 +23,11 @@ static const int writes_starved = 2; Â Â/* max times reads can starve a write */
> Âstatic const int fifo_batch = 16; Â Â Â /* # of sequential requests treated as one
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â by the above parameters. For throughput. */
>
> +enum {
> + Â Â Â REQ_ASYNC,
> + Â Â Â REQ_SYNC,
> +};
> +
> Âstruct deadline_data {
> Â Â Â Â/*
> Â Â Â Â * run time data
> @@ -53,7 +58,7 @@ struct deadline_data {
>
> Âstatic void deadline_move_request(struct deadline_data *, struct request *);
>
> -#define RQ_RB_ROOT(dd, rq) Â Â (&(dd)->sort_list[rq_data_dir((rq))])
> +#define RQ_RB_ROOT(dd, rq) Â Â (&(dd)->sort_list[rq_is_sync((rq))])
>
> Â/*
> Â* get the request after `rq' in sector-sorted order
> @@ -86,7 +91,7 @@ retry:
> Âstatic inline void
> Âdeadline_del_rq_rb(struct deadline_data *dd, struct request *rq)
> Â{
> - Â Â Â const int data_dir = rq_data_dir(rq);
> + Â Â Â const int data_dir = rq_is_sync(rq);
>
> Â Â Â Âif (dd->next_rq[data_dir] == rq)
> Â Â Â Â Â Â Â Âdd->next_rq[data_dir] = deadline_latter_request(rq);
> @@ -101,7 +106,7 @@ static void
> Âdeadline_add_request(struct request_queue *q, struct request *rq)
> Â{
> Â Â Â Âstruct deadline_data *dd = q->elevator->elevator_data;
> - Â Â Â const int data_dir = rq_data_dir(rq);
> + Â Â Â const int data_dir = rq_is_sync(rq);
>
> Â Â Â Âdeadline_add_rq_rb(dd, rq);
>
> @@ -206,10 +211,10 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq)
> Âstatic void
> Âdeadline_move_request(struct deadline_data *dd, struct request *rq)
> Â{
> - Â Â Â const int data_dir = rq_data_dir(rq);
> + Â Â Â const int data_dir = rq_is_sync(rq);
>
> - Â Â Â dd->next_rq[READ] = NULL;
> - Â Â Â dd->next_rq[WRITE] = NULL;
> + Â Â Â dd->next_rq[REQ_SYNC] = NULL;
> + Â Â Â dd->next_rq[REQ_ASYNC] = NULL;
> Â Â Â Âdd->next_rq[data_dir] = deadline_latter_request(rq);
>
> Â Â Â Âdd->last_sector = rq->sector + rq->nr_sectors;
> @@ -245,18 +250,18 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
> Âstatic int deadline_dispatch_requests(struct request_queue *q, int force)
> Â{
> Â Â Â Âstruct deadline_data *dd = q->elevator->elevator_data;
> - Â Â Â const int reads = !list_empty(&dd->fifo_list[READ]);
> - Â Â Â const int writes = !list_empty(&dd->fifo_list[WRITE]);
> + Â Â Â const int reads = !list_empty(&dd->fifo_list[REQ_SYNC]);
> + Â Â Â const int writes = !list_empty(&dd->fifo_list[REQ_ASYNC]);
> Â Â Â Âstruct request *rq;
> Â Â Â Âint data_dir;
>
> Â Â Â Â/*
> Â Â Â Â * batches are currently reads XOR writes
> Â Â Â Â */
> - Â Â Â if (dd->next_rq[WRITE])
> - Â Â Â Â Â Â Â rq = dd->next_rq[WRITE];
> + Â Â Â if (dd->next_rq[REQ_ASYNC])
> + Â Â Â Â Â Â Â rq = dd->next_rq[REQ_ASYNC];
> Â Â Â Âelse
> - Â Â Â Â Â Â Â rq = dd->next_rq[READ];
> + Â Â Â Â Â Â Â rq = dd->next_rq[REQ_SYNC];
>
> Â Â Â Âif (rq) {
> Â Â Â Â Â Â Â Â/* we have a "next request" */
> @@ -276,12 +281,12 @@ static int deadline_dispatch_requests(struct request_queue *q, int force)
> Â Â Â Â */
>
> Â Â Â Âif (reads) {
> - Â Â Â Â Â Â Â BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[READ]));
> + Â Â Â Â Â Â Â BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[REQ_SYNC]));
>
> Â Â Â Â Â Â Â Âif (writes && (dd->starved++ >= dd->writes_starved))
> Â Â Â Â Â Â Â Â Â Â Â Âgoto dispatch_writes;
>
> - Â Â Â Â Â Â Â data_dir = READ;
> + Â Â Â Â Â Â Â data_dir = REQ_SYNC;
>
> Â Â Â Â Â Â Â Âgoto dispatch_find_request;
> Â Â Â Â}
> @@ -292,11 +297,11 @@ static int deadline_dispatch_requests(struct request_queue *q, int force)
>
> Â Â Â Âif (writes) {
> Âdispatch_writes:
> - Â Â Â Â Â Â Â BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[WRITE]));
> + Â Â Â Â Â Â Â BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[REQ_ASYNC]));
>
> Â Â Â Â Â Â Â Âdd->starved = 0;
>
> - Â Â Â Â Â Â Â data_dir = WRITE;
> + Â Â Â Â Â Â Â data_dir = REQ_ASYNC;
>
> Â Â Â Â Â Â Â Âgoto dispatch_find_request;
> Â Â Â Â}
> @@ -338,16 +343,16 @@ static int deadline_queue_empty(struct request_queue *q)
> Â{
> Â Â Â Âstruct deadline_data *dd = q->elevator->elevator_data;
>
> - Â Â Â return list_empty(&dd->fifo_list[WRITE])
> - Â Â Â Â Â Â Â && list_empty(&dd->fifo_list[READ]);
> + Â Â Â return list_empty(&dd->fifo_list[REQ_ASYNC])
> + Â Â Â Â Â Â Â && list_empty(&dd->fifo_list[REQ_SYNC]);
> Â}
>
> Âstatic void deadline_exit_queue(elevator_t *e)
> Â{
> Â Â Â Âstruct deadline_data *dd = e->elevator_data;
>
> - Â Â Â BUG_ON(!list_empty(&dd->fifo_list[READ]));
> - Â Â Â BUG_ON(!list_empty(&dd->fifo_list[WRITE]));
> + Â Â Â BUG_ON(!list_empty(&dd->fifo_list[REQ_SYNC]));
> + Â Â Â BUG_ON(!list_empty(&dd->fifo_list[REQ_ASYNC]));
>
> Â Â Â Âkfree(dd);
> Â}
> @@ -363,12 +368,12 @@ static void *deadline_init_queue(struct request_queue *q)
> Â Â Â Âif (!dd)
> Â Â Â Â Â Â Â Âreturn NULL;
>
> - Â Â Â INIT_LIST_HEAD(&dd->fifo_list[READ]);
> - Â Â Â INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
> - Â Â Â dd->sort_list[READ] = RB_ROOT;
> - Â Â Â dd->sort_list[WRITE] = RB_ROOT;
> - Â Â Â dd->fifo_expire[READ] = read_expire;
> - Â Â Â dd->fifo_expire[WRITE] = write_expire;
> + Â Â Â INIT_LIST_HEAD(&dd->fifo_list[REQ_SYNC]);
> + Â Â Â INIT_LIST_HEAD(&dd->fifo_list[REQ_ASYNC]);
> + Â Â Â dd->sort_list[REQ_SYNC] = RB_ROOT;
> + Â Â Â dd->sort_list[REQ_ASYNC] = RB_ROOT;
> + Â Â Â dd->fifo_expire[REQ_SYNC] = read_expire;
> + Â Â Â dd->fifo_expire[REQ_ASYNC] = write_expire;
> Â Â Â Âdd->writes_starved = writes_starved;
> Â Â Â Âdd->front_merges = 1;
> Â Â Â Âdd->fifo_batch = fifo_batch;
> @@ -403,8 +408,8 @@ static ssize_t __FUNC(elevator_t *e, char *page) Â Â Â Â Â Â Â Â Â Â\
> Â Â Â Â Â Â Â Â__data = jiffies_to_msecs(__data); Â Â Â Â Â Â Â Â Â Â Â\
> Â Â Â Âreturn deadline_var_show(__data, (page)); Â Â Â Â Â Â Â Â Â Â Â \
> Â}
> -SHOW_FUNCTION(deadline_read_expire_show, dd->fifo_expire[READ], 1);
> -SHOW_FUNCTION(deadline_write_expire_show, dd->fifo_expire[WRITE], 1);
> +SHOW_FUNCTION(deadline_read_expire_show, dd->fifo_expire[REQ_SYNC], 1);
> +SHOW_FUNCTION(deadline_write_expire_show, dd->fifo_expire[REQ_ASYNC], 1);
> ÂSHOW_FUNCTION(deadline_writes_starved_show, dd->writes_starved, 0);
> ÂSHOW_FUNCTION(deadline_front_merges_show, dd->front_merges, 0);
> ÂSHOW_FUNCTION(deadline_fifo_batch_show, dd->fifo_batch, 0);
> @@ -426,8 +431,8 @@ static ssize_t __FUNC(elevator_t *e, const char *page, size_t count) Â Â Â Â\
> Â Â Â Â Â Â Â Â*(__PTR) = __data; Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â\
> Â Â Â Âreturn ret; Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â \
> Â}
> -STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
> -STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);
> +STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[REQ_SYNC], 0, INT_MAX, 1);
> +STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[REQ_ASYNC], 0, INT_MAX, 1);
> ÂSTORE_FUNCTION(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX, 0);
> ÂSTORE_FUNCTION(deadline_front_merges_store, &dd->front_merges, 0, 1, 0);
> ÂSTORE_FUNCTION(deadline_fifo_batch_store, &dd->fifo_batch, 0, INT_MAX, 0);
>



--
Xie Gang
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/