[PATCH][7/8] mm: rmap add/remove interface change

From: Stone Wang
Date: Mon Mar 20 2006 - 08:36:30 EST


Modify rmap add/remove interface to support passing structure vm_area_struct,
for this structure contains necessary info(vma->vm_wire_change),
so not to wire the same page twice (make_pages_wired and page_add_*_rmap).

Signed-off-by: Shaoping Wang <pwstone@xxxxxxxxx>

--
linux-2.6.15/include/linux/rmap.h | 4 ++--
linux-2.6.15/mm/filemap_xip.c | 2 +-
linux-2.6.15/mm/fremap.c | 6 ++++--
linux-2.6.15/mm/memory.c | 2 +-
linux-2.6.15/mm/rmap.c | 21 +++++++++++++++------
mm/memory.c | 29 +++++++++++++++--------------
6 files changed, 38 insertions(+), 26 deletions(-)

diff -urN linux-2.6.15.orig/include/linux/rmap.h
linux-2.6.15/include/linux/rmap.h
--- linux-2.6.15.orig/include/linux/rmap.h 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/include/linux/rmap.h 2006-03-06 06:30:07.000000000 -0500
@@ -71,8 +71,8 @@
* rmap interfaces called when adding or removing pte of page
*/
void page_add_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_add_file_rmap(struct page *, struct vm_area_struct *);
+void page_remove_rmap(struct page *, struct vm_area_struct *);

/**
* page_dup_rmap - duplicate pte mapping to a page
diff -urN linux-2.6.15.orig/mm/filemap_xip.c linux-2.6.15/mm/filemap_xip.c
--- linux-2.6.15.orig/mm/filemap_xip.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/mm/filemap_xip.c 2006-03-06 06:30:07.000000000 -0500
@@ -189,7 +189,7 @@
/* 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);
diff -urN linux-2.6.15.orig/mm/fremap.c linux-2.6.15/mm/fremap.c
--- linux-2.6.15.orig/mm/fremap.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/mm/fremap.c 2006-03-06 06:30:07.000000000 -0500
@@ -33,7 +33,7 @@
if (page) {
if (pte_dirty(pte))
set_page_dirty(page);
- page_remove_rmap(page);
+ page_remove_rmap(page, vma);
page_cache_release(page);
}
} else {
@@ -80,7 +80,7 @@

flush_icache_page(vma, page);
set_pte_at(mm, addr, pte, mk_pte(page, prot));
- page_add_file_rmap(page);
+ page_add_file_rmap(page, vma);
pte_val = *pte;
update_mmu_cache(vma, addr, pte_val);
err = 0;
@@ -203,6 +203,8 @@
spin_unlock(&mapping->i_mmap_lock);
}

+ if(vma->vm_flags & VM_LOCKED)
+ flags &= ~MAP_NONBLOCK;
err = vma->vm_ops->populate(vma, start, size,
vma->vm_page_prot,
pgoff, flags & MAP_NONBLOCK);
diff -urN linux-2.6.15.orig/mm/memory.c linux-2.6.15/mm/memory.c
--- linux-2.6.15.orig/mm/memory.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/mm/memory.c 2006-03-07 11:14:59.000000000 -0500
@@ -656,7 +656,7 @@
mark_page_accessed(page);
file_rss--;
}
- page_remove_rmap(page);
+ page_remove_rmap(page, vma);
tlb_remove_page(tlb, page);
continue;
}

diff -urN linux-2.6.15.orig/mm/rmap.c linux-2.6.15/mm/rmap.c
--- linux-2.6.15.orig/mm/rmap.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/mm/rmap.c 2006-03-07 06:17:57.000000000 -0500
@@ -449,6 +449,8 @@
struct anon_vma *anon_vma = vma->anon_vma;

BUG_ON(!anon_vma);
+ if((vma->vm_flags & VM_LOCKED) && !vma->vm_wire_change)
+ wire_page(page);
anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
page->mapping = (struct address_space *) anon_vma;

@@ -465,11 +467,13 @@
*
* The caller needs to hold the pte lock.
*/
-void page_add_file_rmap(struct page *page)
+void page_add_file_rmap(struct page *page, struct vm_area_struct *vma)
{
BUG_ON(PageAnon(page));
BUG_ON(!pfn_valid(page_to_pfn(page)));

+ if((vma->vm_flags & VM_LOCKED) && !vma->vm_wire_change)
+ wire_page(page);
if (atomic_inc_and_test(&page->_mapcount))
inc_page_state(nr_mapped);
}
@@ -480,8 +484,11 @@
*
* 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(PageWired(page) && (vma->vm_flags&VM_LOCKED))
+ unwire_page(page);
+
if (atomic_add_negative(-1, &page->_mapcount)) {
BUG_ON(page_mapcount(page) < 0);
/*
@@ -562,7 +569,7 @@
} else
dec_mm_counter(mm, file_rss);

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

out_unmap:
@@ -652,7 +659,7 @@
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)--;
@@ -712,8 +719,10 @@

list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
shared.vm_set.list) {
- if (vma->vm_flags & VM_LOCKED)
- continue;
+
+ /* If VM_LOCKED set, the page will be moved to Wired list.*/
+ if (vma->vm_flags & VM_LOCKED)
+ continue;
cursor = (unsigned long) vma->vm_private_data;
if (cursor > max_nl_cursor)
max_nl_cursor = cursor;
diff -urN linux-2.6.15.orig/mm/memory.c linux-2.6.15/mm/memory.c
--- linux-2.6.15.orig/mm/memory.c 2006-01-02 22:21:10.000000000 -0500
+++ linux-2.6.15/mm/memory.c 2006-03-07 11:14:59.000000000 -0500
@@ -1089,7 +1120,7 @@
struct page *page = ZERO_PAGE(addr);
pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));
page_cache_get(page);
- page_add_file_rmap(page);
+ page_add_file_rmap(page,vma);
inc_mm_counter(mm, file_rss);
BUG_ON(!pte_none(*pte));
set_pte_at(mm, addr, pte, zero_pte);
@@ -1098,8 +1129,8 @@
return 0;
}

