Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 105912
b: refs/heads/master
c: 0b2f630
h: refs/heads/master
v: v3
  • Loading branch information
Miao Xie authored and Linus Torvalds committed Jul 25, 2008
1 parent 84594ab commit 7c0ec92
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 73 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 628f42355389cfb596ca3a5a5f64fb9054a2a06a
refs/heads/master: 0b2f630a28d53b5a2082a5275bc3334b10373508
181 changes: 109 additions & 72 deletions trunk/kernel/cpuset.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,37 @@ static void cpuset_change_cpumask(struct task_struct *tsk,
set_cpus_allowed_ptr(tsk, &((cgroup_cs(scan->cg))->cpus_allowed));
}

/**
* update_tasks_cpumask - Update the cpumasks of tasks in the cpuset.
* @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
*
* Called with cgroup_mutex held
*
* The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
* calling callback functions for each.
*
* Return 0 if successful, -errno if not.
*/
static int update_tasks_cpumask(struct cpuset *cs)
{
struct cgroup_scanner scan;
struct ptr_heap heap;
int retval;

retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, &started_after);
if (retval)
return retval;

scan.cg = cs->css.cgroup;
scan.test_task = cpuset_test_cpumask;
scan.process_task = cpuset_change_cpumask;
scan.heap = &heap;
retval = cgroup_scan_tasks(&scan);

heap_free(&heap);
return retval;
}

/**
* update_cpumask - update the cpus_allowed mask of a cpuset and all tasks in it
* @cs: the cpuset to consider
Expand All @@ -771,8 +802,6 @@ static void cpuset_change_cpumask(struct task_struct *tsk,
static int update_cpumask(struct cpuset *cs, const char *buf)
{
struct cpuset trialcs;
struct cgroup_scanner scan;
struct ptr_heap heap;
int retval;
int is_load_balanced;

Expand Down Expand Up @@ -806,10 +835,6 @@ static int update_cpumask(struct cpuset *cs, const char *buf)
if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed))
return 0;

retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, &started_after);
if (retval)
return retval;

is_load_balanced = is_sched_load_balance(&trialcs);

mutex_lock(&callback_mutex);
Expand All @@ -820,12 +845,9 @@ static int update_cpumask(struct cpuset *cs, const char *buf)
* Scan tasks in the cpuset, and update the cpumasks of any
* that need an update.
*/
scan.cg = cs->css.cgroup;
scan.test_task = cpuset_test_cpumask;
scan.process_task = cpuset_change_cpumask;
scan.heap = &heap;
cgroup_scan_tasks(&scan);
heap_free(&heap);
retval = update_tasks_cpumask(cs);
if (retval < 0)
return retval;

if (is_load_balanced)
rebuild_sched_domains();
Expand Down Expand Up @@ -881,73 +903,25 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
mutex_unlock(&callback_mutex);
}

/*
* 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 and if
* the cpuset is marked 'memory_migrate', migrate the tasks
* pages to the new memory.
*
* Call with cgroup_mutex held. May take callback_mutex during call.
* Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
* lock each such tasks mm->mmap_sem, scan its vma's and rebind
* their mempolicies to the cpusets new mems_allowed.
*/

static void *cpuset_being_rebound;

