]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - mm/readahead.c
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / mm / readahead.c
index e273f0de337699f8222ab6b73b126435fb6061ee..a59ea70527b9bc46b4fde403a7f19b93493351fb 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/syscalls.h>
 #include <linux/file.h>
 #include <linux/mm_inline.h>
+#include <linux/blk-cgroup.h>
 
 #include "internal.h"
 
@@ -385,6 +386,7 @@ ondemand_readahead(struct address_space *mapping,
 {
        struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
        unsigned long max_pages = ra->ra_pages;
+       unsigned long add_pages;
        pgoff_t prev_offset;
 
        /*
@@ -474,10 +476,17 @@ ondemand_readahead(struct address_space *mapping,
         * Will this read hit the readahead marker made by itself?
         * If so, trigger the readahead marker hit now, and merge
         * the resulted next readahead window into the current one.
+        * Take care of maximum IO pages as above.
         */
        if (offset == ra->start && ra->size == ra->async_size) {
-               ra->async_size = get_next_ra_size(ra, max_pages);
-               ra->size += ra->async_size;
+               add_pages = get_next_ra_size(ra, max_pages);
+               if (ra->size + add_pages <= max_pages) {
+                       ra->async_size = add_pages;
+                       ra->size += add_pages;
+               } else {
+                       ra->size = max_pages;
+                       ra->async_size = max_pages >> 1;
+               }
        }
 
        return ra_submit(ra, mapping, filp);
@@ -505,6 +514,9 @@ void page_cache_sync_readahead(struct address_space *mapping,
        if (!ra->ra_pages)
                return;
 
+       if (blk_cgroup_congested())
+               return;
+
        /* be dumb */
        if (filp && (filp->f_mode & FMODE_RANDOM)) {
                force_page_cache_readahead(mapping, filp, offset, req_size);
@@ -555,6 +567,9 @@ page_cache_async_readahead(struct address_space *mapping,
        if (inode_read_congested(mapping->host))
                return;
 
+       if (blk_cgroup_congested())
+               return;
+
        /* do read-ahead */
        ondemand_readahead(mapping, ra, filp, true, offset, req_size);
 }