Instead of checking each known domain after having received a
VIRQ_DOM_EXC event, use the new xenmanage_poll_changed_domain()
function for directly getting the domid of a domain having changed
its state.
A test doing "xl shutdown" of 1000 guests has shown to reduce the
consumed cpu time of xenstored by 6% with this change applied.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V8:
- new patch
---
tools/xenstored/domain.c | 64 +++++++++++++++++++++++++++++-----------
1 file changed, 46 insertions(+), 18 deletions(-)
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 63df24030e..ad16a00ce3 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -621,30 +621,24 @@ static int destroy_domain(void *_domain)
return 0;
}
-static int check_domain(const void *k, void *v, void *arg)
+static int do_check_domain(struct domain *domain, bool *notify,
+ unsigned int state, uint64_t unique_id)
{
- unsigned int state;
struct connection *conn;
- int dom_invalid;
- struct domain *domain = v;
- bool *notify = arg;
- uint64_t unique_id;
- dom_invalid = xenmanage_get_domain_info(xm_handle, domain->domid,
- &state, &unique_id);
- if (!dom_invalid) {
+ if (unique_id) {
if (!domain->unique_id)
domain->unique_id = unique_id;
else if (domain->unique_id != unique_id)
- dom_invalid = 1;
+ unique_id = 0;
}
if (!domain->introduced) {
- if (dom_invalid)
+ if (!unique_id)
talloc_free(domain);
return 0;
}
- if (!dom_invalid) {
+ if (unique_id) {
if ((state & XENMANAGE_GETDOMSTATE_STATE_SHUTDOWN)
&& !domain->shutdown) {
domain->shutdown = true;
@@ -667,6 +661,21 @@ static int check_domain(const void *k, void *v, void *arg)
return 0;
}
+static int check_domain(const void *k, void *v, void *arg)
+{
+ struct domain *domain = v;
+ unsigned int state;
+ uint64_t unique_id;
+
+ if (xenmanage_get_domain_info(xm_handle, domain->domid, &state,
+ &unique_id)) {
+ unique_id = 0;
+ state = 0;
+ }
+
+ return do_check_domain(domain, arg, state, unique_id);
+}
+
void check_domains(void)
{
bool notify = false;
@@ -678,6 +687,30 @@ void check_domains(void)
fire_special_watches("@releaseDomain");
}
+static struct domain *find_domain_struct(unsigned int domid)
+{
+ return hashtable_search(domhash, &domid);
+}
+
+static void do_check_domains(void)
+{
+ unsigned int domid;
+ unsigned int state;
+ uint64_t unique_id;
+ struct domain *domain;
+ bool notify = false;
+
+ while (!xenmanage_poll_changed_domain(xm_handle, &domid, &state,
+ &unique_id)) {
+ domain = find_domain_struct(domid);
+ if (domain)
+ do_check_domain(domain, ¬ify, state, unique_id);
+ }
+
+ if (notify)
+ fire_special_watches("@releaseDomain");
+}
+
/* We scan all domains rather than use the information given here. */
void handle_event(void)
{
@@ -687,7 +720,7 @@ void handle_event(void)
barf_perror("Failed to read from event fd");
if (port == virq_port)
- check_domains();
+ do_check_domains();
if (xenevtchn_unmask(xce_handle, port) == -1)
barf_perror("Failed to write to event fd");
@@ -698,11 +731,6 @@ static char *talloc_domain_path(const void *context, unsigned int domid)
return talloc_asprintf(context, "/local/domain/%u", domid);
}
-static struct domain *find_domain_struct(unsigned int domid)
-{
- return hashtable_search(domhash, &domid);
-}
-
int domain_get_quota(const void *ctx, struct connection *conn,
unsigned int domid)
{
--
2.43.0