[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 3/3] xen/evtchn: Clean up teardown handling
First of all, rename the evtchn APIs: * evtchn_destroy => evtchn_teardown * evtchn_destroy_final => evtchn_destroy Move both calls into appropriate positions in domain_teardown() and _domain_destroy(), which avoids having different cleanup logic depending on the the cause of the cleanup. In particular, this avoids evtchn_teardown() (previously named evtchn_destroy()) being called redundantly thousands of times on a typical XEN_DOMCTL_destroydomain hypercall. No net change in behaviour. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Wei Liu <wl@xxxxxxx> CC: Stefano Stabellini <sstabellini@xxxxxxxxxx> CC: Julien Grall <julien@xxxxxxx> CC: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx> RFC. While testing this, I observed this, after faking up an -ENOMEM in dom0's construction: (XEN) [2020-12-21 16:31:20] NX (Execute Disable) protection active (XEN) [2020-12-21 16:33:04] (XEN) [2020-12-21 16:33:04] **************************************** (XEN) [2020-12-21 16:33:04] Panic on CPU 0: (XEN) [2020-12-21 16:33:04] Error creating domain 0 (XEN) [2020-12-21 16:33:04] **************************************** XSA-344 appears to have added nearly 2 minutes of wallclock time into the domain_create() error path, which isn't ok. Considering that event channels haven't even been initialised in this particular scenario, it ought to take ~0 time. Even if event channels have been initalised, none can be active as the domain isn't visible to the system. --- xen/common/domain.c | 17 ++++++++--------- xen/common/event_channel.c | 8 ++++---- xen/include/xen/sched.h | 4 ++-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index ef1987335b..701747b9d9 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -284,6 +284,8 @@ custom_param("extra_guest_irqs", parse_extra_guest_irqs); */ static int domain_teardown(struct domain *d) { + int rc; + BUG_ON(!d->is_dying); /* @@ -313,6 +315,10 @@ static int domain_teardown(struct domain *d) }; case 0: + rc = evtchn_teardown(d); + if ( rc ) + return rc; + PROGRESS(done): break; @@ -335,6 +341,8 @@ static void _domain_destroy(struct domain *d) BUG_ON(!d->is_dying); BUG_ON(atomic_read(&d->refcnt) != DOMAIN_DESTROYED); + evtchn_destroy(d); + xfree(d->pbuf); argo_destroy(d); @@ -598,11 +606,7 @@ struct domain *domain_create(domid_t domid, if ( init_status & INIT_gnttab ) grant_table_destroy(d); if ( init_status & INIT_evtchn ) - { - evtchn_destroy(d); - evtchn_destroy_final(d); radix_tree_destroy(&d->pirq_tree, free_pirq_struct); - } if ( init_status & INIT_watchdog ) watchdog_domain_destroy(d); @@ -792,9 +796,6 @@ int domain_kill(struct domain *d) rc = domain_teardown(d); if ( rc ) break; - rc = evtchn_destroy(d); - if ( rc ) - break; rc = domain_relinquish_resources(d); if ( rc != 0 ) break; @@ -987,8 +988,6 @@ static void complete_domain_destroy(struct rcu_head *head) if ( d->target != NULL ) put_domain(d->target); - evtchn_destroy_final(d); - radix_tree_destroy(&d->pirq_tree, free_pirq_struct); xfree(d->vcpu); diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 4a48094356..c1af54eed5 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -1401,7 +1401,7 @@ void free_xen_event_channel(struct domain *d, int port) { /* * Make sure ->is_dying is read /after/ ->valid_evtchns, pairing - * with the spin_barrier() and BUG_ON() in evtchn_destroy(). + * with the spin_barrier() and BUG_ON() in evtchn_teardown(). */ smp_rmb(); BUG_ON(!d->is_dying); @@ -1421,7 +1421,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport) { /* * Make sure ->is_dying is read /after/ ->valid_evtchns, pairing - * with the spin_barrier() and BUG_ON() in evtchn_destroy(). + * with the spin_barrier() and BUG_ON() in evtchn_teardown(). */ smp_rmb(); ASSERT(ld->is_dying); @@ -1499,7 +1499,7 @@ int evtchn_init(struct domain *d, unsigned int max_port) return 0; } -int evtchn_destroy(struct domain *d) +int evtchn_teardown(struct domain *d) { unsigned int i; @@ -1534,7 +1534,7 @@ int evtchn_destroy(struct domain *d) } -void evtchn_destroy_final(struct domain *d) +void evtchn_destroy(struct domain *d) { unsigned int i, j; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 3f35c537b8..bb22eeca38 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -142,8 +142,8 @@ struct evtchn } __attribute__((aligned(64))); int evtchn_init(struct domain *d, unsigned int max_port); -int evtchn_destroy(struct domain *d); /* from domain_kill */ -void evtchn_destroy_final(struct domain *d); /* from complete_domain_destroy */ +int evtchn_teardown(struct domain *d); +void evtchn_destroy(struct domain *d); struct waitqueue_vcpu; -- 2.11.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |