diff options
author | Keir Fraser <keir@xen.org> | 2011-02-06 16:07:27 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-02-06 16:07:27 +0000 |
commit | b9a9873c2e97a765c5136b223bf8921f3bd40c66 (patch) | |
tree | 72c3bfe424d7204e11ad88e040d0d4fed7c87362 /xen/common/cpupool.c | |
parent | a69a0358f60de0ce4d00645d1599f7f7284a32c2 (diff) | |
download | xen-b9a9873c2e97a765c5136b223bf8921f3bd40c66.tar.gz xen-b9a9873c2e97a765c5136b223bf8921f3bd40c66.tar.bz2 xen-b9a9873c2e97a765c5136b223bf8921f3bd40c66.zip |
cpupool: Check for memory allocation failure on switching schedulers
When switching schedulers on a physical cpu due to a cpupool operation
check for a potential memory allocation failure and stop the operation
gracefully.
Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
Diffstat (limited to 'xen/common/cpupool.c')
-rw-r--r-- | xen/common/cpupool.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c index 72ae8a2252..7fd3ad849b 100644 --- a/xen/common/cpupool.c +++ b/xen/common/cpupool.c @@ -202,10 +202,20 @@ static int cpupool_destroy(struct cpupool *c) */ static int cpupool_assign_cpu_locked(struct cpupool *c, unsigned int cpu) { + int ret; + struct cpupool *old; + if ( (cpupool_moving_cpu == cpu) && (c != cpupool_cpu_moving) ) return -EBUSY; + old = per_cpu(cpupool, cpu); per_cpu(cpupool, cpu) = c; - schedule_cpu_switch(cpu, c); + ret = schedule_cpu_switch(cpu, c); + if ( ret ) + { + per_cpu(cpupool, cpu) = old; + return ret; + } + cpu_clear(cpu, cpupool_free_cpus); if (cpupool_moving_cpu == cpu) { @@ -230,12 +240,19 @@ static long cpupool_unassign_cpu_helper(void *info) cpu_set(cpu, cpupool_free_cpus); if ( !ret ) { - schedule_cpu_switch(cpu, NULL); + ret = schedule_cpu_switch(cpu, NULL); + if ( ret ) + { + cpu_clear(cpu, cpupool_free_cpus); + goto out; + } per_cpu(cpupool, cpu) = NULL; cpupool_moving_cpu = -1; cpupool_put(cpupool_cpu_moving); cpupool_cpu_moving = NULL; } + +out: spin_unlock(&cpupool_lock); return ret; } |