mm: Migrate misplaced page
Subsystems (3)
Commit-ID: 4783af477d3da0e2643cf2f0619265fdf12f29f4 Gitweb: http://git.kernel.org/tip/4783af477d3da0e2643cf2f0619265fdf12f29f4 Author: Lee Schermerhorn <[email protected]> AuthorDate: Wed, 11 Jan 2012 16:31:57 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 18 May 2012 08:16:18 +0200
mm: Migrate misplaced page
This patch adds a new function migrate_misplaced_page() to mm/migrate.c [where most of the other page migration functions live] to migrate a misplaced page to a specified destination node. This function will be called from the fault path. Because we already know the destination node for the migration, we allocate pages directly rather than rerunning the policy node computation in alloc_page_vma().
Since the fault path holds an extra reference from other migration paths, introduce a new migration_mode (MIGRATE_FAULT) to communicate this.
The patch adds the function check_migrate_misplaced_page() to migrate.c to check whether a page is "misplaced" -- i.e. on a node different from what the policy for (vma, address) dictates. This check involves accessing the vma policy, so we only do this if:
* page has zero mapcount [no pte references]
* page is not in writeback
* page is up to date
* page's mapping has a migratepage a_op [no fallback!]
If these checks are satisfied, the page will be migrated to the "correct" node, if possible. If migration fails for any reason, we just use the original page.
Subsequent patches will hook the fault handlers [anon, and possibly file and/or shmem] to check_migrate_misplaced_page().
[ removed the weird ignore page count on migrate stuff with the
new migrate_mode and strict accounting ]
--- include/linux/mempolicy.h | 18 +----- include/linux/migrate.h | 14 +++++ include/linux/migrate_mode.h | 3 + mm/mempolicy.c | 19 ++++++ mm/migrate.c | 130 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 167 insertions(+), 17 deletions(-)
include/linux/mempolicy.h +2 -16
@@ -78,6 +78,7 @@ enum mpol_rebind_step {#include <linux/spinlock.h> #include <linux/nodemask.h> #include <linux/pagemap.h> +#include <linux/migrate.h> struct mm_struct ;
@@ -246,22 +247,7 @@ extern int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context);extern int mpol_to_str (char *buffer,int maxlen,struct mempolicy *pol,int no_context); -/* Check if a vma is migratable */ -static inline int vma_migratable (struct vm_area_struct *vma) -{ -if (vma->vm_flags & (VM_IO |VM_HUGETLB |VM_PFNMAP |VM_RESERVED )) -return 0 ; -/* -* Migration allocates pages in the highest zone. If we cannot -* do so then migration (at least from node to node) is not -* possible. -*/ -if (vma->vm_file && -gfp_zone (mapping_gfp_mask (vma->vm_file->f_mapping)) - < policy_zone) -return 0 ; -return 1 ; -} +extern int vma_migratable (struct vm_area_struct *);extern int mpol_misplaced (struct page *,struct vm_area_struct *,unsigned long );
include/linux/migrate.h +14 -0
@@ -32,6 +32,8 @@ extern int migrate_huge_page_move_mapping(struct address_space *mapping, struct page *newpage, struct page *page);extern int migrate_pages_unmap_only (struct list_head *); +extern struct page *migrate_misplaced_page (struct page *, +struct mm_struct *,int );#else static inline void putback_lru_pages (struct list_head *l) {}
@@ -71,4 +73,16 @@ static inline int migrate_pages_unmap_only(struct list_head *l)#define fail_migrate_page NULL#endif /* CONFIG_MIGRATION */ + +#if defined(CONFIG_MIGRATION ) && defined(CONFIG_NUMA ) +extern struct page *check_migrate_misplaced_page (struct page *, +struct vm_area_struct *,unsigned long ); +#else +static inline struct page *check_migrate_misplaced_page (struct page *page, +struct vm_area_struct *vma,unsigned long addr) +{ +return page; +} +#endif +#endif /* _LINUX_MIGRATE_H */
include/linux/migrate_mode.h +3 -0
@@ -6,11 +6,14 @@* on most operations but not ->writepage as the potential stall time * is too significant * MIGRATE_SYNC will block when migrating pages +* MIGRATE_FAULT called from the fault path to migrate-on-fault for mempolicy +* this path has an extra reference count */ enum migrate_mode {MIGRATE_ASYNC ,MIGRATE_SYNC_LIGHT ,MIGRATE_SYNC , +MIGRATE_FAULT , };#endif /* MIGRATE_MODE_H_INCLUDED */
mm/mempolicy.c +19 -0
@@ -464,6 +464,25 @@ static const struct mempolicy_operations mpol_ops[MPOL_MAX] = {static void migrate_page_add (struct page *page,struct list_head *pagelist,unsigned long flags); +/* +* Check whether a vma is migratable +*/ +int vma_migratable (struct vm_area_struct *vma) +{ +if (vma->vm_flags & (VM_IO |VM_HUGETLB |VM_PFNMAP |VM_RESERVED )) +return 0 ; +/* +* Migration allocates pages in the highest zone. If we cannot +* do so then migration (at least from node to node) is not +* possible. +*/ +if (vma->vm_file && +gfp_zone (mapping_gfp_mask (vma->vm_file->f_mapping)) + < policy_zone) +return 0 ; +return 1 ; +} +struct mempol_walk_data {struct vm_area_struct *vma;const nodemask_t *nodes;
mm/migrate.c +129 -1
139 lines not on this page · raw message