diff options
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 43 |
1 files changed, 7 insertions, 36 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 551cde40520b..a683a66599b1 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -185,8 +185,8 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | static void gather_stats(struct page *, void *); | 187 | static void gather_stats(struct page *, void *); |
188 | static void migrate_page_add(struct vm_area_struct *vma, | 188 | static void migrate_page_add(struct page *page, struct list_head *pagelist, |
189 | struct page *page, struct list_head *pagelist, unsigned long flags); | 189 | unsigned long flags); |
190 | 190 | ||
191 | /* Scan through pages checking if pages follow certain conditions. */ | 191 | /* Scan through pages checking if pages follow certain conditions. */ |
192 | static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | 192 | static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, |
@@ -228,7 +228,7 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
228 | if (flags & MPOL_MF_STATS) | 228 | if (flags & MPOL_MF_STATS) |
229 | gather_stats(page, private); | 229 | gather_stats(page, private); |
230 | else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) | 230 | else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) |
231 | migrate_page_add(vma, page, private, flags); | 231 | migrate_page_add(page, private, flags); |
232 | else | 232 | else |
233 | break; | 233 | break; |
234 | } while (pte++, addr += PAGE_SIZE, addr != end); | 234 | } while (pte++, addr += PAGE_SIZE, addr != end); |
@@ -531,42 +531,13 @@ long do_get_mempolicy(int *policy, nodemask_t *nmask, | |||
531 | * page migration | 531 | * page migration |
532 | */ | 532 | */ |
533 | 533 | ||
534 | /* Check if we are the only process mapping the page in question */ | 534 | static void migrate_page_add(struct page *page, struct list_head *pagelist, |
535 | static inline int single_mm_mapping(struct mm_struct *mm, | 535 | unsigned long flags) |
536 | struct address_space *mapping) | ||
537 | { | ||
538 | struct vm_area_struct *vma; | ||
539 | struct prio_tree_iter iter; | ||
540 | int rc = 1; | ||
541 | |||
542 | spin_lock(&mapping->i_mmap_lock); | ||
543 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX) | ||
544 | if (mm != vma->vm_mm) { | ||
545 | rc = 0; | ||
546 | goto out; | ||
547 | } | ||
548 | list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list) | ||
549 | if (mm != vma->vm_mm) { | ||
550 | rc = 0; | ||
551 | goto out; | ||
552 | } | ||
553 | out: | ||
554 | spin_unlock(&mapping->i_mmap_lock); | ||
555 | return rc; | ||
556 | } | ||
557 | |||
558 | /* | ||
559 | * Add a page to be migrated to the pagelist | ||
560 | */ | ||
561 | static void migrate_page_add(struct vm_area_struct *vma, | ||
562 | struct page *page, struct list_head *pagelist, unsigned long flags) | ||
563 | { | 536 | { |
564 | /* | 537 | /* |
565 | * Avoid migrating a page that is shared by others and not writable. | 538 | * Avoid migrating a page that is shared with others. |
566 | */ | 539 | */ |
567 | if ((flags & MPOL_MF_MOVE_ALL) || !page->mapping || PageAnon(page) || | 540 | if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(page) == 1) { |
568 | mapping_writably_mapped(page->mapping) || | ||
569 | single_mm_mapping(vma->vm_mm, page->mapping)) { | ||
570 | if (isolate_lru_page(page)) | 541 | if (isolate_lru_page(page)) |
571 | list_add(&page->lru, pagelist); | 542 | list_add(&page->lru, pagelist); |
572 | } | 543 | } |