Skip to content

Commit

Permalink
[PATCH] SwapMig: Extend parameters for migrate_pages()
Browse files Browse the repository at this point in the history
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: Christoph Lameter <clameter@sgi.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Christoph Lameter authored and Linus Torvalds committed Jan 9, 2006
1 parent ee27497 commit d498471
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 15 deletions.
3 changes: 2 additions & 1 deletion include/linux/swap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 22 additions & 5 deletions mm/mempolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
}
Expand Down
17 changes: 8 additions & 9 deletions mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
/*
Expand Down Expand Up @@ -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;
}
Expand All @@ -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++;
}
Expand All @@ -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;
}

Expand Down

0 comments on commit d498471

Please sign in to comment.