]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - arch/arm26/mm/fault.c
mm: fault feedback #2
[net-next-2.6.git] / arch / arm26 / mm / fault.c
index bd6f2db608b76ecde7dce3e02c26d70c386e7cc6..dec638a0c8d92b0f4e962b573bc3993f226b4ffb 100644 (file)
@@ -8,7 +8,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -156,7 +155,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
         */
 good_area:
        if (READ_FAULT(fsr)) /* read? */
-               mask = VM_READ|VM_EXEC;
+               mask = VM_READ|VM_EXEC|VM_WRITE;
        else
                mask = VM_WRITE;
 
@@ -171,22 +170,22 @@ good_area:
         */
 survive:
        fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(fsr));
-
-       /*
-        * Handle the "normal" cases first - successful and sigbus
-        */
-       switch (fault) {
-       case VM_FAULT_MAJOR:
+       if (unlikely(fault & VM_FAULT_ERROR)) {
+               if (fault & VM_FAULT_OOM)
+                       goto out_of_memory;
+               else if (fault & VM_FAULT_SIGBUS)
+                       return fault;
+               BUG();
+       }
+       if (fault & VM_FAULT_MAJOR)
                tsk->maj_flt++;
-               return fault;
-       case VM_FAULT_MINOR:
+       else
                tsk->min_flt++;
-       case VM_FAULT_SIGBUS:
-               return fault;
-       }
+       return fault;
 
+out_of_memory:
        fault = -3; /* out of memory */
-       if (tsk->pid != 1)
+       if (!is_init(tsk))
                goto out;
 
        /*
@@ -216,7 +215,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
         * If we're in an interrupt or have no user
         * context, we must not take the fault..
         */
-       if (in_interrupt() || !mm)
+       if (in_atomic() || !mm)
                goto no_context;
 
        down_read(&mm->mmap_sem);
@@ -226,13 +225,11 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        /*
         * Handle the "normal" case first
         */
-       switch (fault) {
-       case VM_FAULT_MINOR:
-       case VM_FAULT_MAJOR:
+       if (likely(!(fault & VM_FAULT_ERROR)))
                return 0;
-       case VM_FAULT_SIGBUS:
+       if (fault & VM_FAULT_SIGBUS)
                goto do_sigbus;
-       }
+       /* else VM_FAULT_OOM */
 
        /*
         * If we are in kernel mode at this point, we