Commit 8edfe2e9 authored by Juergen Gross's avatar Juergen Gross Committed by David S. Miller

xen/netfront: fix waiting for xenbus state change

Commit 822fb18a ("xen-netfront: wait xenbus state change when load
module manually") added a new wait queue to wait on for a state change
when the module is loaded manually. Unfortunately there is no wakeup
anywhere to stop that waiting.

Instead of introducing a new wait queue rename the existing
module_unload_q to module_wq and use it for both purposes (loading and
unloading).

As any state change of the backend might be intended to stop waiting
do the wake_up_all() in any case when netback_changed() is called.

Fixes: 822fb18a ("xen-netfront: wait xenbus state change when load module manually")
Cc: <stable@vger.kernel.org> #4.18
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f74dd480
...@@ -87,8 +87,7 @@ struct netfront_cb { ...@@ -87,8 +87,7 @@ struct netfront_cb {
/* IRQ name is queue name with "-tx" or "-rx" appended */ /* IRQ name is queue name with "-tx" or "-rx" appended */
#define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3)
static DECLARE_WAIT_QUEUE_HEAD(module_load_q); static DECLARE_WAIT_QUEUE_HEAD(module_wq);
static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);
struct netfront_stats { struct netfront_stats {
u64 packets; u64 packets;
...@@ -1332,11 +1331,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) ...@@ -1332,11 +1331,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
netif_carrier_off(netdev); netif_carrier_off(netdev);
xenbus_switch_state(dev, XenbusStateInitialising); xenbus_switch_state(dev, XenbusStateInitialising);
wait_event(module_load_q, wait_event(module_wq,
xenbus_read_driver_state(dev->otherend) != xenbus_read_driver_state(dev->otherend) !=
XenbusStateClosed && XenbusStateClosed &&
xenbus_read_driver_state(dev->otherend) != xenbus_read_driver_state(dev->otherend) !=
XenbusStateUnknown); XenbusStateUnknown);
return netdev; return netdev;
exit: exit:
...@@ -2010,15 +2009,14 @@ static void netback_changed(struct xenbus_device *dev, ...@@ -2010,15 +2009,14 @@ static void netback_changed(struct xenbus_device *dev,
dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state)); dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state));
wake_up_all(&module_wq);
switch (backend_state) { switch (backend_state) {
case XenbusStateInitialising: case XenbusStateInitialising:
case XenbusStateInitialised: case XenbusStateInitialised:
case XenbusStateReconfiguring: case XenbusStateReconfiguring:
case XenbusStateReconfigured: case XenbusStateReconfigured:
break;
case XenbusStateUnknown: case XenbusStateUnknown:
wake_up_all(&module_unload_q);
break; break;
case XenbusStateInitWait: case XenbusStateInitWait:
...@@ -2034,12 +2032,10 @@ static void netback_changed(struct xenbus_device *dev, ...@@ -2034,12 +2032,10 @@ static void netback_changed(struct xenbus_device *dev,
break; break;
case XenbusStateClosed: case XenbusStateClosed:
wake_up_all(&module_unload_q);
if (dev->state == XenbusStateClosed) if (dev->state == XenbusStateClosed)
break; break;
/* Missed the backend's CLOSING state -- fallthrough */ /* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing: case XenbusStateClosing:
wake_up_all(&module_unload_q);
xenbus_frontend_closed(dev); xenbus_frontend_closed(dev);
break; break;
} }
...@@ -2147,14 +2143,14 @@ static int xennet_remove(struct xenbus_device *dev) ...@@ -2147,14 +2143,14 @@ static int xennet_remove(struct xenbus_device *dev)
if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) {
xenbus_switch_state(dev, XenbusStateClosing); xenbus_switch_state(dev, XenbusStateClosing);
wait_event(module_unload_q, wait_event(module_wq,
xenbus_read_driver_state(dev->otherend) == xenbus_read_driver_state(dev->otherend) ==
XenbusStateClosing || XenbusStateClosing ||
xenbus_read_driver_state(dev->otherend) == xenbus_read_driver_state(dev->otherend) ==
XenbusStateUnknown); XenbusStateUnknown);
xenbus_switch_state(dev, XenbusStateClosed); xenbus_switch_state(dev, XenbusStateClosed);
wait_event(module_unload_q, wait_event(module_wq,
xenbus_read_driver_state(dev->otherend) == xenbus_read_driver_state(dev->otherend) ==
XenbusStateClosed || XenbusStateClosed ||
xenbus_read_driver_state(dev->otherend) == xenbus_read_driver_state(dev->otherend) ==
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment