]> git.karo-electronics.de Git - linux-beck.git/blobdiff - mm/memory.c
Merge tag 'staging-3.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[linux-beck.git] / mm / memory.c
index e6a3b933517e0442c22aa89ab885ac6f2f95ae5b..bb1369f7b9b4ba8af51d90a40de8f522aa2470dc 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/elf.h>
 #include <linux/gfp.h>
 #include <linux/migrate.h>
+#include <linux/string.h>
 
 #include <asm/io.h>
 #include <asm/pgalloc.h>
@@ -183,10 +184,14 @@ static int tlb_next_batch(struct mmu_gather *tlb)
                return 1;
        }
 
+       if (tlb->batch_count == MAX_GATHER_BATCH_COUNT)
+               return 0;
+
        batch = (void *)__get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
        if (!batch)
                return 0;
 
+       tlb->batch_count++;
        batch->next = NULL;
        batch->nr   = 0;
        batch->max  = MAX_GATHER_BATCH;
@@ -215,6 +220,7 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
        tlb->local.nr   = 0;
        tlb->local.max  = ARRAY_SIZE(tlb->__pages);
        tlb->active     = &tlb->local;
+       tlb->batch_count = 0;
 
 #ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb->batch = NULL;
@@ -3590,6 +3596,7 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
                     unsigned long addr, pmd_t *pmdp)
 {
        BUG();
+       return 0;
 }
 #endif /* CONFIG_NUMA_BALANCING */
 
@@ -3704,6 +3711,14 @@ retry:
                if (pmd_trans_huge(orig_pmd)) {
                        unsigned int dirty = flags & FAULT_FLAG_WRITE;
 
+                       /*
+                        * If the pmd is splitting, return and retry the
+                        * the fault.  Alternative: wait until the split
+                        * is done, and goto retry.
+                        */
+                       if (pmd_trans_splitting(orig_pmd))
+                               return 0;
+
                        if (pmd_numa(orig_pmd))
                                return do_huge_pmd_numa_page(mm, vma, address,
                                                             orig_pmd, pmd);
@@ -4117,15 +4132,12 @@ void print_vma_addr(char *prefix, unsigned long ip)
                struct file *f = vma->vm_file;
                char *buf = (char *)__get_free_page(GFP_KERNEL);
                if (buf) {
-                       char *p, *s;
+                       char *p;
 
                        p = d_path(&f->f_path, buf, PAGE_SIZE);
                        if (IS_ERR(p))
                                p = "?";
-                       s = strrchr(p, '/');
-                       if (s)
-                               p = s+1;
-                       printk("%s%s[%lx+%lx]", prefix, p,
+                       printk("%s%s[%lx+%lx]", prefix, kbasename(p),
                                        vma->vm_start,
                                        vma->vm_end - vma->vm_start);
                        free_page((unsigned long)buf);