# HG changeset patch # User Juergen Gross # Date 1361958197 -3600 # Node ID 04071eb1f2d29de3497f88b860b0584ca25e284e # Parent 1d8c65aee03eaf15ce8ee50deb781b4308302b77 (V2) 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. Changes since V1: - don't use an an own loop for freeing vcpu_data - free old domain data after unpausing the domain - simplify sched_init_vcpu (DOM2OP instead VCPU2OP) Signed-off-by: Juergen Gross diff -r 1d8c65aee03e -r 04071eb1f2d2 xen/common/schedule.c --- a/xen/common/schedule.c Tue Feb 26 10:12:46 2013 +0000 +++ b/xen/common/schedule.c Wed Feb 27 10:43:17 2013 +0100 @@ -220,7 +220,7 @@ int sched_init_vcpu(struct vcpu *v, unsi 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, 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,14 +264,13 @@ int sched_move_domain(struct domain *d, 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; @@ -276,6 +278,8 @@ int sched_move_domain(struct domain *d, 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,11 +292,15 @@ int sched_move_domain(struct domain *d, 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);