Re: ZFS + FreeBSD XEN dom0 panic
- Reply: Roger Pau Monné : "Re: ZFS + FreeBSD XEN dom0 panic"
- In reply to: Ze Dupsys : "Re: ZFS + FreeBSD XEN dom0 panic"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Mar 2022 16:35:15 UTC
On Mon, Mar 21, 2022 at 04:07:48PM +0200, Ze Dupsys wrote:
> On 2022.03.21. 13:14, Roger Pau Monné wrote:
> > I think the problem is not likely with the xenstore implementation
> > (ie: xs_talkv) but rather a race with how the FreeBSD kernel detects
> > and manages addition and removal of devices that hang off xenbus.
> >
> > I'm afraid there's too much data below for me to parse it.
>
> Understood. Sounds more tricky than i thought. What could i do to make data
> more useful?
I have another patch for you to try. This will make the system a bit
chatty, let's see what you get.
Thanks, Roger.
---8<---
diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c
index bf54f3a2f28e..f49b6baa90a6 100644
--- a/sys/dev/xen/netback/netback.c
+++ b/sys/dev/xen/netback/netback.c
@@ -99,7 +99,6 @@ static MALLOC_DEFINE(M_XENNETBACK, "xnb", "Xen Net Back Driver Data");
#define XNB_RX_FLIP 0 /* netback driver does not support feature-rx-flip */
#undef XNB_DEBUG
-#define XNB_DEBUG /* hardcode on during development */
#ifdef XNB_DEBUG
#define DPRINTF(fmt, args...) \
diff --git a/sys/xen/xenbus/xenbusb.c b/sys/xen/xenbus/xenbusb.c
index e026f8203ea1..767175d7174f 100644
--- a/sys/xen/xenbus/xenbusb.c
+++ b/sys/xen/xenbus/xenbusb.c
@@ -254,11 +254,15 @@ xenbusb_delete_child(device_t dev, device_t child)
static void
xenbusb_verify_device(device_t dev, device_t child)
{
- if (xs_exists(XST_NIL, xenbus_get_node(child), "") == 0) {
+ struct xenbus_device_ivars *ivars = device_get_ivars(child);
+
+ printf("Check device %s\n", ivars->xd_node);
+ if (xs_exists(XST_NIL, xenbus_get_node(child), "state") == 0) {
/*
* Device tree has been removed from Xenbus.
* Tear down the device.
*/
+ printf("Delete %s\n", ivars->xd_node);
xenbusb_delete_child(dev, child);
}
}
@@ -454,7 +458,11 @@ xenbusb_probe_children(device_t dev)
continue;
}
- error = device_probe_and_attach(kids[i]);
+ ivars = device_get_ivars(kids[i]);
+ printf("Trying to add dev %s\n", ivars->xd_node);
+ error = xenbus_read_driver_state(ivars->xd_node);
+ if (error != XenbusStateClosed)
+ error = device_probe_and_attach(kids[i]);
if (error == ENXIO) {
struct xenbusb_softc *xbs;
@@ -509,9 +517,9 @@ xenbusb_probe_children(device_t dev)
* that can receive otherend state change events,
* hook up a watch for them.
*/
- ivars = device_get_ivars(kids[i]);
xs_register_watch(&ivars->xd_otherend_watch);
xs_register_watch(&ivars->xd_local_watch);
+ printf("Added dev %s\n", ivars->xd_node);
}
free(kids, M_TEMP);
}
@@ -907,6 +915,7 @@ xenbusb_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
case XENBUS_IVAR_STATE:
{
int error;
+ struct xs_transaction xst;
newstate = (enum xenbus_state)value;
sx_xlock(&ivars->xd_lock);
@@ -915,31 +924,37 @@ xenbusb_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
goto out;
}
- error = xs_scanf(XST_NIL, ivars->xd_node, "state",
- NULL, "%d", &currstate);
- if (error)
- goto out;
-
do {
- error = xs_printf(XST_NIL, ivars->xd_node, "state",
- "%d", newstate);
- } while (error == EAGAIN);
- if (error) {
- /*
- * Avoid looping through xenbus_dev_fatal()
- * which calls xenbus_write_ivar to set the
- * state to closing.
- */
- if (newstate != XenbusStateClosing)
- xenbus_dev_fatal(dev, error,
- "writing new state");
- goto out;
- }
+ error = xs_transaction_start(&xst);
+ if (error != 0)
+ goto out;
+
+ error = xs_scanf(xst, ivars->xd_node, "state", NULL,
+ "%d", &currstate);
+ if (error)
+ goto out;
+
+ do {
+ error = xs_printf(xst, ivars->xd_node, "state",
+ "%d", newstate);
+ } while (error == EAGAIN);
+ if (error) {
+ /*
+ * Avoid looping through xenbus_dev_fatal()
+ * which calls xenbus_write_ivar to set the
+ * state to closing.
+ */
+ if (newstate != XenbusStateClosing)
+ xenbus_dev_fatal(dev, error,
+ "writing new state");
+ goto out;
+ }
+ } while (xs_transaction_end(xst, 0));
ivars->xd_state = newstate;
- if ((ivars->xd_flags & XDF_CONNECTING) != 0
- && (newstate == XenbusStateClosed
- || newstate == XenbusStateConnected)) {
+ if ((ivars->xd_flags & XDF_CONNECTING) != 0 &&
+ (newstate == XenbusStateClosed ||
+ newstate == XenbusStateConnected)) {
struct xenbusb_softc *xbs;
ivars->xd_flags &= ~XDF_CONNECTING;
@@ -949,6 +964,8 @@ xenbusb_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
wakeup(&ivars->xd_state);
out:
+ if (error != 0)
+ xs_transaction_end(xst, 1);
sx_xunlock(&ivars->xd_lock);
return (error);
}