Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7de6b805 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds
Browse files

[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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 19900cde
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ void __anon_vma_link(struct vm_area_struct *);
void page_add_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
void page_add_file_rmap(struct page *);
void page_remove_rmap(struct page *);
void page_remove_rmap(struct page *, struct vm_area_struct *);

/**
 * page_dup_rmap - duplicate pte mapping to a page
+1 −1
Original line number Diff line number Diff line
@@ -189,7 +189,7 @@ __xip_unmap (struct address_space * mapping,
			/* Nuke the page table entry. */
			flush_cache_page(vma, address, pte_pfn(*pte));
			pteval = ptep_clear_flush(vma, address, pte);
			page_remove_rmap(page);
			page_remove_rmap(page, vma);
			dec_mm_counter(mm, file_rss);
			BUG_ON(pte_dirty(pteval));
			pte_unmap_unlock(pte, ptl);
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
		if (page) {
			if (pte_dirty(pte))
				set_page_dirty(page);
			page_remove_rmap(page);
			page_remove_rmap(page, vma);
			page_cache_release(page);
		}
	} else {
+2 −2
Original line number Diff line number Diff line
@@ -681,7 +681,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
					mark_page_accessed(page);
				file_rss--;
			}
			page_remove_rmap(page);
			page_remove_rmap(page, vma);
			tlb_remove_page(tlb, page);
			continue;
		}
@@ -1586,7 +1586,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
	if (likely(pte_same(*page_table, orig_pte))) {
		if (old_page) {
			page_remove_rmap(old_page);
			page_remove_rmap(old_page, vma);
			if (!PageAnon(old_page)) {
				dec_mm_counter(mm, file_rss);
				inc_mm_counter(mm, anon_rss);
+10 −3
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#include <linux/rmap.h>
#include <linux/rcupdate.h>
#include <linux/module.h>
#include <linux/kallsyms.h>

#include <asm/tlbflush.h>

@@ -567,14 +568,20 @@ void page_add_file_rmap(struct page *page)
 *
 * The caller needs to hold the pte lock.
 */
void page_remove_rmap(struct page *page)
void page_remove_rmap(struct page *page, struct vm_area_struct *vma)
{
	if (atomic_add_negative(-1, &page->_mapcount)) {
		if (unlikely(page_mapcount(page) < 0)) {
			printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page));
			printk (KERN_EMERG "  page pfn = %lx\n", page_to_pfn(page));
			printk (KERN_EMERG "  page->flags = %lx\n", page->flags);
			printk (KERN_EMERG "  page->count = %x\n", page_count(page));
			printk (KERN_EMERG "  page->mapping = %p\n", page->mapping);
			print_symbol (KERN_EMERG "  vma->vm_ops = %s\n", (unsigned long)vma->vm_ops);
			if (vma->vm_ops)
				print_symbol (KERN_EMERG "  vma->vm_ops->nopage = %s\n", (unsigned long)vma->vm_ops->nopage);
			if (vma->vm_file && vma->vm_file->f_op)
				print_symbol (KERN_EMERG "  vma->vm_file->f_op->mmap = %s\n", (unsigned long)vma->vm_file->f_op->mmap);
			BUG();
		}

@@ -679,7 +686,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
		dec_mm_counter(mm, file_rss);


	page_remove_rmap(page);
	page_remove_rmap(page, vma);
	page_cache_release(page);

out_unmap:
@@ -769,7 +776,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
		if (pte_dirty(pteval))
			set_page_dirty(page);

		page_remove_rmap(page);
		page_remove_rmap(page, vma);
		page_cache_release(page);
		dec_mm_counter(mm, file_rss);
		(*mapcount)--;