aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/memory.c52
-rw-r--r--mm/page_alloc.c16
-rw-r--r--mm/rmap.c16
3 files changed, 48 insertions, 36 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 89339c61f8e5..cda04b19f733 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -52,6 +52,9 @@
52#include <linux/writeback.h> 52#include <linux/writeback.h>
53#include <linux/memcontrol.h> 53#include <linux/memcontrol.h>
54#include <linux/mmu_notifier.h> 54#include <linux/mmu_notifier.h>
55#include <linux/kallsyms.h>
56#include <linux/swapops.h>
57#include <linux/elf.h>
55 58
56#include <asm/pgalloc.h> 59#include <asm/pgalloc.h>
57#include <asm/uaccess.h> 60#include <asm/uaccess.h>
@@ -59,9 +62,6 @@
59#include <asm/tlbflush.h> 62#include <asm/tlbflush.h>
60#include <asm/pgtable.h> 63#include <asm/pgtable.h>
61 64
62#include <linux/swapops.h>
63#include <linux/elf.h>
64
65#include "internal.h" 65#include "internal.h"
66 66
67#ifndef CONFIG_NEED_MULTIPLE_NODES 67#ifndef CONFIG_NEED_MULTIPLE_NODES
@@ -375,15 +375,41 @@ static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss)
375 * 375 *
376 * The calling function must still handle the error. 376 * The calling function must still handle the error.
377 */ 377 */
378static void print_bad_pte(struct vm_area_struct *vma, pte_t pte, 378static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
379 unsigned long vaddr) 379 pte_t pte, struct page *page)
380{ 380{
381 printk(KERN_ERR "Bad pte = %08llx, process = %s, " 381 pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
382 "vm_flags = %lx, vaddr = %lx\n", 382 pud_t *pud = pud_offset(pgd, addr);
383 (long long)pte_val(pte), 383 pmd_t *pmd = pmd_offset(pud, addr);
384 (vma->vm_mm == current->mm ? current->comm : "???"), 384 struct address_space *mapping;
385 vma->vm_flags, vaddr); 385 pgoff_t index;
386
387 mapping = vma->vm_file ? vma->vm_file->f_mapping : NULL;
388 index = linear_page_index(vma, addr);
389
390 printk(KERN_EMERG "Bad page map in process %s pte:%08llx pmd:%08llx\n",
391 current->comm,
392 (long long)pte_val(pte), (long long)pmd_val(*pmd));
393 if (page) {
394 printk(KERN_EMERG
395 "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
396 page, (void *)page->flags, page_count(page),
397 page_mapcount(page), page->mapping, page->index);
398 }
399 printk(KERN_EMERG
400 "addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
401 (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
402 /*
403 * Choose text because data symbols depend on CONFIG_KALLSYMS_ALL=y
404 */
405 if (vma->vm_ops)
406 print_symbol(KERN_EMERG "vma->vm_ops->fault: %s\n",
407 (unsigned long)vma->vm_ops->fault);
408 if (vma->vm_file && vma->vm_file->f_op)
409 print_symbol(KERN_EMERG "vma->vm_file->f_op->mmap: %s\n",
410 (unsigned long)vma->vm_file->f_op->mmap);
386 dump_stack(); 411 dump_stack();
412 add_taint(TAINT_BAD_PAGE);
387} 413}
388 414
389static inline int is_cow_mapping(unsigned int flags) 415static inline int is_cow_mapping(unsigned int flags)
@@ -773,6 +799,8 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
773 file_rss--; 799 file_rss--;
774 } 800 }
775 page_remove_rmap(page, vma); 801 page_remove_rmap(page, vma);
802 if (unlikely(page_mapcount(page) < 0))
803 print_bad_pte(vma, addr, ptent, page);
776 tlb_remove_page(tlb, page); 804 tlb_remove_page(tlb, page);
777 continue; 805 continue;
778 } 806 }
@@ -2684,7 +2712,7 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2684 /* 2712 /*
2685 * Page table corrupted: show pte and kill process. 2713 * Page table corrupted: show pte and kill process.
2686 */ 2714 */
2687 print_bad_pte(vma, orig_pte, address); 2715 print_bad_pte(vma, address, orig_pte, NULL);
2688 return VM_FAULT_OOM; 2716 return VM_FAULT_OOM;
2689 } 2717 }
2690 2718
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bd330252fc77..3acb216e9a78 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -222,14 +222,14 @@ static inline int bad_range(struct zone *zone, struct page *page)
222 222
223static void bad_page(struct page *page) 223static void bad_page(struct page *page)
224{ 224{
225 printk(KERN_EMERG "Bad page state in process '%s'\n" KERN_EMERG 225 printk(KERN_EMERG "Bad page state in process %s pfn:%05lx\n",
226 "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n", 226 current->comm, page_to_pfn(page));
227 current->comm, page, (int)(2*sizeof(unsigned long)), 227 printk(KERN_EMERG
228 (unsigned long)page->flags, page->mapping, 228 "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
229 page_mapcount(page), page_count(page)); 229 page, (void *)page->flags, page_count(page),
230 230 page_mapcount(page), page->mapping, page->index);
231 printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n" 231 printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n");
232 KERN_EMERG "Backtrace:\n"); 232
233 dump_stack(); 233 dump_stack();
234 234
235 /* Leave bad fields for debug, except PageBuddy could make trouble */ 235 /* Leave bad fields for debug, except PageBuddy could make trouble */
diff --git a/mm/rmap.c b/mm/rmap.c
index b1770b11a571..32098255082e 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -47,7 +47,6 @@
47#include <linux/rmap.h> 47#include <linux/rmap.h>
48#include <linux/rcupdate.h> 48#include <linux/rcupdate.h>
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/kallsyms.h>
51#include <linux/memcontrol.h> 50#include <linux/memcontrol.h>
52#include <linux/mmu_notifier.h> 51#include <linux/mmu_notifier.h>
53#include <linux/migrate.h> 52#include <linux/migrate.h>
@@ -725,21 +724,6 @@ void page_dup_rmap(struct page *page, struct vm_area_struct *vma, unsigned long
725void page_remove_rmap(struct page *page, struct vm_area_struct *vma) 724void page_remove_rmap(struct page *page, struct vm_area_struct *vma)
726{ 725{
727 if (atomic_add_negative(-1, &page->_mapcount)) { 726 if (atomic_add_negative(-1, &page->_mapcount)) {
728 if (unlikely(page_mapcount(page) < 0)) {
729 printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page));
730 printk (KERN_EMERG " page pfn = %lx\n", page_to_pfn(page));
731 printk (KERN_EMERG " page->flags = %lx\n", page->flags);
732 printk (KERN_EMERG " page->count = %x\n", page_count(page));
733 printk (KERN_EMERG " page->mapping = %p\n", page->mapping);
734 print_symbol (KERN_EMERG " vma->vm_ops = %s\n", (unsigned long)vma->vm_ops);
735 if (vma->vm_ops) {
736 print_symbol (KERN_EMERG " vma->vm_ops->fault = %s\n", (unsigned long)vma->vm_ops->fault);
737 }
738 if (vma->vm_file && vma->vm_file->f_op)
739 print_symbol (KERN_EMERG " vma->vm_file->f_op->mmap = %s\n", (unsigned long)vma->vm_file->f_op->mmap);
740 BUG();
741 }
742
743 /* 727 /*
744 * Now that the last pte has gone, s390 must transfer dirty 728 * Now that the last pte has gone, s390 must transfer dirty
745 * flag from storage key to struct page. We can usually skip 729 * flag from storage key to struct page. We can usually skip