diff options
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index c1592a94582f..83c69f8a64c2 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -722,12 +722,29 @@ out: | |||
722 | 722 | ||
723 | } | 723 | } |
724 | 724 | ||
725 | /* | ||
726 | * Allocate a new page for page migration based on vma policy. | ||
727 | * Start assuming that page is mapped by vma pointed to by @private. | ||
728 | * Search forward from there, if not. N.B., this assumes that the | ||
729 | * list of pages handed to migrate_pages()--which is how we get here-- | ||
730 | * is in virtual address order. | ||
731 | */ | ||
725 | static struct page *new_vma_page(struct page *page, unsigned long private, int **x) | 732 | static struct page *new_vma_page(struct page *page, unsigned long private, int **x) |
726 | { | 733 | { |
727 | struct vm_area_struct *vma = (struct vm_area_struct *)private; | 734 | struct vm_area_struct *vma = (struct vm_area_struct *)private; |
735 | unsigned long uninitialized_var(address); | ||
728 | 736 | ||
729 | return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, | 737 | while (vma) { |
730 | page_address_in_vma(page, vma)); | 738 | address = page_address_in_vma(page, vma); |
739 | if (address != -EFAULT) | ||
740 | break; | ||
741 | vma = vma->vm_next; | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * if !vma, alloc_page_vma() will use task or system default policy | ||
746 | */ | ||
747 | return alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address); | ||
731 | } | 748 | } |
732 | #else | 749 | #else |
733 | 750 | ||