aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/schedule.c
diff options
context:
space:
mode:
authorJuergen Gross <juergen.gross@ts.fujitsu.com>2013-02-28 14:56:45 +0000
committerKeir Fraser <keir@xen.org>2013-02-28 14:56:45 +0000
commit482300def7d08e773ccd2a0d978bcb9469fdd810 (patch)
tree1b33ab0376aa64436bfb2e748b371ba1a3830513 /xen/common/schedule.c
parent7dd3b06ff031c9a8c727df16c5def2afb382101c (diff)
downloadxen-482300def7d08e773ccd2a0d978bcb9469fdd810.tar.gz
xen-482300def7d08e773ccd2a0d978bcb9469fdd810.tar.bz2
xen-482300def7d08e773ccd2a0d978bcb9469fdd810.zip
Avoid stale pointer when moving domain to another cpupool
When a domain is moved to another cpupool the scheduler private data pointers in vcpu and domain structures must never point to an already freed memory area. While at it, simplify sched_init_vcpu() by using DOM2OP instead VCPU2OP. Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
Diffstat (limited to 'xen/common/schedule.c')
-rw-r--r--xen/common/schedule.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 9c58b12074..1fc9b7df6c 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -220,7 +220,7 @@ int sched_init_vcpu(struct vcpu *v, unsigned int processor)
if ( v->sched_priv == NULL )
return 1;
- SCHED_OP(VCPU2OP(v), insert_vcpu, v);
+ SCHED_OP(DOM2OP(d), insert_vcpu, v);
return 0;
}
@@ -231,6 +231,9 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
unsigned int new_p;
void **vcpu_priv;
void *domdata;
+ void *vcpudata;
+ struct scheduler *old_ops;
+ void *old_domdata;
domdata = SCHED_OP(c->sched, alloc_domdata, d);
if ( domdata == NULL )
@@ -261,21 +264,22 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
domain_pause(d);
+ old_ops = DOM2OP(d);
+ old_domdata = d->sched_priv;
+
for_each_vcpu ( d, v )
{
- SCHED_OP(VCPU2OP(v), remove_vcpu, v);
- SCHED_OP(VCPU2OP(v), free_vdata, v->sched_priv);
- v->sched_priv = NULL;
+ SCHED_OP(old_ops, remove_vcpu, v);
}
- SCHED_OP(DOM2OP(d), free_domdata, d->sched_priv);
-
d->cpupool = c;
d->sched_priv = domdata;
new_p = cpumask_first(c->cpu_valid);
for_each_vcpu ( d, v )
{
+ vcpudata = v->sched_priv;
+
migrate_timer(&v->periodic_timer, new_p);
migrate_timer(&v->singleshot_timer, new_p);
migrate_timer(&v->poll_timer, new_p);
@@ -288,12 +292,16 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
new_p = cpumask_cycle(new_p, c->cpu_valid);
SCHED_OP(c->sched, insert_vcpu, v);
+
+ SCHED_OP(old_ops, free_vdata, vcpudata);
}
domain_update_node_affinity(d);
domain_unpause(d);
+ SCHED_OP(old_ops, free_domdata, old_domdata);
+
xfree(vcpu_priv);
return 0;