aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2006-01-08 04:00:55 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-08 23:12:42 -0500
commitd498471133ff1f9586a06820beaeebc575fe2814 (patch)
treec7cde93441692e3b32d83dfbf85858ab2d85e481 /mm
parentee27497df36823f2793212cad0997c044eb0e1eb (diff)
[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: 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>
Diffstat (limited to 'mm')
-rw-r--r--mm/mempolicy.c27
-rw-r--r--mm/vmscan.c17
2 files changed, 30 insertions, 14 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 20d5ad39fa41..30bdafba52d8 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -429,6 +429,19 @@ static int contextualize_policy(int mode, nodemask_t *nodes)
429 return mpol_check_policy(mode, nodes); 429 return mpol_check_policy(mode, nodes);
430} 430}
431 431
432static int swap_pages(struct list_head *pagelist)
433{
434 LIST_HEAD(moved);
435 LIST_HEAD(failed);
436 int n;
437
438 n = migrate_pages(pagelist, NULL, &moved, &failed);
439 putback_lru_pages(&failed);
440 putback_lru_pages(&moved);
441
442 return n;
443}
444
432long do_mbind(unsigned long start, unsigned long len, 445long do_mbind(unsigned long start, unsigned long len,
433 unsigned long mode, nodemask_t *nmask, unsigned long flags) 446 unsigned long mode, nodemask_t *nmask, unsigned long flags)
434{ 447{
@@ -481,10 +494,13 @@ long do_mbind(unsigned long start, unsigned long len,
481 (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) ? &pagelist : NULL); 494 (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) ? &pagelist : NULL);
482 err = PTR_ERR(vma); 495 err = PTR_ERR(vma);
483 if (!IS_ERR(vma)) { 496 if (!IS_ERR(vma)) {
497 int nr_failed = 0;
498
484 err = mbind_range(vma, start, end, new); 499 err = mbind_range(vma, start, end, new);
485 if (!list_empty(&pagelist)) 500 if (!list_empty(&pagelist))
486 migrate_pages(&pagelist, NULL); 501 nr_failed = swap_pages(&pagelist);
487 if (!err && !list_empty(&pagelist) && (flags & MPOL_MF_STRICT)) 502
503 if (!err && nr_failed && (flags & MPOL_MF_STRICT))
488 err = -EIO; 504 err = -EIO;
489 } 505 }
490 if (!list_empty(&pagelist)) 506 if (!list_empty(&pagelist))
@@ -635,11 +651,12 @@ int do_migrate_pages(struct mm_struct *mm,
635 down_read(&mm->mmap_sem); 651 down_read(&mm->mmap_sem);
636 check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes, 652 check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes,
637 flags | MPOL_MF_DISCONTIG_OK, &pagelist); 653 flags | MPOL_MF_DISCONTIG_OK, &pagelist);
654
638 if (!list_empty(&pagelist)) { 655 if (!list_empty(&pagelist)) {
639 migrate_pages(&pagelist, NULL); 656 count = swap_pages(&pagelist);
640 if (!list_empty(&pagelist)) 657 putback_lru_pages(&pagelist);
641 count = putback_lru_pages(&pagelist);
642 } 658 }
659
643 up_read(&mm->mmap_sem); 660 up_read(&mm->mmap_sem);
644 return count; 661 return count;
645} 662}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 73ba4046ed27..5eecb514ccea 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -670,10 +670,10 @@ retry:
670 * list. The direct migration patchset 670 * list. The direct migration patchset
671 * extends this function to avoid the use of swap. 671 * extends this function to avoid the use of swap.
672 */ 672 */
673int migrate_pages(struct list_head *l, struct list_head *t) 673int migrate_pages(struct list_head *from, struct list_head *to,
674 struct list_head *moved, struct list_head *failed)
674{ 675{
675 int retry; 676 int retry;
676 LIST_HEAD(failed);
677 int nr_failed = 0; 677 int nr_failed = 0;
678 int pass = 0; 678 int pass = 0;
679 struct page *page; 679 struct page *page;
@@ -686,12 +686,12 @@ int migrate_pages(struct list_head *l, struct list_head *t)
686redo: 686redo:
687 retry = 0; 687 retry = 0;
688 688
689 list_for_each_entry_safe(page, page2, l, lru) { 689 list_for_each_entry_safe(page, page2, from, lru) {
690 cond_resched(); 690 cond_resched();
691 691
692 if (page_count(page) == 1) { 692 if (page_count(page) == 1) {
693 /* page was freed from under us. So we are done. */ 693 /* page was freed from under us. So we are done. */
694 move_to_lru(page); 694 list_move(&page->lru, moved);
695 continue; 695 continue;
696 } 696 }
697 /* 697 /*
@@ -722,7 +722,7 @@ redo:
722 if (PageAnon(page) && !PageSwapCache(page)) { 722 if (PageAnon(page) && !PageSwapCache(page)) {
723 if (!add_to_swap(page, GFP_KERNEL)) { 723 if (!add_to_swap(page, GFP_KERNEL)) {
724 unlock_page(page); 724 unlock_page(page);
725 list_move(&page->lru, &failed); 725 list_move(&page->lru, failed);
726 nr_failed++; 726 nr_failed++;
727 continue; 727 continue;
728 } 728 }
@@ -732,8 +732,10 @@ redo:
732 * Page is properly locked and writeback is complete. 732 * Page is properly locked and writeback is complete.
733 * Try to migrate the page. 733 * Try to migrate the page.
734 */ 734 */
735 if (!swap_page(page)) 735 if (!swap_page(page)) {
736 list_move(&page->lru, moved);
736 continue; 737 continue;
738 }
737retry_later: 739retry_later:
738 retry++; 740 retry++;
739 } 741 }
@@ -743,9 +745,6 @@ retry_later:
743 if (!swapwrite) 745 if (!swapwrite)
744 current->flags &= ~PF_SWAPWRITE; 746 current->flags &= ~PF_SWAPWRITE;
745 747
746 if (!list_empty(&failed))
747 list_splice(&failed, l);
748
749 return nr_failed + retry; 748 return nr_failed + retry;
750} 749}
751 750