diff mbox series

[v8,9/9] tools/xenstored: use xenmanage_poll_changed_domain()

Message ID 20250204113407.16839-10-jgross@suse.com (mailing list archive)
State New
Headers show
Series remove libxenctrl usage from xenstored | expand

Commit Message

Juergen Gross Feb. 4, 2025, 11:34 a.m. UTC
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 mbox series

Patch

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, &notify, 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)
 {