svn commit: r225704 - in head/sys: dev/xen/control xen/xenbus
xen/xenstore
Justin T. Gibbs
gibbs at FreeBSD.org
Tue Sep 20 23:44:35 UTC 2011
Author: gibbs
Date: Tue Sep 20 23:44:34 2011
New Revision: 225704
URL: http://svn.freebsd.org/changeset/base/225704
Log:
Properly handle suspend/resume events in the Xen device
framework.
Sponsored by: BQ Internet
sys/xen/xenbus/xenbusb.c:
o In xenbusb_resume(), publish the state transition of the
resuming device into XenbusStateIntiailising so that the
remote peer can see it. Recording the state locally is
not sufficient to trigger a re-connect sequence.
o In xenbusb_resume(), defer new-bus resume processing until
after the remote peer's XenStore address has been updated.
The drivers may need to refer to this information during
resume processing.
sys/xen/xenbus/xenbusb_back.c:
sys/xen/xenbus/xenbusb_front.c:
Register xenbusb_resume() rather than bus_generic_resume()
as the handler for device_resume events.
sys/xen/xenstore/xenstore.c:
o Fix grammer in a comment.
o In xs_suspend(), pass suspend events on to the child
devices (e.g. xenbusb_front/back, that are attached
to the XenStore.
Approved by: re
MFC after: 1 week
Modified:
head/sys/dev/xen/control/control.c
head/sys/xen/xenbus/xenbusb.c
head/sys/xen/xenbus/xenbusb_back.c
head/sys/xen/xenbus/xenbusb_front.c
head/sys/xen/xenstore/xenstore.c
Modified: head/sys/dev/xen/control/control.c
==============================================================================
--- head/sys/dev/xen/control/control.c Tue Sep 20 23:22:58 2011 (r225703)
+++ head/sys/dev/xen/control/control.c Tue Sep 20 23:44:34 2011 (r225704)
@@ -115,6 +115,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/rman.h>
+#include <sys/sched.h>
#include <sys/taskqueue.h>
#include <sys/types.h>
#include <sys/vnode.h>
@@ -201,6 +202,8 @@ xctrl_suspend()
int i, j, k, fpp;
unsigned long max_pfn, start_info_mfn;
+ EVENTHANDLER_INVOKE(power_suspend);
+
#ifdef SMP
struct thread *td;
cpuset_t map;
@@ -221,7 +224,13 @@ xctrl_suspend()
stop_cpus(map);
#endif
+ /*
+ * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
+ * drivers need this.
+ */
+ mtx_lock(&Giant);
if (DEVICE_SUSPEND(root_bus) != 0) {
+ mtx_unlock(&Giant);
printf("xen_suspend: device_suspend failed\n");
#ifdef SMP
if (!CPU_EMPTY(&map))
@@ -229,6 +238,7 @@ xctrl_suspend()
#endif
return;
}
+ mtx_unlock(&Giant);
local_irq_disable();
@@ -283,11 +293,14 @@ xctrl_suspend()
vcpu_prepare(i);
#endif
+
/*
* Only resume xenbus /after/ we've prepared our VCPUs; otherwise
* the VCPU hotplug callback can race with our vcpu_prepare
*/
+ mtx_lock(&Giant);
DEVICE_RESUME(root_bus);
+ mtx_unlock(&Giant);
#ifdef SMP
thread_lock(curthread);
@@ -296,6 +309,7 @@ xctrl_suspend()
if (!CPU_EMPTY(&map))
restart_cpus(map);
#endif
+ EVENTHANDLER_INVOKE(power_resume);
}
static void
@@ -322,39 +336,47 @@ xctrl_suspend()
{
int suspend_cancelled;
+ EVENTHANDLER_INVOKE(power_suspend);
+
+ /*
+ * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
+ * drivers need this.
+ */
+ mtx_lock(&Giant);
if (DEVICE_SUSPEND(root_bus)) {
+ mtx_unlock(&Giant);
printf("xen_suspend: device_suspend failed\n");
return;
}
-
- /*
- * Make sure we don't change cpus or switch to some other
- * thread. for the duration.
- */
- critical_enter();
+ mtx_unlock(&Giant);
/*
* Prevent any races with evtchn_interrupt() handler.
*/
- irq_suspend();
disable_intr();
+ irq_suspend();
suspend_cancelled = HYPERVISOR_suspend(0);
- if (!suspend_cancelled)
+ if (suspend_cancelled)
+ irq_resume();
+ else
xenpci_resume();
/*
* Re-enable interrupts and put the scheduler back to normal.
*/
enable_intr();
- critical_exit();
/*
* FreeBSD really needs to add DEVICE_SUSPEND_CANCEL or
* similar.
*/
+ mtx_lock(&Giant);
if (!suspend_cancelled)
DEVICE_RESUME(root_bus);
+ mtx_unlock(&Giant);
+
+ EVENTHANDLER_INVOKE(power_resume);
}
#endif
Modified: head/sys/xen/xenbus/xenbusb.c
==============================================================================
--- head/sys/xen/xenbus/xenbusb.c Tue Sep 20 23:22:58 2011 (r225703)
+++ head/sys/xen/xenbus/xenbusb.c Tue Sep 20 23:44:34 2011 (r225704)
@@ -773,7 +773,7 @@ xenbusb_resume(device_t dev)
ivars = device_get_ivars(kids[i]);
xs_unregister_watch(&ivars->xd_otherend_watch);
- ivars->xd_state = XenbusStateInitialising;
+ xenbus_set_state(kids[i], XenbusStateInitialising);
/*
* Find the new backend details and
@@ -783,16 +783,16 @@ xenbusb_resume(device_t dev)
if (error)
return (error);
- DEVICE_RESUME(kids[i]);
-
statepath = malloc(ivars->xd_otherend_path_len
+ strlen("/state") + 1, M_XENBUS, M_WAITOK);
sprintf(statepath, "%s/state", ivars->xd_otherend_path);
free(ivars->xd_otherend_watch.node, M_XENBUS);
ivars->xd_otherend_watch.node = statepath;
- xs_register_watch(&ivars->xd_otherend_watch);
+ DEVICE_RESUME(kids[i]);
+
+ xs_register_watch(&ivars->xd_otherend_watch);
#if 0
/*
* Can't do this yet since we are running in
Modified: head/sys/xen/xenbus/xenbusb_back.c
==============================================================================
--- head/sys/xen/xenbus/xenbusb_back.c Tue Sep 20 23:22:58 2011 (r225703)
+++ head/sys/xen/xenbus/xenbusb_back.c Tue Sep 20 23:44:34 2011 (r225704)
@@ -292,7 +292,7 @@ static device_method_t xenbusb_back_meth
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_resume, xenbusb_resume),
/* Bus Interface */
DEVMETHOD(bus_print_child, xenbusb_print_child),
Modified: head/sys/xen/xenbus/xenbusb_front.c
==============================================================================
--- head/sys/xen/xenbus/xenbusb_front.c Tue Sep 20 23:22:58 2011 (r225703)
+++ head/sys/xen/xenbus/xenbusb_front.c Tue Sep 20 23:44:34 2011 (r225704)
@@ -171,7 +171,7 @@ static device_method_t xenbusb_front_met
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_resume, xenbusb_resume),
/* Bus Interface */
DEVMETHOD(bus_print_child, xenbusb_print_child),
Modified: head/sys/xen/xenstore/xenstore.c
==============================================================================
--- head/sys/xen/xenstore/xenstore.c Tue Sep 20 23:22:58 2011 (r225703)
+++ head/sys/xen/xenstore/xenstore.c Tue Sep 20 23:44:34 2011 (r225704)
@@ -721,8 +721,8 @@ xs_reply_filter(uint32_t request_msg_typ
/*
* The count of transactions drops if we attempted
* to end a transaction (even if that attempt fails
- * in error), we receive a transaction end acknowledgement
- * or if our attempt to begin a transactionfails.
+ * in error), we receive a transaction end acknowledgement,
+ * or if our attempt to begin a transaction fails.
*/
if (request_msg_type == XS_TRANSACTION_END
|| (request_reply_error == 0 && reply_msg_type == XS_TRANSACTION_END)
@@ -1194,8 +1194,14 @@ xs_attach(device_t dev)
* all transactions and individual requests have completed.
*/
static int
-xs_suspend(device_t dev __unused)
+xs_suspend(device_t dev)
{
+ int error;
+
+ /* Suspend child Xen devices. */
+ error = bus_generic_suspend(dev);
+ if (error != 0)
+ return (error);
sx_xlock(&xs.suspend_mutex);
sx_xlock(&xs.request_mutex);
@@ -1227,6 +1233,9 @@ xs_resume(device_t dev __unused)
sx_xunlock(&xs.suspend_mutex);
+ /* Resume child Xen devices. */
+ bus_generic_resume(dev);
+
return (0);
}
More information about the svn-src-head
mailing list