diff options
-rw-r--r-- | include/linux/migrate.h | 11 | ||||
-rw-r--r-- | include/linux/mm.h | 2 | ||||
-rw-r--r-- | mm/mempolicy.c | 6 | ||||
-rw-r--r-- | mm/migrate.c | 20 |
4 files changed, 37 insertions, 2 deletions
diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 5dba23a1c0d0..48148e0cdbd1 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h | |||
@@ -16,7 +16,9 @@ extern int fail_migrate_page(struct address_space *, | |||
16 | struct page *, struct page *); | 16 | struct page *, struct page *); |
17 | 17 | ||
18 | extern int migrate_prep(void); | 18 | extern int migrate_prep(void); |
19 | 19 | extern int migrate_vmas(struct mm_struct *mm, | |
20 | const nodemask_t *from, const nodemask_t *to, | ||
21 | unsigned long flags); | ||
20 | #else | 22 | #else |
21 | 23 | ||
22 | static inline int isolate_lru_page(struct page *p, struct list_head *list) | 24 | static inline int isolate_lru_page(struct page *p, struct list_head *list) |
@@ -30,6 +32,13 @@ static inline int migrate_pages_to(struct list_head *pagelist, | |||
30 | 32 | ||
31 | static inline int migrate_prep(void) { return -ENOSYS; } | 33 | static inline int migrate_prep(void) { return -ENOSYS; } |
32 | 34 | ||
35 | static inline int migrate_vmas(struct mm_struct *mm, | ||
36 | const nodemask_t *from, const nodemask_t *to, | ||
37 | unsigned long flags) | ||
38 | { | ||
39 | return -ENOSYS; | ||
40 | } | ||
41 | |||
33 | /* Possible settings for the migrate_page() method in address_operations */ | 42 | /* Possible settings for the migrate_page() method in address_operations */ |
34 | #define migrate_page NULL | 43 | #define migrate_page NULL |
35 | #define fail_migrate_page NULL | 44 | #define fail_migrate_page NULL |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 71c5d2f667ed..a929ea197e48 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -206,6 +206,8 @@ struct vm_operations_struct { | |||
206 | int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new); | 206 | int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new); |
207 | struct mempolicy *(*get_policy)(struct vm_area_struct *vma, | 207 | struct mempolicy *(*get_policy)(struct vm_area_struct *vma, |
208 | unsigned long addr); | 208 | unsigned long addr); |
209 | int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from, | ||
210 | const nodemask_t *to, unsigned long flags); | ||
209 | #endif | 211 | #endif |
210 | }; | 212 | }; |
211 | 213 | ||
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index ec4a1a950df9..73e0f23b7f51 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -632,6 +632,10 @@ int do_migrate_pages(struct mm_struct *mm, | |||
632 | 632 | ||
633 | down_read(&mm->mmap_sem); | 633 | down_read(&mm->mmap_sem); |
634 | 634 | ||
635 | err = migrate_vmas(mm, from_nodes, to_nodes, flags); | ||
636 | if (err) | ||
637 | goto out; | ||
638 | |||
635 | /* | 639 | /* |
636 | * Find a 'source' bit set in 'tmp' whose corresponding 'dest' | 640 | * Find a 'source' bit set in 'tmp' whose corresponding 'dest' |
637 | * bit in 'to' is not also set in 'tmp'. Clear the found 'source' | 641 | * bit in 'to' is not also set in 'tmp'. Clear the found 'source' |
@@ -691,7 +695,7 @@ int do_migrate_pages(struct mm_struct *mm, | |||
691 | if (err < 0) | 695 | if (err < 0) |
692 | break; | 696 | break; |
693 | } | 697 | } |
694 | 698 | out: | |
695 | up_read(&mm->mmap_sem); | 699 | up_read(&mm->mmap_sem); |
696 | if (err < 0) | 700 | if (err < 0) |
697 | return err; | 701 | return err; |
diff --git a/mm/migrate.c b/mm/migrate.c index 1c2a71aa05cd..0576c0535988 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -976,3 +976,23 @@ out2: | |||
976 | } | 976 | } |
977 | #endif | 977 | #endif |
978 | 978 | ||
979 | /* | ||
980 | * Call migration functions in the vma_ops that may prepare | ||
981 | * memory in a vm for migration. migration functions may perform | ||
982 | * the migration for vmas that do not have an underlying page struct. | ||
983 | */ | ||
984 | int migrate_vmas(struct mm_struct *mm, const nodemask_t *to, | ||
985 | const nodemask_t *from, unsigned long flags) | ||
986 | { | ||
987 | struct vm_area_struct *vma; | ||
988 | int err = 0; | ||
989 | |||
990 | for(vma = mm->mmap; vma->vm_next && !err; vma = vma->vm_next) { | ||
991 | if (vma->vm_ops && vma->vm_ops->migrate) { | ||
992 | err = vma->vm_ops->migrate(vma, to, from, flags); | ||
993 | if (err) | ||
994 | break; | ||
995 | } | ||
996 | } | ||
997 | return err; | ||
998 | } | ||