diff options
author | Juergen Gross <juergen.gross@ts.fujitsu.com> | 2013-02-28 14:56:45 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2013-02-28 14:56:45 +0000 |
commit | 482300def7d08e773ccd2a0d978bcb9469fdd810 (patch) | |
tree | 1b33ab0376aa64436bfb2e748b371ba1a3830513 /xen/common/schedule.c | |
parent | 7dd3b06ff031c9a8c727df16c5def2afb382101c (diff) | |
download | xen-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.c | 20 |
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; |