task_unlock(tsk);
if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {
- nodemask_t oldmem = tsk->mems_allowed;
- int migrate;
-
down(&callback_sem);
task_lock(tsk);
cs = tsk->cpuset; /* Maybe changed when task not locked */
- migrate = is_memory_migrate(cs);
guarantee_online_mems(cs, &tsk->mems_allowed);
tsk->cpuset_mems_generation = cs->mems_generation;
task_unlock(tsk);
up(&callback_sem);
mpol_rebind_task(tsk, &tsk->mems_allowed);
- if (!nodes_equal(oldmem, tsk->mems_allowed)) {
- if (migrate) {
- do_migrate_pages(tsk->mm, &oldmem,
- &tsk->mems_allowed,
- MPOL_MF_MOVE_ALL);
- }
- }
}
}
* Handle user request to change the 'mems' memory placement
* of a cpuset. Needs to validate the request, update the
* cpusets mems_allowed and mems_generation, and for each
- * task in the cpuset, rebind any vma mempolicies.
+ * task in the cpuset, rebind any vma mempolicies and if
+ * the cpuset is marked 'memory_migrate', migrate the tasks
+ * pages to the new memory.
*
* Call with manage_sem held. May take callback_sem during call.
* Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
static int update_nodemask(struct cpuset *cs, char *buf)
{
struct cpuset trialcs;
+ nodemask_t oldmem;
struct task_struct *g, *p;
struct mm_struct **mmarray;
int i, n, ntasks;
+ int migrate;
int fudge;
int retval;
if (retval < 0)
goto done;
nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map);
+ oldmem = cs->mems_allowed;
+ if (nodes_equal(oldmem, trialcs.mems_allowed)) {
+ retval = 0; /* Too easy - nothing to do */
+ goto done;
+ }
if (nodes_empty(trialcs.mems_allowed)) {
retval = -ENOSPC;
goto done;
* cpuset manage_sem, we know that no other rebind effort will
* be contending for the global variable cpuset_being_rebound.
* It's ok if we rebind the same mm twice; mpol_rebind_mm()
- * is idempotent.
+ * is idempotent. Also migrate pages in each mm to new nodes.
*/
+ migrate = is_memory_migrate(cs);
for (i = 0; i < n; i++) {
struct mm_struct *mm = mmarray[i];
mpol_rebind_mm(mm, &cs->mems_allowed);
+ if (migrate) {
+ do_migrate_pages(mm, &oldmem, &cs->mems_allowed,
+ MPOL_MF_MOVE_ALL);
+ }
mmput(mm);
}