static int update_nodemask(struct cpuset *cs, const char *buf)
/**
* update_tasks_nodemask - Update the nodemasks of tasks in the cpuset.
* @cs: the cpuset in which each task's mems_allowed mask needs to be changed
* @oldmem: old mems_allowed of cpuset cs
*
* Called with cgroup_mutex held
* Return 0 if successful, -errno if not.
*/
static int update_tasks_nodemask(struct cpuset *cs, const nodemask_t *oldmem)
{
struct cpuset trialcs;
nodemask_t oldmem;
struct task_struct *p;
struct mm_struct **mmarray;
int i, n, ntasks;
int migrate;
int fudge;
int retval;
struct cgroup_iter it;

/*
* top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
* it's read-only
*/
if (cs == &top_cpuset)
return -EACCES;

trialcs = *cs;

/*
* An empty mems_allowed is ok iff there are no tasks in the cpuset.
* Since nodelist_parse() fails on an empty mask, we special case
* that parsing. The validate_change() call ensures that cpusets
* with tasks have memory.
*/
if (!*buf) {
nodes_clear(trialcs.mems_allowed);
} else {
retval = nodelist_parse(buf, trialcs.mems_allowed);
if (retval < 0)
goto done;

if (!nodes_subset(trialcs.mems_allowed,
node_states[N_HIGH_MEMORY]))
return -EINVAL;
}
oldmem = cs->mems_allowed;
if (nodes_equal(oldmem, trialcs.mems_allowed)) {
retval = 0; /* Too easy - nothing to do */
goto done;
}
retval = validate_change(cs, &trialcs);
if (retval < 0)
goto done;

mutex_lock(&callback_mutex);
cs->mems_allowed = trialcs.mems_allowed;
cs->mems_generation = cpuset_mems_generation++;
mutex_unlock(&callback_mutex);
int retval;

cpuset_being_rebound = cs; /* causes mpol_dup() rebind */

Expand Down Expand Up @@ -1014,7 +988,7 @@ static int update_nodemask(struct cpuset *cs, const char *buf)

mpol_rebind_mm(mm, &cs->mems_allowed);
if (migrate)
cpuset_migrate_mm(mm, &oldmem, &cs->mems_allowed);
cpuset_migrate_mm(mm, oldmem, &cs->mems_allowed);
mmput(mm);
}

Expand All @@ -1026,6 +1000,70 @@ static int update_nodemask(struct cpuset *cs, const char *buf)
return retval;
}

/*
* 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 and if
* the cpuset is marked 'memory_migrate', migrate the tasks
* pages to the new memory.
*
* Call with cgroup_mutex held. May take callback_mutex during call.
* Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
* lock each such tasks mm->mmap_sem, scan its vma's and rebind
* their mempolicies to the cpusets new mems_allowed.
*/
static int update_nodemask(struct cpuset *cs, const char *buf)
{
struct cpuset trialcs;
nodemask_t oldmem;
int retval;

/*
* top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
* it's read-only
*/
if (cs == &top_cpuset)
return -EACCES;

trialcs = *cs;

/*
* An empty mems_allowed is ok iff there are no tasks in the cpuset.
* Since nodelist_parse() fails on an empty mask, we special case
* that parsing. The validate_change() call ensures that cpusets
* with tasks have memory.
*/
if (!*buf) {
nodes_clear(trialcs.mems_allowed);
} else {
retval = nodelist_parse(buf, trialcs.mems_allowed);
if (retval < 0)
goto done;

if (!nodes_subset(trialcs.mems_allowed,
node_states[N_HIGH_MEMORY]))
return -EINVAL;
}
oldmem = cs->mems_allowed;
if (nodes_equal(oldmem, trialcs.mems_allowed)) {
retval = 0; /* Too easy - nothing to do */
goto done;
}
retval = validate_change(cs, &trialcs);
if (retval < 0)
goto done;

mutex_lock(&callback_mutex);
cs->mems_allowed = trialcs.mems_allowed;
cs->mems_generation = cpuset_mems_generation++;
mutex_unlock(&callback_mutex);

retval = update_tasks_nodemask(cs, &oldmem);
done:
return retval;
}

int current_cpuset_is_being_rebound(void)
{
return task_cs(current) == cpuset_being_rebound;
Expand Down Expand Up @@ -1935,7 +1973,6 @@ void __init cpuset_init_smp(void)
}

/**
* cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset.
* @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
* @pmask: pointer to cpumask_t variable to receive cpus_allowed set.
Expand Down

0 comments on commit 7c0ec92

Please sign in to comment.