aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorNick Piggin <nickpiggin@yahoo.com.au>2006-12-22 04:09:33 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-22 11:55:49 -0500
commit7de6b8057976584e5a422574cae4dd21c677b4d4 (patch)
tree900bc533401715eec4e44b73e388a74f08b3f1a5 /mm
parent19900cdee29c812857ce938ab449e1053d516252 (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')
-rw-r--r--mm/filemap_xip.c2
-rw-r--r--mm/fremap.c2
-rw-r--r--mm/memory.c4
-rw-r--r--mm/rmap.c13
4 files changed, 14 insertions, 7 deletions
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 8d667617f558..45b3553865cf 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -189,7 +189,7 @@ __xip_unmap (struct address_space * mapping,
189 /* Nuke the page table entry. */ 189 /* Nuke the page table entry. */
190 flush_cache_page(vma, address, pte_pfn(*pte)); 190 flush_cache_page(vma, address, pte_pfn(*pte));
191 pteval = ptep_clear_flush(vma, address, pte); 191 pteval = ptep_clear_flush(vma, address, pte);
192 page_remove_rmap(page); 192 page_remove_rmap(page, vma);
193 dec_mm_counter(mm, file_rss); 193 dec_mm_counter(mm, file_rss);
194 BUG_ON(pte_dirty(pteval)); 194 BUG_ON(pte_dirty(pteval));
195 pte_unmap_unlock(pte, ptl); 195 pte_unmap_unlock(pte, ptl);
diff --git a/mm/fremap.c b/mm/fremap.c
index b77a002c3352..4e3f53dd5fd4 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -33,7 +33,7 @@ static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
33 if (page) { 33 if (page) {
34 if (pte_dirty(pte)) 34 if (pte_dirty(pte))
35 set_page_dirty(page); 35 set_page_dirty(page);
36 page_remove_rmap(page); 36 page_remove_rmap(page, vma);
37 page_cache_release(page); 37 page_cache_release(page);
38 } 38 }
39 } else { 39 } else {
diff --git a/mm/memory.c b/mm/memory.c
index c00bac66ce9f..563792f4f687 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -681,7 +681,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
681 mark_page_accessed(page); 681 mark_page_accessed(page);
682 file_rss--; 682 file_rss--;
683 } 683 }
684 page_remove_rmap(page); 684 page_remove_rmap(page, vma);
685 tlb_remove_page(tlb, page); 685 tlb_remove_page(tlb, page);
686 continue; 686 continue;
687 } 687 }
@@ -1586,7 +1586,7 @@ gotten:
1586 page_table = pte_offset_map_lock(mm, pmd, address, &ptl); 1586 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
1587 if (likely(pte_same(*page_table, orig_pte))) { 1587 if (likely(pte_same(*page_table, orig_pte))) {
1588 if (old_page) { 1588 if (old_page) {
1589 page_remove_rmap(old_page); 1589 page_remove_rmap(old_page, vma);
1590 if (!PageAnon(old_page)) { 1590 if (!PageAnon(old_page)) {
1591 dec_mm_counter(mm, file_rss); 1591 dec_mm_counter(mm, file_rss);
1592 inc_mm_counter(mm, anon_rss); 1592 inc_mm_counter(mm, anon_rss);
diff --git a/mm/rmap.c b/mm/rmap.c
index d8a842a586db..b3deda8b5019 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -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 */
570void page_remove_rmap(struct page *page) 571void 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
685out_unmap: 692out_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)--;