From: Nick Piggin The problem was last_request_pos being reset to the new request before being used to calculate the seek delta. Stupid mistake - I have seen it before, but I guess either I forgot to fix it or it crept back in. Also a few small tweaks to improve seeky loads. Anyway, previously the regressed rawread workload would get ~600K/s with antic_expire = 10, ~900K/s with antic_expire = 0. Now there isn't a big difference either way at ~900K/s (I didn't bother doing a full run, just looked at vmstat output because its consistent). drivers/block/as-iosched.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-) diff -puN drivers/block/as-iosched.c~as-fix-seeky-loads drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~as-fix-seeky-loads 2003-06-11 18:47:19.000000000 -0700 +++ 25-akpm/drivers/block/as-iosched.c 2003-06-11 18:47:19.000000000 -0700 @@ -721,13 +721,13 @@ static int as_close_req(struct as_data * delay = ((jiffies - ad->antic_start) * 1000) / HZ; if (delay <= 1) - delta = 32; + delta = 64; else if (delay <= 20 && delay <= ad->antic_expire) - delta = 32 << (delay-1); + delta = 64 << (delay-1); else return 1; - return (last - delta <= next) && (next <= last + delta); + return (last - (delta>>1) <= next) && (next <= last + delta); } /* @@ -794,7 +794,8 @@ static int as_can_break_anticipation(str s = arq->request->sector - ad->last_sector[REQ_SYNC]; else s = ad->last_sector[REQ_SYNC] - arq->request->sector; - if (aic->seek_mean > s) { + + if (aic->seek_mean > (s>>1)) { /* this request is better than what we're expecting */ return 1; } @@ -877,8 +878,6 @@ static void as_update_iohist(struct as_i } /* Calculate read -> read seek distance */ - aic->last_request_pos = rq->sector + rq->nr_sectors; - if (!aic->seek_samples) seek_dist = 0; else if (aic->last_request_pos < rq->sector) @@ -886,7 +885,8 @@ static void as_update_iohist(struct as_i else seek_dist = aic->last_request_pos - rq->sector; -#if 0 /* TODO does this fix IBM's rawio random reads? */ + aic->last_request_pos = rq->sector + rq->nr_sectors; + /* * Don't allow the seek distance to get too large from the * odd fragment, pagein, etc @@ -897,7 +897,6 @@ static void as_update_iohist(struct as_i else seek_dist = min(seek_dist, (aic->seek_mean * 4) + 2*1024*64); -#endif aic->seek_samples += 256; aic->seek_total += 256*seek_dist; _