Index: linux-2.6.15-rc2-mm1/mm/mempolicy.c =================================================================== --- linux-2.6.15-rc2-mm1.orig/mm/mempolicy.c 2005-11-28 12:37:20.000000000 -0800 +++ linux-2.6.15-rc2-mm1/mm/mempolicy.c 2005-11-28 16:58:17.000000000 -0800 @@ -1580,8 +1580,8 @@ void numa_default_policy(void) } /* Migrate a policy to a different set of nodes */ -static void rebind_policy(struct mempolicy *pol, const nodemask_t *old, - const nodemask_t *new) +static void rebind_policy(struct task_struct *task, struct mempolicy *pol, + const nodemask_t *old, const nodemask_t *new) { nodemask_t tmp; @@ -1594,7 +1594,7 @@ static void rebind_policy(struct mempoli case MPOL_INTERLEAVE: nodes_remap(tmp, pol->v.nodes, *old, *new); pol->v.nodes = tmp; - current->il_next = node_remap(current->il_next, *old, *new); + task->il_next = node_remap(task->il_next, *old, *new); break; case MPOL_PREFERRED: pol->v.preferred_node = node_remap(pol->v.preferred_node, @@ -1632,14 +1632,27 @@ static void rebind_policy(struct mempoli } /* + * Rebind vma policies in an mm_struct + */ +void update_vma_policies(struct task_struct *task, struct mm_struct *mm, + const nodemask_t *old, const nodemask_t *new) +{ + struct vm_area_struct *vma; + + down_write(&mm->mmap_sem); + + for (vma = mm->mmap; vma; vma = vma->vm_next) + rebind_policy(task, vma->vm_policy, old, new); + + up_write(&mm->mmap_sem); +} + +/* * Someone moved this task to different nodes. Fixup mempolicies. - * - * TODO - fixup current->mm->vma and shmfs/tmpfs/hugetlbfs policies as well, - * once we have a cpuset mechanism to mark which cpuset subtree is migrating. */ void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new) { - rebind_policy(current->mempolicy, old, new); + rebind_policy(current, current->mempolicy, old, new); } /* Index: linux-2.6.15-rc2-mm1/kernel/cpuset.c =================================================================== --- linux-2.6.15-rc2-mm1.orig/kernel/cpuset.c 2005-11-28 12:30:08.000000000 -0800 +++ linux-2.6.15-rc2-mm1/kernel/cpuset.c 2005-11-28 16:59:28.000000000 -0800 @@ -677,9 +677,16 @@ static void refresh_mems(void) if (!nodes_equal(oldmem, current->mems_allowed)) { numa_policy_rebind(&oldmem, ¤t->mems_allowed); if (migrate) { + /* + * This should be done when the mems are modified + * and not while updating the tasks mems_allowed. + * We may not be able to take the mmap_sem lock! + */ do_migrate_pages(current->mm, &oldmem, ¤t->mems_allowed, MPOL_MF_MOVE_ALL); + update_vma_policies(current, current->mm, + &oldmem, ¤t->mems_allowed); } } } @@ -1092,8 +1099,11 @@ static int attach_task(struct cpuset *cs to = cs->mems_allowed; up(&callback_sem); - if (is_memory_migrate(cs)) + if (is_memory_migrate(cs)) { do_migrate_pages(tsk->mm, &from, &to, MPOL_MF_MOVE_ALL); + /* Ummm.. Are we allowed here to modify tsk->il_next ??? */ + update_vma_policies(tsk, tsk->mm, &from, &to); + } put_task_struct(tsk); if (atomic_dec_and_test(&oldcs->count)) check_for_release(oldcs, ppathbuf); Index: linux-2.6.15-rc2-mm1/include/linux/mempolicy.h =================================================================== --- linux-2.6.15-rc2-mm1.orig/include/linux/mempolicy.h 2005-11-28 12:30:08.000000000 -0800 +++ linux-2.6.15-rc2-mm1/include/linux/mempolicy.h 2005-11-28 16:59:48.000000000 -0800 @@ -147,6 +147,8 @@ struct mempolicy *mpol_shared_policy_loo extern void numa_default_policy(void); extern void numa_policy_init(void); extern void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new); +extern void update_vma_policies(struct task_struct *task, struct mm_struct *mm, + const nodemask_t *old, const nodemask_t *new); extern struct mempolicy default_policy; extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr);