Patch from Nick Piggin This adds helper functions to start and stop anticipation. drivers/block/as-iosched.c | 96 +++++++++++++++++++++------------------------ 1 files changed, 45 insertions(+), 51 deletions(-) diff -puN drivers/block/as-iosched.c~as-start-stop-anticipation-helpers drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~as-start-stop-anticipation-helpers 2003-02-24 23:53:17.000000000 -0800 +++ 25-akpm/drivers/block/as-iosched.c 2003-02-24 23:53:17.000000000 -0800 @@ -623,9 +623,46 @@ static void as_anticipate_work(void *dat spin_unlock_irqrestore(q->queue_lock, flags); } +static void as_start_anticipation(struct as_data *ad) +{ + struct request_queue *q = ad->q; + unsigned long timeout; + + if (ad->antic_status == ANTIC_OFF) { + ant_stats.anticipate_starts++; + ad->antic_start = jiffies; + } + timeout = ad->antic_start + ad->antic_expire; +#if 0 + /* FIX THIS!!! */ + timeout = min(timeout, ad->current_batch_expires); +#endif + mod_timer(&ad->antic_timer, timeout); + + ad->antic_status = ANTIC_WAIT; + blk_plug_device(q); +} + +static void as_stop_anticipation_notimer(struct as_data *ad) +{ + if (ad->antic_status == ANTIC_WAIT) { + blk_remove_plug(ad->q); + schedule_work(&ad->antic_work); + } + ad->antic_status = ANTIC_FINISHED; +} + +static void as_stop_anticipation(struct as_data *ad) +{ + if (ad->antic_status == ANTIC_WAIT) + del_timer(&ad->antic_timer); + + as_stop_anticipation_notimer(ad); +} + /* * as_anticipate_timeout is the timer function set by - * as_start_anticipate. + * as_start_anticipation. */ static void as_anticipate_timeout(unsigned long data) { @@ -634,13 +671,8 @@ static void as_anticipate_timeout(unsign unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - - ad->antic_status = ANTIC_FINISHED; - - blk_remove_plug(q); - schedule_work(&ad->antic_work); + as_stop_anticipation_notimer(ad); ant_stats.timeouts++; - spin_unlock_irqrestore(q->queue_lock, flags); } @@ -670,8 +702,7 @@ as_close_req(struct as_data *ad, struct #define MAXBACK (512 * 1024) static struct as_rq * -as_choose_req(struct as_data *ad, - struct as_rq *arq1, struct as_rq *arq2) +as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2) { int data_dir; sector_t last, s1, s2, d1, d2; @@ -820,12 +851,7 @@ static void as_update_arq(struct as_data ant_stats.lba_forward_offsets[log2]++; } - if (ad->antic_status == ANTIC_WAIT) { - del_timer(&ad->antic_timer); - blk_remove_plug(ad->q); - schedule_work(&ad->antic_work); - } - ad->antic_status = ANTIC_FINISHED; + as_stop_anticipation(ad); } } @@ -846,10 +872,7 @@ static int as_can_anticipate(struct as_d * In this situation status should really be FINISHED, however * the timer hasn't had the chance to run yet. */ - del_timer(&ad->antic_timer); - ad->antic_status = ANTIC_FINISHED; - blk_remove_plug(ad->q); - schedule_work(&ad->antic_work); + as_stop_anticipation(ad); return 0; } @@ -877,12 +900,9 @@ static int as_can_anticipate(struct as_d */ static int as_dispatch_request(struct as_data *ad) { - struct request_queue *q = ad->q; struct as_rq *arq; const int reads = !list_empty(&ad->fifo_list[READ]); const int writes = !list_empty(&ad->fifo_list[WRITE]); - static unsigned long last_read_id; - static unsigned long last_finished; if (!(reads || writes)) return 0; @@ -905,22 +925,7 @@ static int as_dispatch_request(struct as goto fifo_expired; if (as_can_anticipate(ad, arq)) { - unsigned long timeout; - - if (ad->antic_status == ANTIC_OFF) { - ant_stats.anticipate_starts++; - ad->antic_start = jiffies; - } - timeout = ad->antic_start + ad->antic_expire; -#if 0 - /* FIX THIS!!! */ - timeout = min(timeout, - ad->current_batch_expires); -#endif - mod_timer(&ad->antic_timer, timeout); - - ad->antic_status = ANTIC_WAIT; - blk_plug_device(q); + as_start_anticipation(ad); return 0; } @@ -997,13 +1002,6 @@ fifo_expired: ad->antic_status = ANTIC_OFF; as_move_request(ad, arq); - if (ad->batch_data_dir == READ) { - if (last_read_id != arq->request_id) { - last_read_id = arq->request_id; - } - last_finished = arq->request->sector + arq->request->nr_sectors; - } - return 1; } @@ -1039,12 +1037,8 @@ as_insert_request(request_queue_t *q, st list_add(&rq->queuelist, insert_here); if (!list_empty(ad->dispatch) && rq_data_dir(rq) == READ - && ad->antic_status == ANTIC_WAIT) { - del_timer(&ad->antic_timer); - ad->antic_status = ANTIC_FINISHED; - blk_remove_plug(q); - schedule_work(&ad->antic_work); - } + && ad->antic_status == ANTIC_WAIT) + as_stop_anticipation(ad); return; } _