mm: do not rely on preempt_count in print_vma_addr
[linux-2.6-block.git] / mm / memory.c
index 42fb30300bb51a0a79942df7df3c04271e41e03b..85e7a87da79fe4a5487e1f3f6216e61b9827515c 100644 (file)
@@ -438,7 +438,7 @@ static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
        pgtable_t token = pmd_pgtable(*pmd);
        pmd_clear(pmd);
        pte_free_tlb(tlb, token, addr);
-       atomic_long_dec(&tlb->mm->nr_ptes);
+       mm_dec_nr_ptes(tlb->mm);
 }
 
 static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
@@ -506,6 +506,7 @@ static inline void free_pud_range(struct mmu_gather *tlb, p4d_t *p4d,
        pud = pud_offset(p4d, start);
        p4d_clear(p4d);
        pud_free_tlb(tlb, pud, start);
+       mm_dec_nr_puds(tlb->mm);
 }
 
 static inline void free_p4d_range(struct mmu_gather *tlb, pgd_t *pgd,
@@ -665,7 +666,7 @@ int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
 
        ptl = pmd_lock(mm, pmd);
        if (likely(pmd_none(*pmd))) {   /* Has another populated it ? */
-               atomic_long_inc(&mm->nr_ptes);
+               mm_inc_nr_ptes(mm);
                pmd_populate(mm, pmd, new);
                new = NULL;
        }
@@ -3237,7 +3238,7 @@ static int pte_alloc_one_map(struct vm_fault *vmf)
                        goto map_pte;
                }
 
-               atomic_long_inc(&vma->vm_mm->nr_ptes);
+               mm_inc_nr_ptes(vma->vm_mm);
                pmd_populate(vma->vm_mm, vmf->pmd, vmf->prealloc_pte);
                spin_unlock(vmf->ptl);
                vmf->prealloc_pte = NULL;
@@ -3296,7 +3297,7 @@ static void deposit_prealloc_pte(struct vm_fault *vmf)
         * We are going to consume the prealloc table,
         * count that as nr_ptes.
         */
-       atomic_long_inc(&vma->vm_mm->nr_ptes);
+       mm_inc_nr_ptes(vma->vm_mm);
        vmf->prealloc_pte = NULL;
 }
 
@@ -4149,15 +4150,17 @@ int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address)
 
        spin_lock(&mm->page_table_lock);
 #ifndef __ARCH_HAS_5LEVEL_HACK
-       if (p4d_present(*p4d))          /* Another has populated it */
-               pud_free(mm, new);
-       else
+       if (!p4d_present(*p4d)) {
+               mm_inc_nr_puds(mm);
                p4d_populate(mm, p4d, new);
-#else
-       if (pgd_present(*p4d))          /* Another has populated it */
+       } else  /* Another has populated it */
                pud_free(mm, new);
-       else
+#else
+       if (!pgd_present(*p4d)) {
+               mm_inc_nr_puds(mm);
                pgd_populate(mm, p4d, new);
+       } else  /* Another has populated it */
+               pud_free(mm, new);
 #endif /* __ARCH_HAS_5LEVEL_HACK */
        spin_unlock(&mm->page_table_lock);
        return 0;
@@ -4482,17 +4485,15 @@ void print_vma_addr(char *prefix, unsigned long ip)
        struct vm_area_struct *vma;
 
        /*
-        * Do not print if we are in atomic
-        * contexts (in exception stacks, etc.):
+        * we might be running from an atomic context so we cannot sleep
         */
-       if (preempt_count())
+       if (!down_read_trylock(&mm->mmap_sem))
                return;
 
-       down_read(&mm->mmap_sem);
        vma = find_vma(mm, ip);
        if (vma && vma->vm_file) {
                struct file *f = vma->vm_file;
-               char *buf = (char *)__get_free_page(GFP_KERNEL);
+               char *buf = (char *)__get_free_page(GFP_NOWAIT);
                if (buf) {
                        char *p;