From: Paul Durrant <paul.durrant@citrix.com>
To: <qemu-devel@nongnu.org>, <xen-devel@lists.xenproject.org>
Cc: Anthony Perard <anthony.perard@citrix.com>,
Paul Durrant <paul.durrant@citrix.com>,
Stefano Stabellini <sstabellini@kernel.org>
Subject: [Qemu-devel] [PATCH 2/3] xen: introduce separate XenWatchList for XenDevice objects
Date: Wed, 11 Sep 2019 15:36:17 +0100 [thread overview]
Message-ID: <20190911143618.23477-3-paul.durrant@citrix.com> (raw)
In-Reply-To: <20190911143618.23477-1-paul.durrant@citrix.com>
This patch uses the XenWatchList abstraction to add a separate watch list
for each device. This is more scalable than walking a single notifier
list for all watches and is also necessary to implement a bug-fix in a
subsequent patch.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
hw/xen/trace-events | 2 ++
hw/xen/xen-bus.c | 72 ++++++++++++++++++++++++++++++++--------
include/hw/xen/xen-bus.h | 2 ++
3 files changed, 62 insertions(+), 14 deletions(-)
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index ac8d9c20d2..80ce3dafad 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -29,6 +29,8 @@ xen_device_backend_changed(const char *type, char *name) "type: %s name: %s"
xen_device_frontend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
xen_device_frontend_changed(const char *type, char *name) "type: %s name: %s"
xen_device_unplug(const char *type, char *name) "type: %s name: %s"
+xen_device_add_watch(const char *type, char *name, const char *node, const char *key) "type: %s name: %s node: %s key: %s"
+xen_device_remove_watch(const char *type, char *name, const char *node, const char *key) "type: %s name: %s node: %s key: %s"
# xen-bus-helper.c
xs_node_create(const char *node) "%s"
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 28efaccff2..810a4e2df3 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -235,11 +235,11 @@ static void watch_list_remove(XenWatchList *watch_list, XenWatch *watch,
static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
const char *key, XenWatchHandler handler,
- void *opaque, Error **errp)
+ Error **errp)
{
trace_xen_bus_add_watch(node, key);
- return watch_list_add(xenbus->watch_list, node, key, handler, opaque,
+ return watch_list_add(xenbus->watch_list, node, key, handler, xenbus,
errp);
}
@@ -433,7 +433,7 @@ static void xen_bus_realize(BusState *bus, Error **errp)
xenbus->backend_watch =
xen_bus_add_watch(xenbus, "", /* domain root node */
- "backend", xen_bus_enumerate, xenbus, &local_err);
+ "backend", xen_bus_enumerate, &local_err);
if (local_err) {
/* This need not be treated as a hard error so don't propagate */
error_reportf_err(local_err,
@@ -621,6 +621,31 @@ static void xen_device_backend_changed(void *opaque)
}
}
+static XenWatch *xen_device_add_watch(XenDevice *xendev, const char *node,
+ const char *key,
+ XenWatchHandler handler,
+ Error **errp)
+{
+ const char *type = object_get_typename(OBJECT(xendev));
+
+ trace_xen_device_add_watch(type, xendev->name, node, key);
+
+ return watch_list_add(xendev->watch_list, node, key, handler, xendev,
+ errp);
+}
+
+static void xen_device_remove_watch(XenDevice *xendev, XenWatch *watch,
+ Error **errp)
+{
+ const char *type = object_get_typename(OBJECT(xendev));
+
+ trace_xen_device_remove_watch(type, xendev->name, watch->node,
+ watch->key);
+
+ watch_list_remove(xendev->watch_list, watch, errp);
+}
+
+
static void xen_device_backend_create(XenDevice *xendev, Error **errp)
{
XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -645,9 +670,9 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp)
}
xendev->backend_state_watch =
- xen_bus_add_watch(xenbus, xendev->backend_path,
- "state", xen_device_backend_changed,
- xendev, &local_err);
+ xen_device_add_watch(xendev, xendev->backend_path,
+ "state", xen_device_backend_changed,
+ &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err,
"failed to watch backend state: ");
@@ -655,9 +680,9 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp)
}
xendev->backend_online_watch =
- xen_bus_add_watch(xenbus, xendev->backend_path,
- "online", xen_device_backend_changed,
- xendev, &local_err);
+ xen_device_add_watch(xendev, xendev->backend_path,
+ "online", xen_device_backend_changed,
+ &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err,
"failed to watch backend online: ");
@@ -671,12 +696,12 @@ static void xen_device_backend_destroy(XenDevice *xendev)
Error *local_err = NULL;
if (xendev->backend_online_watch) {
- xen_bus_remove_watch(xenbus, xendev->backend_online_watch, NULL);
+ xen_device_remove_watch(xendev, xendev->backend_online_watch, NULL);
xendev->backend_online_watch = NULL;
}
if (xendev->backend_state_watch) {
- xen_bus_remove_watch(xenbus, xendev->backend_state_watch, NULL);
+ xen_device_remove_watch(xendev, xendev->backend_state_watch, NULL);
xendev->backend_state_watch = NULL;
}
@@ -812,8 +837,8 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
}
xendev->frontend_state_watch =
- xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
- xen_device_frontend_changed, xendev, &local_err);
+ xen_device_add_watch(xendev, xendev->frontend_path, "state",
+ xen_device_frontend_changed, &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err,
"failed to watch frontend state: ");
@@ -826,7 +851,8 @@ static void xen_device_frontend_destroy(XenDevice *xendev)
Error *local_err = NULL;
if (xendev->frontend_state_watch) {
- xen_bus_remove_watch(xenbus, xendev->frontend_state_watch, NULL);
+ xen_device_remove_watch(xendev, xendev->frontend_state_watch,
+ NULL);
xendev->frontend_state_watch = NULL;
}
@@ -1122,6 +1148,16 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
xendev->xgth = NULL;
}
+ if (xendev->watch_list) {
+ watch_list_destroy(xendev->watch_list);
+ xendev->watch_list = NULL;
+ }
+
+ if (xendev->xsh) {
+ xs_close(xendev->xsh);
+ xendev->xsh = NULL;
+ }
+
g_free(xendev->name);
xendev->name = NULL;
}
@@ -1164,6 +1200,14 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
trace_xen_device_realize(type, xendev->name);
+ xendev->xsh = xs_open(0);
+ if (!xendev->xsh) {
+ error_setg_errno(errp, errno, "failed xs_open");
+ goto unrealize;
+ }
+
+ xendev->watch_list = watch_list_create(xendev->xsh);
+
xendev->xgth = xengnttab_open(NULL, 0);
if (!xendev->xgth) {
error_setg_errno(errp, errno, "failed xengnttab_open");
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 88b84e29bb..0d198148f6 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -22,6 +22,8 @@ typedef struct XenDevice {
DeviceState qdev;
domid_t frontend_id;
char *name;
+ struct xs_handle *xsh;
+ XenWatchList *watch_list;
char *backend_path, *frontend_path;
enum xenbus_state backend_state, frontend_state;
Notifier exit;
--
2.20.1.2.gb21ebb6
next prev parent reply other threads:[~2019-09-11 14:45 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-11 14:36 [Qemu-devel] [PATCH 0/3] xen: fix a potential crash in xen-bus Paul Durrant
2019-09-11 14:36 ` [Qemu-devel] [PATCH 1/3] xen / notify: introduce a new XenWatchList abstraction Paul Durrant
2019-09-12 10:16 ` Anthony PERARD
2019-09-12 11:40 ` Paul Durrant
2019-09-11 14:36 ` Paul Durrant [this message]
2019-09-12 11:27 ` [Qemu-devel] [PATCH 2/3] xen: introduce separate XenWatchList for XenDevice objects Anthony PERARD
2019-09-11 14:36 ` [Qemu-devel] [PATCH 3/3] xen: perform XenDevice clean-up in XenBus watch handler Paul Durrant
2019-09-11 16:15 ` Paul Durrant
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=20190911143618.23477-3-paul.durrant@citrix.com \
--to=paul.durrant@citrix.com \
--cc=anthony.perard@citrix.com \
--cc=qemu-devel@nongnu.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).