aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c43
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
187static void gather_stats(struct page *, void *); 187static void gather_stats(struct page *, void *);
188static void migrate_page_add(struct vm_area_struct *vma, 188static 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. */
192static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, 192static 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 */ 534static void migrate_page_add(struct page *page, struct list_head *pagelist,
535static 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 }
553out:
554 spin_unlock(&mapping->i_mmap_lock);
555 return rc;
556}
557
558/*
559 * Add a page to be migrated to the pagelist
560 */
561static 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 }