aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/cpupool.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2011-02-06 16:07:27 +0000
committerKeir Fraser <keir@xen.org>2011-02-06 16:07:27 +0000
commitb9a9873c2e97a765c5136b223bf8921f3bd40c66 (patch)
tree72c3bfe424d7204e11ad88e040d0d4fed7c87362 /xen/common/cpupool.c
parenta69a0358f60de0ce4d00645d1599f7f7284a32c2 (diff)
downloadxen-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.c21
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;
}