]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
readahead: fault retry breaks mmap file read random detection
authorShaohua Li <shli@kernel.org>
Thu, 13 Sep 2012 00:58:22 +0000 (10:58 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 18 Sep 2012 06:04:10 +0000 (16:04 +1000)
.fault now can retry.  The retry can break state machine of .fault.  In
filemap_fault, if page is miss, ra->mmap_miss is increased.  In the second
try, since the page is in page cache now, ra->mmap_miss is decreased.  And
these are done in one fault, so we can't detect random mmap file access.

Add a new flag to indicate .fault is tried once.  In the second try, skip
ra->mmap_miss decreasing.  The filemap_fault state machine is ok with it.

I only tested x86, didn't test other archs, but looks the change for other
archs is obvious, but who knows :)

Signed-off-by: Shaohua Li <shaohua.li@fusionio.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
20 files changed:
arch/arm/mm/fault.c
arch/avr32/mm/fault.c
arch/cris/mm/fault.c
arch/hexagon/mm/vm_fault.c
arch/ia64/mm/fault.c
arch/m68k/mm/fault.c
arch/microblaze/mm/fault.c
arch/mips/mm/fault.c
arch/openrisc/mm/fault.c
arch/powerpc/mm/fault.c
arch/s390/mm/fault.c
arch/sh/mm/fault.c
arch/sparc/mm/fault_32.c
arch/sparc/mm/fault_64.c
arch/tile/mm/fault.c
arch/um/kernel/trap.c
arch/x86/mm/fault.c
arch/xtensa/mm/fault.c
include/linux/mm.h
mm/filemap.c

index c3bd8345022780e45e3135228329a56dda91cee4..5dbf13f954f6f493aaae525d4f3b93282ac88f75 100644 (file)
@@ -336,6 +336,7 @@ retry:
                        /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
                        * of starvation. */
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
                        goto retry;
                }
        }
index b92e60958617eb25ff90481989f494c3625f5a98..b2f2d2d668491905dbbc37c385449852a9e7fdde 100644 (file)
@@ -152,6 +152,7 @@ good_area:
                        tsk->min_flt++;
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /*
                         * No need to up_read(&mm->mmap_sem) as we would have
index 45fd542cf173df075c556d3fb1586d740298b426..73312ab6c696c160f7fd58df02a50890390ad650 100644 (file)
@@ -186,6 +186,7 @@ retry:
                        tsk->min_flt++;
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /*
                         * No need to up_read(&mm->mmap_sem) as we would
index 06695cc4fe58f09f61d73c0e28803de8b9dfbda3..513b74cb397eb4dffab84d240367f2e71d8a4263 100644 (file)
@@ -113,6 +113,7 @@ good_area:
                                current->min_flt++;
                        if (fault & VM_FAULT_RETRY) {
                                flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                               flags |= FAULT_FLAG_TRIED;
                                goto retry;
                        }
                }
index 8443daf4f515777ca3cd6d710bef4a92b6373608..6cf0341f978e59ddf235c44e70dcf615799390ed 100644 (file)
@@ -184,6 +184,7 @@ retry:
                        current->min_flt++;
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                         /* No need to up_read(&mm->mmap_sem) as we would
                         * have already released it in __lock_page_or_retry
index aeebbb7b30f0b6ca7348740a6a374ef475066a82..a563727806bf922b5b3315559b9b46b5bbb9d7fc 100644 (file)
@@ -170,6 +170,7 @@ good_area:
                        /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
                         * of starvation. */
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /*
                         * No need to up_read(&mm->mmap_sem) as we would
index eb365d6795fa80448fbe4fe391b8b3211c0f4156..714b35a9c4f7b156ac59476debad57426988f849 100644 (file)
@@ -233,6 +233,7 @@ good_area:
                        current->min_flt++;
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /*
                         * No need to up_read(&mm->mmap_sem) as we would
index 7a19957735e96056732b00f5ef77f9e658a1d333..ddcec1e1a0cd256df9db44404686a42a31e58947 100644 (file)
@@ -171,6 +171,7 @@ good_area:
                }
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /*
                         * No need to up_read(&mm->mmap_sem) as we would
index 40f850e9766c78a0d790a040937b2d053b8ac4bd..e2bfafce66c53661064e2cf5e4b0d5d036e2c6a7 100644 (file)
@@ -183,6 +183,7 @@ good_area:
                        tsk->min_flt++;
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                         /* No need to up_read(&mm->mmap_sem) as we would
                         * have already released it in __lock_page_or_retry
index 995f924e007f8f01fa4fe6eaba2b83006d66d81d..183c787e862ddb29769605d9e883463060ec7f07 100644 (file)
@@ -451,6 +451,7 @@ good_area:
                        /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
                         * of starvation. */
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
                        goto retry;
                }
        }
