From: Oleg Nesterov On top of "[PATCH 2/2] readahead: improve sequential read detection". Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton --- 25-akpm/mm/readahead.c | 31 +++++++++++++------------------ 1 files changed, 13 insertions(+), 18 deletions(-) diff -puN mm/readahead.c~readahead-simplify-ra-size-testing-fix mm/readahead.c --- 25/mm/readahead.c~readahead-simplify-ra-size-testing-fix Thu Mar 3 16:59:07 2005 +++ 25-akpm/mm/readahead.c Thu Mar 3 16:59:07 2005 @@ -192,18 +192,16 @@ out: * size: Number of pages in that read * Together, these form the "current window". * Together, start and size represent the `readahead window'. - * next_size: The number of pages to read on the next readahead miss. - * Has the magical value -1UL if readahead has been disabled. * prev_page: The page which the readahead algorithm most-recently inspected. - * prev_page is mainly an optimisation: if page_cache_readahead - * sees that it is again being called for a page which it just - * looked at, it can return immediately without making any state - * changes. + * It is mainly used to detect sequential file reading. + * If page_cache_readahead sees that it is again being called for + * a page which it just looked at, it can return immediately without + * making any state changes. * ahead_start, * ahead_size: Together, these form the "ahead window". * ra_pages: The externally controlled max readahead for this fd. * - * When readahead is in the off state (size == -1UL), readahead is disabled. + * When readahead is in the off state (size == 0), readahead is disabled. * In this state, prev_page is used to detect the resumption of sequential I/O. * * The readahead code manages two windows - the "current" and the "ahead" @@ -224,7 +222,7 @@ out: * ahead window. * * A `readahead hit' occurs when a read request is made against a page which is - * the next sequential page. Ahead windowe calculations are done only when it + * the next sequential page. Ahead window calculations are done only when it * is time to submit a new IO. The code ramps up the size agressively at first, * but slow down as it approaches max_readhead. * @@ -235,12 +233,9 @@ out: * read happens to be the first page of the file, it is assumed that a linear * read is about to happen and the window is immediately set to the initial size * based on I/O request size and the max_readahead. - * - * A page request at (start + size) is not a miss at all - it's just a part of - * sequential file reading. * * This function is to be called for every read request, rather than when - * it is time to perform readahead. It is called only oce for the entire I/O + * it is time to perform readahead. It is called only once for the entire I/O * regardless of size unless readahead is unable to start enough I/O to satisfy * the request (I/O request > max_readahead). */ @@ -447,28 +442,28 @@ page_cache_readahead(struct address_spac int sequential; /* - * Here we detect the case where the application is performing - * sub-page sized reads. We avoid doing extra work and bogusly - * perturbing the readahead window expansion logic. + * We avoid doing extra work and bogusly perturbing the readahead + * window expansion logic. */ if (offset == ra->prev_page && --req_size) ++offset; + /* Note that prev_page == -1 if it is a first read */ sequential = (offset == ra->prev_page + 1); ra->prev_page = offset; max = get_max_readahead(ra); newsize = min(req_size, max); - /* No readahead or file already in cache or sub-page sized read */ + /* No readahead or sub-page sized read or file already in cache */ if (newsize == 0 || (ra->flags & RA_FLAG_INCACHE)) goto out; ra->prev_page += newsize - 1; /* - * Special case - first read. We'll assume it's a whole-file read if - * at start of file, and grow the window fast. Or detect first + * Special case - first read at start of file. We'll assume it's + * a whole-file read and grow the window fast. Or detect first * sequential access */ if (sequential && ra->size == 0) { _