# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1239096570 -3600
# Node ID e5d3f2fa3428ca1d3ee265647b60239509cd798c
# Parent 950b9eb2766128f85adf52d5aabcd15eb8c77dc0
netfront accel: Better watch handling across suspend/resume
Signed-off-by: Kieran Mansley <kmansley@xxxxxxxxxxxxxx>
---
drivers/xen/netfront/accel.c | 43 ++++++++++++++++++++++++++++---------------
1 files changed, 28 insertions(+), 15 deletions(-)
diff -r 950b9eb27661 -r e5d3f2fa3428 drivers/xen/netfront/accel.c
--- a/drivers/xen/netfront/accel.c Mon Apr 06 13:51:20 2009 +0100
+++ b/drivers/xen/netfront/accel.c Tue Apr 07 10:29:30 2009 +0100
@@ -50,6 +50,8 @@ static int netfront_load_accelerator(str
static int netfront_load_accelerator(struct netfront_info *np,
struct xenbus_device *dev,
const char *frontend);
+
+static void netfront_accelerator_remove_watch(struct netfront_info *np);
/*
* List of all netfront accelerator plugin modules available. Each
@@ -164,8 +166,11 @@ void netfront_accelerator_add_watch(stru
{
int err;
- /* Check we're not trying to overwrite an existing watch */
- BUG_ON(np->accel_vif_state.accel_watch.node != NULL);
+ /*
+ * If old watch exists, e.g. from before suspend/resume,
+ * remove it now
+ */
+ netfront_accelerator_remove_watch(np);
/* Get a watch on the accelerator plugin */
err = xenbus_watch_path2(np->xbdev, np->xbdev->otherend,
@@ -180,6 +185,19 @@ void netfront_accelerator_add_watch(stru
}
+static void
+netfront_accelerator_purge_watch(struct netfront_accel_vif_state *vif_state)
+{
+ flush_workqueue(accel_watch_workqueue);
+
+ /* Clean up any state left from watch */
+ if (vif_state->accel_frontend != NULL) {
+ kfree(vif_state->accel_frontend);
+ vif_state->accel_frontend = NULL;
+ }
+}
+
+
static
void netfront_accelerator_remove_watch(struct netfront_info *np)
{
@@ -191,13 +209,7 @@ void netfront_accelerator_remove_watch(s
kfree(vif_state->accel_watch.node);
vif_state->accel_watch.node = NULL;
- flush_workqueue(accel_watch_workqueue);
-
- /* Clean up any state left from watch */
- if (vif_state->accel_frontend != NULL) {
- kfree(vif_state->accel_frontend);
- vif_state->accel_frontend = NULL;
- }
+ netfront_accelerator_purge_watch(vif_state);
}
}
@@ -670,8 +682,6 @@ int netfront_accelerator_suspend(struct
{
int rc = 0;
- netfront_accelerator_remove_watch(np);
-
mutex_lock(&accelerator_mutex);
/* Check that we've got a device that was accelerated */
@@ -692,13 +702,16 @@ int netfront_accelerator_suspend_cancel(
int netfront_accelerator_suspend_cancel(struct netfront_info *np,
struct xenbus_device *dev)
{
+ netfront_accelerator_purge_watch(&np->accel_vif_state);
+
/*
- * Setting the watch will cause it to fire and probe the
- * accelerator, so no need to call accelerator_probe_new_vif()
- * directly here
+ * Gratuitously fire the watch handler to reinstate the
+ * configured accelerator
*/
if (dev->state == XenbusStateConnected)
- netfront_accelerator_add_watch(np);
+ queue_work(accel_watch_workqueue,
+ &np->accel_vif_state.accel_work);
+
return 0;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|