index ac9122ca11529217e3843483042306a7a09a74cb..04ad4001a289e05c89d30b5d6aaad9573b2ca388 100644 (file)
@@ -367,6 +367,7 @@ retry:
                        /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
                         * of starvation. */
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
                        down_read(&mm->mmap_sem);
                        goto retry;
                }
index 3bdc1ad9a341f4418a1724dfcd8cd3ac4388a011..cbbdcad8fcb357cc7fc383820a6f0c7dc1537be9 100644 (file)
@@ -504,6 +504,7 @@ good_area:
                }
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /*
                         * No need to up_read(&mm->mmap_sem) as we would
index 77ac917be15295f787977715ea8f63c43bbb1697..e98bfda205a2beb97bcaa49a27d5a9412bf03dc3 100644 (file)
@@ -265,6 +265,7 @@ good_area:
                }
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /* No need to up_read(&mm->mmap_sem) as we would
                         * have already released it in __lock_page_or_retry
index 1fe0429b6314257faa40d80b07f7d4e3b77538c6..413d292633046a62d51b342b6de85bc04125affd 100644 (file)
@@ -452,6 +452,7 @@ good_area:
                }
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                        /* No need to up_read(&mm->mmap_sem) as we would
                         * have already released it in __lock_page_or_retry
index 84ce7abbf5afb80c5d82648244349bf7d746a9c0..fe811fa5f1b96f682633e2c54f6be6bbdd525095 100644 (file)
@@ -454,6 +454,7 @@ good_area:
                        tsk->min_flt++;
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                         /*
                          * No need to up_read(&mm->mmap_sem) as we would
index 0353b98ae35a28208c695816bd9b7883ad6fb22e..0f00e9c82080f644030191cb31bc7ae3e0937f49 100644 (file)
@@ -89,6 +89,7 @@ good_area:
                                current->min_flt++;
                        if (fault & VM_FAULT_RETRY) {
                                flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                               flags |= FAULT_FLAG_TRIED;
 
                                goto retry;
                        }
index 7dde46d68a25a562b54fcdd300f232b051c10153..d57ca71e124508bcc933cb7a51783aa0190bada5 100644 (file)
@@ -1202,6 +1202,7 @@ good_area:
                        /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
                         * of starvation. */
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
                        goto retry;
                }
        }
index 5a74c53bc69c132cfad6231d9294e49f5cedef93..2c2f710ed1dc905a8c9e0509d36cd76ed073e0ce 100644 (file)
@@ -126,6 +126,7 @@ good_area:
                        current->min_flt++;
                if (fault & VM_FAULT_RETRY) {
                        flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       flags |= FAULT_FLAG_TRIED;
 
                         /* No need to up_read(&mm->mmap_sem) as we would
                         * have already released it in __lock_page_or_retry
index 311be906b57d8498d5c3529d0e42de0996a0c1ec..c861ef121b74928bd5b2419df062bfd0ee2e906e 100644 (file)
@@ -157,6 +157,7 @@ extern pgprot_t protection_map[16];
 #define FAULT_FLAG_ALLOW_RETRY 0x08    /* Retry fault if blocking */
 #define FAULT_FLAG_RETRY_NOWAIT        0x10    /* Don't drop mmap_sem and wait when retrying */
 #define FAULT_FLAG_KILLABLE    0x20    /* The fault task is in SIGKILL killable region */
+#define FAULT_FLAG_TRIED       0x40    /* second try */
 
 /*
  * This interface is used by x86 PAT code to identify a pfn mapping that is
index 384344575c375e1a1464734670218557c31e0e27..94a50bfa2f996183c0a4c3dade6f2c84adda14d9 100644 (file)
@@ -1607,13 +1607,13 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
         * Do we have something in the page cache already?
         */
        page = find_get_page(mapping, offset);
-       if (likely(page)) {
+       if (likely(page) && !(vmf->flags & FAULT_FLAG_TRIED)) {
                /*
                 * We found the page, so try async readahead before
                 * waiting for the lock.
                 */
                do_async_mmap_readahead(vma, ra, file, page, offset);
-       } else {
+       } else if (!page) {
                /* No page in the page cache at all */
                do_sync_mmap_readahead(vma, ra, file, offset);
                count_vm_event(PGMAJFAULT);