Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6b10c6c9fbfe754e8482efb8c8b84f8e40c0f2eb
Commit:     6b10c6c9fbfe754e8482efb8c8b84f8e40c0f2eb
Parent:     6df8ba4f8a4c4abca9ccad10441d0dddbdff301c
Author:     Fengguang Wu <[EMAIL PROTECTED]>
AuthorDate: Tue Oct 16 01:24:34 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue Oct 16 09:42:52 2007 -0700

    readahead: basic support of interleaved reads
    
    This is a simplified version of the pagecache context based readahead.  It
    handles the case of multiple threads reading on the same fd and invalidating
    each others' readahead state.  It does the trick by scanning the pagecache 
and
    recovering the current read stream's readahead status.
    
    The algorithm works in a opportunistic way, in that it does not try to 
detect
    interleaved reads _actively_, which requires a probe into the page cache
    (which means a little more overhead for random reads).  It only tries to
    handle a previously started sequential readahead whose state was overwritten
    by another concurrent stream, and it can do this job pretty well.
    
    Negative and positive examples(or what you can expect from it):
    
    1) it cannot detect and serve perfect request-by-request interleaved reads
       right:
        time    stream 1  stream 2
        0       1
        1                 1001
        2       2
        3                 1002
        4       3
        5                 1003
        6       4
        7                 1004
        8       5
        9                 1005
    
    Here no single readahead will be carried out.
    
    2) However, if it's two concurrent reads by two threads, the chance of the
       initial sequential readahead be started is huge. Once the first 
sequential
       readahead is started for a stream, this patch will ensure that the 
readahead
       window continues to rampup and won't be disturbed by other streams.
    
        time    stream 1  stream 2
        0       1
        1       2
        2                 1001
        3       3
        4                 1002
        5                 1003
        6       4
        7       5
        8                 1004
        9       6
        10                1005
        11      7
        12                1006
        13                1007
    
    Here stream 1 will start a readahead at page 2, and stream 2 will start its
    first readahead at page 1003.  From then on the two streams will be served
    right.
    
    Cc: Rusty Russell <[EMAIL PROTECTED]>
    Signed-off-by: Fengguang Wu <[EMAIL PROTECTED]>
    Cc: Rusty Russell <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 mm/readahead.c |   33 +++++++++++++++++++++++----------
 1 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/mm/readahead.c b/mm/readahead.c
index 4a58bef..fd588ff 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -380,6 +380,29 @@ ondemand_readahead(struct address_space *mapping,
        }
 
        /*
+        * Hit a marked page without valid readahead state.
+        * E.g. interleaved reads.
+        * Query the pagecache for async_size, which normally equals to
+        * readahead size. Ramp it up and use it as the new readahead size.
+        */
+       if (hit_readahead_marker) {
+               pgoff_t start;
+
+               read_lock_irq(&mapping->tree_lock);
+               start = radix_tree_next_hole(&mapping->page_tree, offset, 
max+1);
+               read_unlock_irq(&mapping->tree_lock);
+
+               if (!start || start - offset > max)
+                       return 0;
+
+               ra->start = start;
+               ra->size = start - offset;      /* old async_size */
+               ra->size = get_next_ra_size(ra, max);
+               ra->async_size = ra->size;
+               goto readit;
+       }
+
+       /*
         * It may be one of
         *      - first read on start of file
         *      - sequential cache miss
@@ -390,16 +413,6 @@ ondemand_readahead(struct address_space *mapping,
        ra->size = get_init_ra_size(req_size, max);
        ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size;
 
-       /*
-        * Hit on a marked page without valid readahead state.
-        * E.g. interleaved reads.
-        * Not knowing its readahead pos/size, bet on the minimal possible one.
-        */
-       if (hit_readahead_marker) {
-               ra->start++;
-               ra->size = get_next_ra_size(ra, max);
-       }
-
 readit:
        return ra_submit(ra, mapping, filp);
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to