[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2] xen: rework error handling in vcpu_create
In vcpu_create after scheduler data is allocated, if vmtrace_alloc_buffer fails, it will jump to the wrong cleanup label resulting in a memory leak. Move sched_destroy_vcpu and destroy_waitqueue_vcpu to vcpu_teardown. Make vcpu_teardown idempotent: deal with NULL unit. Fix vcpu_runstate_get (called during XEN_SYSCTL_getdomaininfolist post vcpu_teardown) when v->sched_unit is NULL. Fixes: 217dd79ee292 ("xen/domain: Add vmtrace_size domain creation parameter") Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx> --- v1->v2: * move cleanup functions to vcpu_teardown * renamed, was ("xen: fix memory leak on error in vcpu_create") --- xen/common/domain.c | 14 ++++++-------- xen/common/sched/core.c | 5 ++++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index 5241a1629eeb..9c65c2974ea3 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -388,6 +388,8 @@ static int vmtrace_alloc_buffer(struct vcpu *v) static int vcpu_teardown(struct vcpu *v) { vmtrace_free_buffer(v); + sched_destroy_vcpu(v); + destroy_waitqueue_vcpu(v); return 0; } @@ -448,13 +450,13 @@ struct vcpu *vcpu_create(struct domain *d, unsigned int vcpu_id) } if ( sched_init_vcpu(v) != 0 ) - goto fail_wq; + goto fail; if ( vmtrace_alloc_buffer(v) != 0 ) - goto fail_wq; + goto fail; if ( arch_vcpu_create(v) != 0 ) - goto fail_sched; + goto fail; d->vcpu[vcpu_id] = v; if ( vcpu_id != 0 ) @@ -472,11 +474,7 @@ struct vcpu *vcpu_create(struct domain *d, unsigned int vcpu_id) return v; - fail_sched: - sched_destroy_vcpu(v); - fail_wq: - destroy_waitqueue_vcpu(v); - + fail: /* Must not hit a continuation in this context. */ if ( vcpu_teardown(v) ) ASSERT_UNREACHABLE(); diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c index 2ab4313517c3..fb7c99b05360 100644 --- a/xen/common/sched/core.c +++ b/xen/common/sched/core.c @@ -321,7 +321,7 @@ void vcpu_runstate_get(const struct vcpu *v, */ unit = is_idle_vcpu(v) ? get_sched_res(v->processor)->sched_unit_idle : v->sched_unit; - lock = likely(v == current) ? NULL : unit_schedule_lock_irq(unit); + lock = likely(v == current || !unit) ? NULL : unit_schedule_lock_irq(unit); memcpy(runstate, &v->runstate, sizeof(*runstate)); delta = NOW() - runstate->state_entry_time; if ( delta > 0 ) @@ -839,6 +839,9 @@ void sched_destroy_vcpu(struct vcpu *v) { struct sched_unit *unit = v->sched_unit; + if ( !unit ) + return; + kill_timer(&v->periodic_timer); kill_timer(&v->singleshot_timer); kill_timer(&v->poll_timer); base-commit: f6c990ac3cddc2d1965a7ab09324d821b05e4b6c -- 2.50.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |