diff options
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 27 |
1 files changed, 22 insertions, 5 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 | ||
432 | static 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 | |||
432 | long do_mbind(unsigned long start, unsigned long len, | 445 | long 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 | } |