Patch from Nick Piggin This is pretty well correct I think. If we get a write from the process we are anticipating a read from, then the read isn't sync, right? I still don't think this will help the Oracle load, however. drivers/block/as-iosched.c | 68 ++++++++++++++++++++++++--------------------- 1 files changed, 37 insertions(+), 31 deletions(-) diff -puN drivers/block/as-iosched.c~as-break-anticipation-on-write drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~as-break-anticipation-on-write Mon Feb 24 15:09:23 2003 +++ 25-akpm/drivers/block/as-iosched.c Mon Feb 24 15:09:23 2003 @@ -33,6 +33,7 @@ struct ant_stats { int expired_fifo_writes; int close_requests; int matching_ids; + int broken_by_write; int ant_delay_hist[100]; /* milliseconds */ @@ -749,17 +750,23 @@ elevator_wrap: } /* - * as_antic_req, has @ad been anticipating this @arq? + * as_antic_req returns true if we have been anticipating this request. + * + * It also returns true if the process against which we are anticipating + * submits a write - that's presumably an fsync, O_SYNC write, etc. We want to + * dispatch it ASAP, because we know that application will not be submitting + * any new reads. */ -static int -as_antic_req(struct as_data *ad, struct as_rq *arq) +static int as_antic_req(struct as_data *ad, struct as_rq *arq) { - if (as_close_req(ad, arq)) { + if (rq_data_dir(arq->request) == READ && as_close_req(ad, arq)) { ant_stats.close_requests++; return 1; } if (ad->current_id == arq->request_id) { ant_stats.matching_ids++; + if (rq_data_dir(arq->request) == WRITE) + ant_stats.broken_by_write++; return 1; } return 0; @@ -770,12 +777,10 @@ as_antic_req(struct as_data *ad, struct * the sort_list. This function keeps caches up to date, and checks if the * request might be one we are "anticipating" */ -static void -as_update_arq(struct as_data *ad, struct as_rq *arq) +static void as_update_arq(struct as_data *ad, struct as_rq *arq) { const int data_dir = rq_data_dir(arq->request); - if (data_dir == READ) ant_stats.reads++; else @@ -784,11 +789,12 @@ as_update_arq(struct as_data *ad, struct /* keep the next_arq cache up to date */ ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]); - /* have we been anticipating this request? */ - if (ad->antic_status != ANTIC_OFF && data_dir == READ - && as_antic_req(ad, arq)) { - - /* statistics stuff */ + /* + * have we been anticipating this request? + * or does it come from the same process as the one we are anticipating + * for? + */ + if (ad->antic_status != ANTIC_OFF && as_antic_req(ad, arq)) { sector_t last = ad->last_sector[data_dir]; sector_t this = arq->request->sector; unsigned long delay = jiffies - ad->antic_start; @@ -796,24 +802,25 @@ as_update_arq(struct as_data *ad, struct int neg; int log2; - if (delay >= ARRAY_SIZE(ant_stats.ant_delay_hist)) - delay = ARRAY_SIZE(ant_stats.ant_delay_hist) - 1; - ant_stats.ant_delay_hist[delay]++; - ant_stats.anticipate_hits++; - - lba_offset = this - last; - neg = 0; - if (lba_offset < 0) { - lba_offset = -lba_offset; - neg = 1; + if (data_dir == READ) { + if (delay >= ARRAY_SIZE(ant_stats.ant_delay_hist)) + delay = ARRAY_SIZE(ant_stats.ant_delay_hist)-1; + ant_stats.ant_delay_hist[delay]++; + ant_stats.anticipate_hits++; + + lba_offset = this - last; + neg = 0; + if (lba_offset < 0) { + lba_offset = -lba_offset; + neg = 1; + } + log2 = ffs(lba_offset); + BUG_ON(log2 >= 32); + if (neg) + ant_stats.lba_backward_offsets[log2]++; + else + ant_stats.lba_forward_offsets[log2]++; } - log2 = ffs(lba_offset); - BUG_ON(log2 >= 32); - if (neg) - ant_stats.lba_backward_offsets[log2]++; - else - ant_stats.lba_forward_offsets[log2]++; - del_timer(&ad->antic_timer); ad->antic_status = ANTIC_FINISHED; if (arq) @@ -826,8 +833,7 @@ as_update_arq(struct as_data *ad, struct * can_start_anticipation indicates weather we should either run arq * or keep anticipating a better request. */ -static int -can_start_anticipation(struct as_data *ad, struct as_rq *arq) +static int can_start_anticipation(struct as_data *ad, struct as_rq *arq) { if (ad->antic_status == ANTIC_FINISHED) /* _