-static inline int zeromap_pmd_range(struct mm_struct *mm, pud_t *pud,
- unsigned long addr, unsigned long end, pgprot_t prot)
+static inline int zeromap_pmd_range(struct mm_struct *mm, struct
vm_area_struct *vma,
+ pud_t *pud, unsigned long addr, unsigned long end, pgprot_t prot)
{
pmd_t *pmd;
unsigned long next;
@@ -1109,14 +1140,14 @@
return -ENOMEM;
do {
next = pmd_addr_end(addr, end);
- if (zeromap_pte_range(mm, pmd, addr, next, prot))
+ if (zeromap_pte_range(mm, vma, pmd, addr, next, prot))
return -ENOMEM;
} while (pmd++, addr = next, addr != end);
return 0;
}

-static inline int zeromap_pud_range(struct mm_struct *mm, pgd_t *pgd,
- unsigned long addr, unsigned long end, pgprot_t prot)
+static inline int zeromap_pud_range(struct mm_struct *mm, struct
vm_area_struct *vma,
+ pgd_t *pgd, unsigned long addr, unsigned long end, pgprot_t prot)
{
pud_t *pud;
unsigned long next;
@@ -1126,7 +1157,7 @@
return -ENOMEM;
do {
next = pud_addr_end(addr, end);
- if (zeromap_pmd_range(mm, pud, addr, next, prot))
+ if (zeromap_pmd_range(mm, vma, pud, addr, next, prot))
return -ENOMEM;
} while (pud++, addr = next, addr != end);
return 0;
@@ -1146,7 +1177,7 @@
flush_cache_range(vma, addr, end);
do {
next = pgd_addr_end(addr, end);
- err = zeromap_pud_range(mm, pgd, addr, next, prot);
+ err = zeromap_pud_range(mm, vma, pgd, addr, next, prot);
if (err)
break;
} while (pgd++, addr = next, addr != end);
@@ -1172,7 +1203,8 @@
* old drivers should use this, and they needed to mark their
* pages reserved for the old functions anyway.
*/
-static int insert_page(struct mm_struct *mm, unsigned long addr,
struct page *page, pgprot_t prot)
+static int insert_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, struct page *page, pgprot_t prot)
{
int retval;
pte_t *pte;
@@ -1193,7 +1225,7 @@
/* Ok, finally just insert the thing.. */
get_page(page);
inc_mm_counter(mm, file_rss);
- page_add_file_rmap(page);
+ page_add_file_rmap(page,vma);
set_pte_at(mm, addr, pte, mk_pte(page, prot));

retval = 0;
@@ -1229,7 +1261,7 @@
if (!page_count(page))
return -EINVAL;
vma->vm_flags |= VM_INSERTPAGE;
- return insert_page(vma->vm_mm, addr, page, vma->vm_page_prot);
+ return insert_page(vma->vm_mm, vma, addr, page, vma->vm_page_prot);
}
EXPORT_SYMBOL(vm_insert_page);

@@ -1484,7 +1516,7 @@
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);
@@ -1967,7 +1999,7 @@
if (!pte_none(*page_table))
goto release;
inc_mm_counter(mm, file_rss);
- page_add_file_rmap(page);
+ page_add_file_rmap(page, vma);
}

set_pte_at(mm, address, page_table, entry);
@@ -2089,7 +2121,7 @@
page_add_anon_rmap(new_page, vma, address);
} else {
inc_mm_counter(mm, file_rss);
- page_add_file_rmap(new_page);
+ page_add_file_rmap(new_page, vma);
}
} else {
/* One of our sibling threads was faster, back out. */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/