|
[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 |