提交 d4984711 编写于 作者: C Christoph Lameter 提交者: Linus Torvalds

[PATCH] SwapMig: Extend parameters for migrate_pages()

Extend the parameters of migrate_pages() to allow the caller control over the
fate of successfully migrated or impossible to migrate pages.

Swap migration and direct migration will have the same interface after this
patch so that patches can be independently applied to the policy layer and the
core migration code.
Signed-off-by: NChristoph Lameter <clameter@sgi.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 ee27497d
...@@ -178,7 +178,8 @@ extern int vm_swappiness; ...@@ -178,7 +178,8 @@ extern int vm_swappiness;
#ifdef CONFIG_MIGRATION #ifdef CONFIG_MIGRATION
extern int isolate_lru_page(struct page *p); extern int isolate_lru_page(struct page *p);
extern int putback_lru_pages(struct list_head *l); 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 #endif
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
......
...@@ -429,6 +429,19 @@ static int contextualize_policy(int mode, nodemask_t *nodes) ...@@ -429,6 +429,19 @@ static int contextualize_policy(int mode, nodemask_t *nodes)
return mpol_check_policy(mode, 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, long do_mbind(unsigned long start, unsigned long len,
unsigned long mode, nodemask_t *nmask, unsigned long flags) unsigned long mode, nodemask_t *nmask, unsigned long flags)
{ {
...@@ -481,10 +494,13 @@ long do_mbind(unsigned long start, unsigned long len, ...@@ -481,10 +494,13 @@ long do_mbind(unsigned long start, unsigned long len,
(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) ? &pagelist : NULL); (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) ? &pagelist : NULL);
err = PTR_ERR(vma); err = PTR_ERR(vma);
if (!IS_ERR(vma)) { if (!IS_ERR(vma)) {
int nr_failed = 0;
err = mbind_range(vma, start, end, new); err = mbind_range(vma, start, end, new);
if (!list_empty(&pagelist)) if (!list_empty(&pagelist))
migrate_pages(&pagelist, NULL); nr_failed = swap_pages(&pagelist);
if (!err && !list_empty(&pagelist) && (flags & MPOL_MF_STRICT))
if (!err && nr_failed && (flags & MPOL_MF_STRICT))
err = -EIO; err = -EIO;
} }
if (!list_empty(&pagelist)) if (!list_empty(&pagelist))
...@@ -635,11 +651,12 @@ int do_migrate_pages(struct mm_struct *mm, ...@@ -635,11 +651,12 @@ int do_migrate_pages(struct mm_struct *mm,
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes, check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes,
flags | MPOL_MF_DISCONTIG_OK, &pagelist); flags | MPOL_MF_DISCONTIG_OK, &pagelist);
if (!list_empty(&pagelist)) { if (!list_empty(&pagelist)) {
migrate_pages(&pagelist, NULL); count = swap_pages(&pagelist);
if (!list_empty(&pagelist)) putback_lru_pages(&pagelist);
count = putback_lru_pages(&pagelist);
} }
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
return count; return count;
} }
......
...@@ -670,10 +670,10 @@ static int swap_page(struct page *page) ...@@ -670,10 +670,10 @@ static int swap_page(struct page *page)
* list. The direct migration patchset * list. The direct migration patchset
* extends this function to avoid the use of swap. * 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; int retry;
LIST_HEAD(failed);
int nr_failed = 0; int nr_failed = 0;
int pass = 0; int pass = 0;
struct page *page; struct page *page;
...@@ -686,12 +686,12 @@ int migrate_pages(struct list_head *l, struct list_head *t) ...@@ -686,12 +686,12 @@ int migrate_pages(struct list_head *l, struct list_head *t)
redo: redo:
retry = 0; retry = 0;
list_for_each_entry_safe(page, page2, l, lru) { list_for_each_entry_safe(page, page2, from, lru) {
cond_resched(); cond_resched();
if (page_count(page) == 1) { if (page_count(page) == 1) {
/* page was freed from under us. So we are done. */ /* page was freed from under us. So we are done. */
move_to_lru(page); list_move(&page->lru, moved);
continue; continue;
} }
/* /*
...@@ -722,7 +722,7 @@ int migrate_pages(struct list_head *l, struct list_head *t) ...@@ -722,7 +722,7 @@ int migrate_pages(struct list_head *l, struct list_head *t)
if (PageAnon(page) && !PageSwapCache(page)) { if (PageAnon(page) && !PageSwapCache(page)) {
if (!add_to_swap(page, GFP_KERNEL)) { if (!add_to_swap(page, GFP_KERNEL)) {
unlock_page(page); unlock_page(page);
list_move(&page->lru, &failed); list_move(&page->lru, failed);
nr_failed++; nr_failed++;
continue; continue;
} }
...@@ -732,8 +732,10 @@ int migrate_pages(struct list_head *l, struct list_head *t) ...@@ -732,8 +732,10 @@ int migrate_pages(struct list_head *l, struct list_head *t)
* Page is properly locked and writeback is complete. * Page is properly locked and writeback is complete.
* Try to migrate the page. * Try to migrate the page.
*/ */
if (!swap_page(page)) if (!swap_page(page)) {
list_move(&page->lru, moved);
continue; continue;
}
retry_later: retry_later:
retry++; retry++;
} }
...@@ -743,9 +745,6 @@ int migrate_pages(struct list_head *l, struct list_head *t) ...@@ -743,9 +745,6 @@ int migrate_pages(struct list_head *l, struct list_head *t)
if (!swapwrite) if (!swapwrite)
current->flags &= ~PF_SWAPWRITE; current->flags &= ~PF_SWAPWRITE;
if (!list_empty(&failed))
list_splice(&failed, l);
return nr_failed + retry; return nr_failed + retry;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册