diff options
author | Nick Piggin <nickpiggin@yahoo.com.au> | 2006-12-22 04:09:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-22 11:55:49 -0500 |
commit | 7de6b8057976584e5a422574cae4dd21c677b4d4 (patch) | |
tree | 900bc533401715eec4e44b73e388a74f08b3f1a5 /mm/rmap.c | |
parent | 19900cdee29c812857ce938ab449e1053d516252 (diff) |
[PATCH] mm: more rmap debugging
Add more debugging in the rmap code in an attempt to locate to source of
the occasional "mapcount went negative" assertions.
Cc: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/rmap.c')
-rw-r--r-- | mm/rmap.c | 13 |
1 files changed, 10 insertions, 3 deletions
@@ -47,6 +47,7 @@ | |||
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> | ||
50 | 51 | ||
51 | #include <asm/tlbflush.h> | 52 | #include <asm/tlbflush.h> |
52 | 53 | ||
@@ -567,14 +568,20 @@ void page_add_file_rmap(struct page *page) | |||
567 | * | 568 | * |
568 | * The caller needs to hold the pte lock. | 569 | * The caller needs to hold the pte lock. |
569 | */ | 570 | */ |
570 | void page_remove_rmap(struct page *page) | 571 | void page_remove_rmap(struct page *page, struct vm_area_struct *vma) |
571 | { | 572 | { |
572 | if (atomic_add_negative(-1, &page->_mapcount)) { | 573 | if (atomic_add_negative(-1, &page->_mapcount)) { |
573 | if (unlikely(page_mapcount(page) < 0)) { | 574 | if (unlikely(page_mapcount(page) < 0)) { |
574 | printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page)); | 575 | printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page)); |
576 | printk (KERN_EMERG " page pfn = %lx\n", page_to_pfn(page)); | ||
575 | printk (KERN_EMERG " page->flags = %lx\n", page->flags); | 577 | printk (KERN_EMERG " page->flags = %lx\n", page->flags); |
576 | printk (KERN_EMERG " page->count = %x\n", page_count(page)); | 578 | printk (KERN_EMERG " page->count = %x\n", page_count(page)); |
577 | printk (KERN_EMERG " page->mapping = %p\n", page->mapping); | 579 | printk (KERN_EMERG " page->mapping = %p\n", page->mapping); |
580 | print_symbol (KERN_EMERG " vma->vm_ops = %s\n", (unsigned long)vma->vm_ops); | ||
581 | if (vma->vm_ops) | ||
582 | print_symbol (KERN_EMERG " vma->vm_ops->nopage = %s\n", (unsigned long)vma->vm_ops->nopage); | ||
583 | if (vma->vm_file && vma->vm_file->f_op) | ||
584 | print_symbol (KERN_EMERG " vma->vm_file->f_op->mmap = %s\n", (unsigned long)vma->vm_file->f_op->mmap); | ||
578 | BUG(); | 585 | BUG(); |
579 | } | 586 | } |
580 | 587 | ||
@@ -679,7 +686,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, | |||
679 | dec_mm_counter(mm, file_rss); | 686 | dec_mm_counter(mm, file_rss); |
680 | 687 | ||
681 | 688 | ||
682 | page_remove_rmap(page); | 689 | page_remove_rmap(page, vma); |
683 | page_cache_release(page); | 690 | page_cache_release(page); |
684 | 691 | ||
685 | out_unmap: | 692 | out_unmap: |
@@ -769,7 +776,7 @@ static void try_to_unmap_cluster(unsigned long cursor, | |||
769 | if (pte_dirty(pteval)) | 776 | if (pte_dirty(pteval)) |
770 | set_page_dirty(page); | 777 | set_page_dirty(page); |
771 | 778 | ||
772 | page_remove_rmap(page); | 779 | page_remove_rmap(page, vma); |
773 | page_cache_release(page); | 780 | page_cache_release(page); |
774 | dec_mm_counter(mm, file_rss); | 781 | dec_mm_counter(mm, file_rss); |
775 | (*mapcount)--; | 782 | (*mapcount)--; |