From c1e3e15c585f2dc4c9d66516acd1cd0c75c7aeee Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Thu, 15 Mar 2012 11:12:44 +0000 Subject: [PATCH] Mem event: don't leave zombie domains if there are wait-queued vcpus Vcpus in wait queues retain a domain reference. Upon domain destruction, we were not taking care of draining the wait queues. Signed-off-by: Andres Lagar-Cavilla Acked-by: Tim Deegan Committed-by: Tim Deegan --- xen/arch/x86/mm/mem_event.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/mm/mem_event.c b/xen/arch/x86/mm/mem_event.c index 814bfe54b6..ff644790be 100644 --- a/xen/arch/x86/mm/mem_event.c +++ b/xen/arch/x86/mm/mem_event.c @@ -489,12 +489,25 @@ int do_mem_event_op(int op, uint32_t domain, void *arg) /* Clean up on domain destruction */ void mem_event_cleanup(struct domain *d) { - if ( d->mem_event->paging.ring_page ) + if ( d->mem_event->paging.ring_page ) { + /* Destroying the wait queue head means waking up all + * queued vcpus. This will drain the list, allowing + * the disable routine to complete. It will also drop + * all domain refs the wait-queued vcpus are holding. + * Finally, because this code path involves previously + * pausing the domain (domain_kill), unpausing the + * vcpus causes no harm. */ + destroy_waitqueue_head(&d->mem_event->paging.wq); (void)mem_event_disable(d, &d->mem_event->paging); - if ( d->mem_event->access.ring_page ) + } + if ( d->mem_event->access.ring_page ) { + destroy_waitqueue_head(&d->mem_event->access.wq); (void)mem_event_disable(d, &d->mem_event->access); - if ( d->mem_event->share.ring_page ) + } + if ( d->mem_event->share.ring_page ) { + destroy_waitqueue_head(&d->mem_event->share.wq); (void)mem_event_disable(d, &d->mem_event->share); + } } int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, -- 2.30.2