From 61f9bf656c41ae6fc2b1777d407268f0427eb7eb Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 8 Jan 2006 01:00:55 -0800 Subject: [PATCH] --- yaml --- r: 16843 b: refs/heads/master c: d498471133ff1f9586a06820beaeebc575fe2814 h: refs/heads/master i: 16841: 6a09dde0118c456f923ac1fc2fed439a49618615 16839: 3253ff3675f197f9282b05528eeb0562bbf4f72a v: v3 --- [refs] | 2 +- trunk/include/linux/swap.h | 3 ++- trunk/mm/mempolicy.c | 27 ++++++++++++++++++++++----- trunk/mm/vmscan.c | 17 ++++++++--------- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/[refs] b/[refs] index 84759e687e4f..2a75ee8eb069 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ee27497df36823f2793212cad0997c044eb0e1eb +refs/heads/master: d498471133ff1f9586a06820beaeebc575fe2814 diff --git a/trunk/include/linux/swap.h b/trunk/include/linux/swap.h index eb591eaad1b7..389d1c382e20 100644 --- a/trunk/include/linux/swap.h +++ b/trunk/include/linux/swap.h @@ -178,7 +178,8 @@ extern int vm_swappiness; #ifdef CONFIG_MIGRATION extern int isolate_lru_page(struct page *p); extern int putback_lru_pages(struct list_head *l); -extern int migrate_pages(struct list_head *l, struct list_head *t); +extern int migrate_pages(struct list_head *l, struct list_head *t, + struct list_head *moved, struct list_head *failed); #endif #ifdef CONFIG_MMU diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 20d5ad39fa41..30bdafba52d8 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -429,6 +429,19 @@ static int contextualize_policy(int mode, nodemask_t *nodes) return mpol_check_policy(mode, nodes); } +static int swap_pages(struct list_head *pagelist) +{ + LIST_HEAD(moved); + LIST_HEAD(failed); + int n; + + n = migrate_pages(pagelist, NULL, &moved, &failed); + putback_lru_pages(&failed); + putback_lru_pages(&moved); + + return n; +} + long do_mbind(unsigned long start, unsigned long len, unsigned long mode, nodemask_t *nmask, unsigned long flags) { @@ -481,10 +494,13 @@ long do_mbind(unsigned long start, unsigned long len, (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) ? &pagelist : NULL); err = PTR_ERR(vma); if (!IS_ERR(vma)) { + int nr_failed = 0; + err = mbind_range(vma, start, end, new); if (!list_empty(&pagelist)) - migrate_pages(&pagelist, NULL); - if (!err && !list_empty(&pagelist) && (flags & MPOL_MF_STRICT)) + nr_failed = swap_pages(&pagelist); + + if (!err && nr_failed && (flags & MPOL_MF_STRICT)) err = -EIO; } if (!list_empty(&pagelist)) @@ -635,11 +651,12 @@ int do_migrate_pages(struct mm_struct *mm, down_read(&mm->mmap_sem); check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes, flags | MPOL_MF_DISCONTIG_OK, &pagelist); + if (!list_empty(&pagelist)) { - migrate_pages(&pagelist, NULL); - if (!list_empty(&pagelist)) - count = putback_lru_pages(&pagelist); + count = swap_pages(&pagelist); + putback_lru_pages(&pagelist); } + up_read(&mm->mmap_sem); return count; } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 73ba4046ed27..5eecb514ccea 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -670,10 +670,10 @@ static int swap_page(struct page *page) * list. The direct migration patchset * extends this function to avoid the use of swap. */ -int migrate_pages(struct list_head *l, struct list_head *t) +int migrate_pages(struct list_head *from, struct list_head *to, + struct list_head *moved, struct list_head *failed) { int retry; - LIST_HEAD(failed); int nr_failed = 0; int pass = 0; struct page *page; @@ -686,12 +686,12 @@ int migrate_pages(struct list_head *l, struct list_head *t) redo: retry = 0; - list_for_each_entry_safe(page, page2, l, lru) { + list_for_each_entry_safe(page, page2, from, lru) { cond_resched(); if (page_count(page) == 1) { /* page was freed from under us. So we are done. */ - move_to_lru(page); + list_move(&page->lru, moved); continue; } /* @@ -722,7 +722,7 @@ int migrate_pages(struct list_head *l, struct list_head *t) if (PageAnon(page) && !PageSwapCache(page)) { if (!add_to_swap(page, GFP_KERNEL)) { unlock_page(page); - list_move(&page->lru, &failed); + list_move(&page->lru, failed); nr_failed++; continue; } @@ -732,8 +732,10 @@ int migrate_pages(struct list_head *l, struct list_head *t) * Page is properly locked and writeback is complete. * Try to migrate the page. */ - if (!swap_page(page)) + if (!swap_page(page)) { + list_move(&page->lru, moved); continue; + } retry_later: retry++; } @@ -743,9 +745,6 @@ int migrate_pages(struct list_head *l, struct list_head *t) if (!swapwrite) current->flags &= ~PF_SWAPWRITE; - if (!list_empty(&failed)) - list_splice(&failed, l); - return nr_failed + retry; }