From: Ram Pai Looks like you are right on all counts! I did some modifications to your patch and did a preliminary run with my user-level simulator. With these changes I am able to get rid of that extra page. Also code looks much simpler and adapts well to sequential and random patterns. However I have to run this under some benchmarks and see how it fares. Its a pre-alpha level patch. Can you take a quick look at the changes and see if you like it? I am sure you won't consider these changes a hack ;) --- 25-akpm/mm/readahead.c | 49 +++++++++++++++++++++++++------------------------ 1 files changed, 25 insertions(+), 24 deletions(-) diff -puN mm/readahead.c~seeky-readahead-speedups mm/readahead.c --- 25/mm/readahead.c~seeky-readahead-speedups Tue May 11 14:17:59 2004 +++ 25-akpm/mm/readahead.c Tue May 11 14:17:59 2004 @@ -353,7 +353,7 @@ page_cache_readahead(struct address_spac unsigned orig_next_size; unsigned actual; int first_access=0; - unsigned long preoffset=0; + unsigned long average=0; /* * Here we detect the case where the application is performing @@ -394,10 +394,17 @@ page_cache_readahead(struct address_spac if (ra->serial_cnt <= (max * 2)) ra->serial_cnt++; } else { - ra->average = (ra->average + ra->serial_cnt) / 2; + /* to avoid rounding errors, ensure that 'average' + * tends towards the value of ra->serial_cnt. + */ + if(ra->average > ra->serial_cnt) { + average = ra->average - 1; + } else { + average = ra->average + 1; + } + ra->average = (average + ra->serial_cnt) / 2; ra->serial_cnt = 1; } - preoffset = ra->prev_page; ra->prev_page = offset; if (offset >= ra->start && offset <= (ra->start + ra->size)) { @@ -457,18 +464,14 @@ do_io: * ahead window and get some I/O underway for the new * current window. */ - if (!first_access && preoffset >= ra->start && - preoffset < (ra->start + ra->size)) { - /* Heuristic: If 'n' pages were - * accessed in the current window, there - * is a high probability that around 'n' pages - * shall be used in the next current window. - * - * To minimize lazy-readahead triggered - * in the next current window, read in - * an extra page. + if (!first_access) { + /* Heuristic: there is a high probability + * that around ra->average number of + * pages shall be accessed in the next + * current window. */ - ra->next_size = preoffset - ra->start + 2; + ra->next_size = (ra->average > max ? + max : ra->average); } ra->start = offset; ra->size = ra->next_size; @@ -492,21 +495,19 @@ do_io: */ if (ra->ahead_start == 0) { /* - * if the average io-size is less than maximum + * If the average io-size is more than maximum * readahead size of the file the io pattern is * sequential. Hence bring in the readahead window - * immediately. - * Else the i/o pattern is random. Bring - * in the readahead window only if the last page of - * the current window is accessed (lazy readahead). + * immediately. + * If the average io-size is less than maximum + * readahead size of the file the io pattern is + * random. Hence don't bother to readahead. */ - unsigned long average = ra->average; - + average = ra->average; if (ra->serial_cnt > average) - average = (ra->serial_cnt + ra->average) / 2; + average = (ra->serial_cnt + ra->average + 1) / 2; - if ((average >= max) || (offset == (ra->start + - ra->size - 1))) { + if (average > max) { ra->ahead_start = ra->start + ra->size; ra->ahead_size = ra->next_size; actual = do_page_cache_readahead(mapping, filp, _