From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andres Lagar-Cavilla Subject: [PATCH] Mem event: don't leave zombie domains if there are wait-queued vcpus Date: Mon, 12 Mar 2012 11:17:06 -0400 Message-ID: <06a927b592df2899be2b.1331565426@xdev.gridcentric.ca> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: andres@gridcentric.ca, tim@xen.org, olaf@aepfle.de, adin@gridcentric.ca List-Id: xen-devel@lists.xenproject.org xen/arch/x86/mm/mem_event.c | 19 ++++++++++++++++--- 1 files changed, 16 insertions(+), 3 deletions(-) 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 diff -r 9e44b357d988 -r 06a927b592df xen/arch/x86/mm/mem_event.c --- a/xen/arch/x86/mm/mem_event.c +++ b/xen/arch/x86/mm/mem_event.c @@ -490,12 +490,25 @@ int do_mem_event_op(int op, uint32_t dom /* 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,