From: Nick Piggin This patch changes the queue_notready hack to be nicer. IIRC when the hack was done our state machine wasn't adequately able to handle what we wanted to do. Now it can. Upshot is that requests have a bigger merge window, and we choose the next request later, which would sometimes result in a better choice. drivers/block/as-iosched.c | 31 ++++++++++++++++++++++++------- 1 files changed, 24 insertions(+), 7 deletions(-) diff -puN drivers/block/as-iosched.c~as-queue_notready-cleanup drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~as-queue_notready-cleanup 2003-03-28 21:53:21.000000000 -0800 +++ 25-akpm/drivers/block/as-iosched.c 2003-03-28 21:53:21.000000000 -0800 @@ -1059,14 +1059,14 @@ static void as_move_to_dispatch(struct a * read/write expire, batch expire, etc, and moves it to the dispatch * queue. Returns 1 if a request was found, 0 otherwise. */ -static int as_dispatch_request(struct as_data *ad) +static struct as_rq *__as_dispatch_request(struct as_data *ad) { struct as_rq *arq; const int reads = !list_empty(&ad->fifo_list[READ]); const int writes = !list_empty(&ad->fifo_list[WRITE]); if (!(reads || writes)) - return 0; + return NULL; if (!(reads && writes && as_batch_expired(ad)) ) { /* @@ -1080,7 +1080,7 @@ static int as_dispatch_request(struct as if (as_can_anticipate(ad, arq)) { as_antic_waitreq(ad); - return 0; + return NULL; } } @@ -1130,7 +1130,7 @@ dispatch_writes: } BUG(); - return 0; + return NULL; dispatch_request: /* @@ -1146,9 +1146,20 @@ fifo_expired: /* * arq is the selected appropriate request. */ - as_move_to_dispatch(ad, arq); - return 1; + return arq; +} + +static inline int as_dispatch_request(struct as_data *ad) +{ + struct as_rq *arq; + arq = __as_dispatch_request(ad); + if (arq) { + as_move_to_dispatch(ad, arq); + return 1; + } + + return 0; } static struct request *as_next_request(request_queue_t *q) @@ -1264,11 +1275,17 @@ static int as_queue_notready(request_que goto out; } - if (!as_dispatch_request(ad)) { + if (!__as_dispatch_request(ad)) { ret = 1; goto out; } + /* + * OK, force the next call to elv_next_request to return !NULL. This + * works around drivers that assume elv_queue_empty == FALSE means + * the next elv_next_request will return a request. + * */ + ad->antic_status = ANTIC_FINISHED; out: return ret; } _