From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: "Juergen Gross" <jgross@suse.com>,
"Andrew Cooper" <andrew.cooper3@citrix.com>,
"Anthony PERARD" <anthony.perard@vates.tech>,
"Michal Orzel" <michal.orzel@amd.com>,
"Jan Beulich" <jbeulich@suse.com>,
"Julien Grall" <julien@xen.org>,
"Roger Pau Monné" <roger.pau@citrix.com>,
"Stefano Stabellini" <sstabellini@kernel.org>
Subject: [PATCH v7 4/7] xen: add bitmap to indicate per-domain state changes
Date: Thu, 9 Jan 2025 11:59:32 +0100 [thread overview]
Message-ID: <20250109105935.23585-5-jgross@suse.com> (raw)
In-Reply-To: <20250109105935.23585-1-jgross@suse.com>
Add a bitmap with one bit per possible domid indicating the respective
domain has changed its state (created, deleted, dying, crashed,
shutdown).
Registering the VIRQ_DOM_EXC event will result in setting the bits for
all existing domains and resetting all other bits.
As the usage of this bitmap is tightly coupled with the VIRQ_DOM_EXC
event, it is meant to be used only by a single consumer in the system,
just like the VIRQ_DOM_EXC event.
Resetting a bit will be done in a future patch.
This information is needed for Xenstore to keep track of all domains.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- use DOMID_FIRST_RESERVED instead of DOMID_MASK + 1 (Jan Beulich)
- use const (Jan Beulich)
- move call of domain_reset_states() into evtchn_bind_virq() (Jan Beulich)
- dynamically allocate dom_state_changed bitmap (Jan Beulich)
V3:
- use xvzalloc_array() (Jan Beulich)
- don't rename existing label (Jan Beulich)
V4:
- add __read_mostly (Jan Beulich)
- use __set_bit() (Jan Beulich)
- fix error handling in evtchn_bind_virq() (Jan Beulich)
V5:
- domain_init_states() may be called only if evtchn_bind_virq() has been
called validly (Jan Beulich)
V6:
- guard dom_state_changed bitmap with d->event_lock (Jan Beulich)
V7:
- still use __set_bit() at one place (Jan Beulich)
- use rw_is_write_locked_by_me() (Jan Beulich)
---
xen/common/domain.c | 51 ++++++++++++++++++++++++++++++++++++++
xen/common/event_channel.c | 31 +++++++++++++++++++++++
xen/include/xen/event.h | 4 +++
xen/include/xen/sched.h | 3 +++
4 files changed, 89 insertions(+)
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 0c4cc77111..1c1d6da885 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -35,6 +35,7 @@
#include <xen/irq.h>
#include <xen/argo.h>
#include <xen/llc-coloring.h>
+#include <xen/xvmalloc.h>
#include <asm/p2m.h>
#include <asm/processor.h>
#include <public/sched.h>
@@ -139,6 +140,51 @@ bool __read_mostly vmtrace_available;
bool __read_mostly vpmu_is_available;
+static unsigned long *__read_mostly dom_state_changed;
+
+int domain_init_states(void)
+{
+ const struct domain *d;
+
+ ASSERT(!dom_state_changed);
+ ASSERT(rw_is_write_locked_by_me(¤t->domain->event_lock));
+
+ dom_state_changed = xvzalloc_array(unsigned long,
+ BITS_TO_LONGS(DOMID_FIRST_RESERVED));
+ if ( !dom_state_changed )
+ return -ENOMEM;
+
+ rcu_read_lock(&domlist_read_lock);
+
+ for_each_domain ( d )
+ __set_bit(d->domain_id, dom_state_changed);
+
+ rcu_read_unlock(&domlist_read_lock);
+
+ return 0;
+}
+
+void domain_deinit_states(const struct domain *d)
+{
+ ASSERT(rw_is_write_locked_by_me(&d->event_lock));
+
+ XVFREE(dom_state_changed);
+}
+
+static void domain_changed_state(const struct domain *d)
+{
+ struct domain *hdl;
+
+ hdl = lock_dom_exc_handler();
+ if ( unlikely(!hdl) )
+ return;
+
+ if ( dom_state_changed )
+ set_bit(d->domain_id, dom_state_changed);
+
+ unlock_dom_exc_handler(hdl);
+}
+
static void __domain_finalise_shutdown(struct domain *d)
{
struct vcpu *v;
@@ -153,6 +199,7 @@ static void __domain_finalise_shutdown(struct domain *d)
return;
d->is_shut_down = 1;
+ domain_changed_state(d);
if ( (d->shutdown_code == SHUTDOWN_suspend) && d->suspend_evtchn )
evtchn_send(d, d->suspend_evtchn);
else
@@ -840,6 +887,7 @@ struct domain *domain_create(domid_t domid,
*/
domlist_insert(d);
+ domain_changed_state(d);
memcpy(d->handle, config->handle, sizeof(d->handle));
return d;
@@ -1105,6 +1153,7 @@ int domain_kill(struct domain *d)
/* Mem event cleanup has to go here because the rings
* have to be put before we call put_domain. */
vm_event_cleanup(d);
+ domain_changed_state(d);
put_domain(d);
send_global_virq(VIRQ_DOM_EXC);
/* fallthrough */
@@ -1294,6 +1343,8 @@ static void cf_check complete_domain_destroy(struct rcu_head *head)
xfree(d->vcpu);
+ domain_changed_state(d);
+
_domain_destroy(d);
send_global_virq(VIRQ_DOM_EXC);
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 4dba59efa2..4ee6b6b4ce 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -509,10 +509,18 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
goto out;
}
+ if ( virq == VIRQ_DOM_EXC )
+ {
+ rc = domain_init_states();
+ if ( rc )
+ goto out;
+ }
+
port = rc = evtchn_get_port(d, port);
if ( rc < 0 )
{
gdprintk(XENLOG_WARNING, "EVTCHNOP failure: error %d\n", rc);
+ domain_deinit_states(d);
goto out;
}
@@ -745,6 +753,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
struct vcpu *v;
unsigned long flags;
+ if ( chn1->u.virq == VIRQ_DOM_EXC )
+ domain_deinit_states(d1);
+
v = d1->vcpu[virq_is_global(chn1->u.virq) ? 0 : chn1->notify_vcpu_id];
write_lock_irqsave(&v->virq_lock, flags);
@@ -1075,6 +1086,26 @@ static void clear_global_virq_handlers(struct domain *d)
}
}
+struct domain *lock_dom_exc_handler(void)
+{
+ struct domain *d;
+
+ d = get_global_virq_handler(VIRQ_DOM_EXC);
+ if ( unlikely(!get_domain(d)) )
+ return NULL;
+
+ read_lock(&d->event_lock);
+
+ return d;
+}
+
+void unlock_dom_exc_handler(struct domain *d)
+{
+ read_unlock(&d->event_lock);
+
+ put_domain(d);
+}
+
int evtchn_status(evtchn_status_t *status)
{
struct domain *d;
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 48b79f3d62..5c0ba90c9f 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -100,6 +100,10 @@ bool evtchn_virq_enabled(const struct vcpu *v, unsigned int virq);
/* Notify remote end of a Xen-attached event channel.*/
void notify_via_xen_event_channel(struct domain *ld, int lport);
+/* Lock/unlock of VIRQ_DOM_EXC associated data (read_lock(d->event_lock)). */
+struct domain *lock_dom_exc_handler(void);
+void unlock_dom_exc_handler(struct domain *d);
+
/*
* Internal event channel object storage.
*
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 037c83fda2..9d9b89ec27 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -805,6 +805,9 @@ void domain_resume(struct domain *d);
int domain_soft_reset(struct domain *d, bool resuming);
+int domain_init_states(void);
+void domain_deinit_states(const struct domain *d);
+
int vcpu_start_shutdown_deferral(struct vcpu *v);
void vcpu_end_shutdown_deferral(struct vcpu *v);
--
2.43.0
next prev parent reply other threads:[~2025-01-09 11:00 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-09 10:59 [PATCH v7 0/7] remove libxenctrl usage from xenstored Juergen Gross
2025-01-09 10:59 ` [PATCH v7 1/7] xen/events: fix race with set_global_virq_handler() Juergen Gross
2025-01-09 15:46 ` Jan Beulich
2025-01-09 10:59 ` [PATCH v7 2/7] xen/events: don't allow binding a global virq from any domain Juergen Gross
2025-01-09 10:59 ` [PATCH v7 3/7] xen/events: allow setting of global virq handler only for unbound virqs Juergen Gross
2025-01-09 10:59 ` Juergen Gross [this message]
2025-01-09 15:49 ` [PATCH v7 4/7] xen: add bitmap to indicate per-domain state changes Jan Beulich
2025-01-09 10:59 ` [PATCH v7 5/7] xen: add new domctl get_changed_domain Juergen Gross
2025-01-09 15:50 ` Jan Beulich
2025-01-09 10:59 ` [PATCH v7 6/7] tools/libs: add a new libxenmanage library Juergen Gross
2025-01-09 10:59 ` [PATCH v7 7/7] tools/xenstored: use new stable interface instead of libxenctrl Juergen Gross
2025-01-16 13:44 ` Anthony PERARD
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250109105935.23585-5-jgross@suse.com \
--to=jgross@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=michal.orzel@amd.com \
--cc=roger.pau@citrix.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.