[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] xen/domain: Introduce domain_teardown()
commit 98d4d6d8a6329ea3a8dcf8aab65acdd70c6397fc Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Mon Sep 28 18:14:53 2020 +0100 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Tue Dec 22 14:31:34 2020 +0000 xen/domain: Introduce domain_teardown() There is no common equivelent of domain_reliquish_resources(), which has caused various pieces of common cleanup to live in inappropriate places. Perhaps most obviously, evtchn_destroy() is called for every continuation of domain_reliquish_resources(), which can easily be thousands of times. Create domain_teardown() to be a new top level facility, and call it from the appropriate positions in domain_kill() and domain_create()'s error path. The intention is for this to supersede domain_reliquish_resources() in due course. No change in behaviour yet. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/common/domain.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ xen/include/xen/sched.h | 8 +++++++ 2 files changed, 68 insertions(+) diff --git a/xen/common/domain.c b/xen/common/domain.c index 54241b0064..d151be3f36 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -272,6 +272,59 @@ static int __init parse_extra_guest_irqs(const char *s) } custom_param("extra_guest_irqs", parse_extra_guest_irqs); +/* + * Release resources held by a domain. There may or may not be live + * references to the domain, and it may or may not be fully constructed. + * + * d->is_dying differing between DOMDYING_dying and DOMDYING_dead can be used + * to determine if live references to the domain exist, and also whether + * continuations are permitted. + * + * If d->is_dying is DOMDYING_dead, this must not return non-zero. + */ +static int domain_teardown(struct domain *d) +{ + BUG_ON(!d->is_dying); + + /* + * This hypercall can take minutes of wallclock time to complete. This + * logic implements a co-routine, stashing state in struct domain across + * hypercall continuation boundaries. + */ + switch ( d->teardown.val ) + { + /* + * Record the current progress. Subsequent hypercall continuations + * will logically restart work from this point. + * + * PROGRESS() markers must not be in the middle of loops. The loop + * variable isn't preserved across a continuation. + * + * To avoid redundant work, there should be a marker before each + * function which may return -ERESTART. + */ +#define PROGRESS(x) \ + d->teardown.val = PROG_ ## x; \ + /* Fallthrough */ \ + case PROG_ ## x + + enum { + PROG_done = 1, + }; + + case 0: + PROGRESS(done): + break; + +#undef PROGRESS + + default: + BUG(); + } + + return 0; +} + /* * Destroy a domain once all references to it have been dropped. Used either * from the RCU path, or from the domain_create() error path before the domain @@ -552,6 +605,10 @@ struct domain *domain_create(domid_t domid, if ( init_status & INIT_watchdog ) watchdog_domain_destroy(d); + /* Must not hit a continuation in this context. */ + if ( domain_teardown(d) ) + ASSERT_UNREACHABLE(); + _domain_destroy(d); return ERR_PTR(err); @@ -732,6 +789,9 @@ int domain_kill(struct domain *d) domain_set_outstanding_pages(d, 0); /* fallthrough */ case DOMDYING_dying: + rc = domain_teardown(d); + if ( rc ) + break; rc = evtchn_destroy(d); if ( rc ) break; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 76af29e932..3e46384a3c 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -525,6 +525,14 @@ struct domain /* Argo interdomain communication support */ struct argo_domain *argo; #endif + + /* + * Continuation information for domain_teardown(). All fields entirely + * private. + */ + struct { + unsigned int val; + } teardown; }; static inline struct page_list_head *page_to_list( -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |