Commit b124bc14 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] rmap 21 try_to_unmap_one mapcount

From: Hugh Dickins <hugh@veritas.com>

Why should try_to_unmap_anon and try_to_unmap_file take a copy of
page->mapcount and pass it down for try_to_unmap_one to decrement?  why not
just check page->mapcount itself?  asks akpm.  Perhaps there used to be a good
reason, but not any more: remove the mapcount arg.
parent c7a491f0
...@@ -462,9 +462,8 @@ int fastcall mremap_move_anon_rmap(struct page *page, unsigned long address) ...@@ -462,9 +462,8 @@ int fastcall mremap_move_anon_rmap(struct page *page, unsigned long address)
* Subfunctions of try_to_unmap: try_to_unmap_one called * Subfunctions of try_to_unmap: try_to_unmap_one called
* repeatedly from either try_to_unmap_anon or try_to_unmap_file. * repeatedly from either try_to_unmap_anon or try_to_unmap_file.
*/ */
static int try_to_unmap_one(struct page *page, static int try_to_unmap_one(struct page *page, struct mm_struct *mm,
struct mm_struct *mm, unsigned long address, unsigned long address, struct vm_area_struct *vma)
unsigned int *mapcount, struct vm_area_struct *vma)
{ {
pgd_t *pgd; pgd_t *pgd;
pmd_t *pmd; pmd_t *pmd;
...@@ -494,8 +493,6 @@ static int try_to_unmap_one(struct page *page, ...@@ -494,8 +493,6 @@ static int try_to_unmap_one(struct page *page,
if (page_to_pfn(page) != pte_pfn(*pte)) if (page_to_pfn(page) != pte_pfn(*pte))
goto out_unmap; goto out_unmap;
(*mapcount)--;
if (!vma) { if (!vma) {
vma = find_vma(mm, address); vma = find_vma(mm, address);
/* unmap_vmas drops page_table_lock with vma unlinked */ /* unmap_vmas drops page_table_lock with vma unlinked */
...@@ -654,7 +651,6 @@ static int try_to_unmap_cluster(struct mm_struct *mm, unsigned long cursor, ...@@ -654,7 +651,6 @@ static int try_to_unmap_cluster(struct mm_struct *mm, unsigned long cursor,
static inline int try_to_unmap_anon(struct page *page) static inline int try_to_unmap_anon(struct page *page)
{ {
unsigned int mapcount = page->mapcount;
struct anonmm *anonmm = (struct anonmm *) page->mapping; struct anonmm *anonmm = (struct anonmm *) page->mapping;
struct anonmm *anonhd = anonmm->head; struct anonmm *anonhd = anonmm->head;
struct list_head *seek_head; struct list_head *seek_head;
...@@ -665,9 +661,8 @@ static inline int try_to_unmap_anon(struct page *page) ...@@ -665,9 +661,8 @@ static inline int try_to_unmap_anon(struct page *page)
* First try the indicated mm, it's the most likely. * First try the indicated mm, it's the most likely.
*/ */
if (anonmm->mm && anonmm->mm->rss) { if (anonmm->mm && anonmm->mm->rss) {
ret = try_to_unmap_one(page, ret = try_to_unmap_one(page, anonmm->mm, page->index, NULL);
anonmm->mm, page->index, &mapcount, NULL); if (ret == SWAP_FAIL || !page->mapcount)
if (ret == SWAP_FAIL || !mapcount)
goto out; goto out;
} }
...@@ -681,9 +676,8 @@ static inline int try_to_unmap_anon(struct page *page) ...@@ -681,9 +676,8 @@ static inline int try_to_unmap_anon(struct page *page)
list_for_each_entry(anonmm, seek_head, list) { list_for_each_entry(anonmm, seek_head, list) {
if (!anonmm->mm || !anonmm->mm->rss) if (!anonmm->mm || !anonmm->mm->rss)
continue; continue;
ret = try_to_unmap_one(page, ret = try_to_unmap_one(page, anonmm->mm, page->index, NULL);
anonmm->mm, page->index, &mapcount, NULL); if (ret == SWAP_FAIL || !page->mapcount)
if (ret == SWAP_FAIL || !mapcount)
goto out; goto out;
} }
out: out:
...@@ -705,7 +699,6 @@ static inline int try_to_unmap_anon(struct page *page) ...@@ -705,7 +699,6 @@ static inline int try_to_unmap_anon(struct page *page)
*/ */
static inline int try_to_unmap_file(struct page *page) static inline int try_to_unmap_file(struct page *page)
{ {
unsigned int mapcount = page->mapcount;
struct address_space *mapping = page->mapping; struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct vm_area_struct *vma = NULL; struct vm_area_struct *vma = NULL;
...@@ -715,6 +708,7 @@ static inline int try_to_unmap_file(struct page *page) ...@@ -715,6 +708,7 @@ static inline int try_to_unmap_file(struct page *page)
unsigned long cursor; unsigned long cursor;
unsigned long max_nl_cursor = 0; unsigned long max_nl_cursor = 0;
unsigned long max_nl_size = 0; unsigned long max_nl_size = 0;
unsigned int mapcount;
if (!spin_trylock(&mapping->i_mmap_lock)) if (!spin_trylock(&mapping->i_mmap_lock))
return ret; return ret;
...@@ -723,9 +717,8 @@ static inline int try_to_unmap_file(struct page *page) ...@@ -723,9 +717,8 @@ static inline int try_to_unmap_file(struct page *page)
&iter, pgoff, pgoff)) != NULL) { &iter, pgoff, pgoff)) != NULL) {
if (vma->vm_mm->rss) { if (vma->vm_mm->rss) {
address = vma_address(vma, pgoff); address = vma_address(vma, pgoff);
ret = try_to_unmap_one(page, ret = try_to_unmap_one(page, vma->vm_mm, address, vma);
vma->vm_mm, address, &mapcount, vma); if (ret == SWAP_FAIL || !page->mapcount)
if (ret == SWAP_FAIL || !mapcount)
goto out; goto out;
} }
} }
...@@ -755,6 +748,7 @@ static inline int try_to_unmap_file(struct page *page) ...@@ -755,6 +748,7 @@ static inline int try_to_unmap_file(struct page *page)
* The mapcount of the page we came in with is irrelevant, * The mapcount of the page we came in with is irrelevant,
* but even so use it as a guide to how hard we should try? * but even so use it as a guide to how hard we should try?
*/ */
mapcount = page->mapcount;
page_map_unlock(page); page_map_unlock(page);
cond_resched_lock(&mapping->i_mmap_lock); cond_resched_lock(&mapping->i_mmap_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment