diff options
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r-- | mm/mempolicy.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index c39bd86f4ea0..1850d0aef4ac 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -1131,6 +1131,15 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order) | |||
1131 | } | 1131 | } |
1132 | EXPORT_SYMBOL(alloc_pages_current); | 1132 | EXPORT_SYMBOL(alloc_pages_current); |
1133 | 1133 | ||
1134 | /* | ||
1135 | * If mpol_copy() sees current->cpuset == cpuset_being_rebound, then it | ||
1136 | * rebinds the mempolicy its copying by calling mpol_rebind_policy() | ||
1137 | * with the mems_allowed returned by cpuset_mems_allowed(). This | ||
1138 | * keeps mempolicies cpuset relative after its cpuset moves. See | ||
1139 | * further kernel/cpuset.c update_nodemask(). | ||
1140 | */ | ||
1141 | void *cpuset_being_rebound; | ||
1142 | |||
1134 | /* Slow path of a mempolicy copy */ | 1143 | /* Slow path of a mempolicy copy */ |
1135 | struct mempolicy *__mpol_copy(struct mempolicy *old) | 1144 | struct mempolicy *__mpol_copy(struct mempolicy *old) |
1136 | { | 1145 | { |
@@ -1138,6 +1147,10 @@ struct mempolicy *__mpol_copy(struct mempolicy *old) | |||
1138 | 1147 | ||
1139 | if (!new) | 1148 | if (!new) |
1140 | return ERR_PTR(-ENOMEM); | 1149 | return ERR_PTR(-ENOMEM); |
1150 | if (current_cpuset_is_being_rebound()) { | ||
1151 | nodemask_t mems = cpuset_mems_allowed(current); | ||
1152 | mpol_rebind_policy(old, &mems); | ||
1153 | } | ||
1141 | *new = *old; | 1154 | *new = *old; |
1142 | atomic_set(&new->refcnt, 1); | 1155 | atomic_set(&new->refcnt, 1); |
1143 | if (new->policy == MPOL_BIND) { | 1156 | if (new->policy == MPOL_BIND) { |
@@ -1481,6 +1494,22 @@ void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new) | |||
1481 | } | 1494 | } |
1482 | 1495 | ||
1483 | /* | 1496 | /* |
1497 | * Rebind each vma in mm to new nodemask. | ||
1498 | * | ||
1499 | * Call holding a reference to mm. Takes mm->mmap_sem during call. | ||
1500 | */ | ||
1501 | |||
1502 | void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new) | ||
1503 | { | ||
1504 | struct vm_area_struct *vma; | ||
1505 | |||
1506 | down_write(&mm->mmap_sem); | ||
1507 | for (vma = mm->mmap; vma; vma = vma->vm_next) | ||
1508 | mpol_rebind_policy(vma->vm_policy, new); | ||
1509 | up_write(&mm->mmap_sem); | ||
1510 | } | ||
1511 | |||
1512 | /* | ||
1484 | * Display pages allocated per node and memory policy via /proc. | 1513 | * Display pages allocated per node and memory policy via /proc. |
1485 | */ | 1514 | */ |
1486 | 1515 | ||