mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 18:24:14 +08:00
xen/netfront: fix waiting for xenbus state change
Commit822fb18a82
("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:822fb18a82
("xen-netfront: wait xenbus state change when load module manually") Cc: <stable@vger.kernel.org> #4.18 Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f74dd480cf
commit
8edfe2e992
@ -87,8 +87,7 @@ struct netfront_cb {
|
||||
/* IRQ name is queue name with "-tx" or "-rx" appended */
|
||||
#define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3)
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(module_load_q);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(module_wq);
|
||||
|
||||
struct netfront_stats {
|
||||
u64 packets;
|
||||
@ -1332,11 +1331,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
xenbus_switch_state(dev, XenbusStateInitialising);
|
||||
wait_event(module_load_q,
|
||||
xenbus_read_driver_state(dev->otherend) !=
|
||||
XenbusStateClosed &&
|
||||
xenbus_read_driver_state(dev->otherend) !=
|
||||
XenbusStateUnknown);
|
||||
wait_event(module_wq,
|
||||
xenbus_read_driver_state(dev->otherend) !=
|
||||
XenbusStateClosed &&
|
||||
xenbus_read_driver_state(dev->otherend) !=
|
||||
XenbusStateUnknown);
|
||||
return netdev;
|
||||
|
||||
exit:
|
||||
@ -2010,15 +2009,14 @@ static void netback_changed(struct xenbus_device *dev,
|
||||
|
||||
dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state));
|
||||
|
||||
wake_up_all(&module_wq);
|
||||
|
||||
switch (backend_state) {
|
||||
case XenbusStateInitialising:
|
||||
case XenbusStateInitialised:
|
||||
case XenbusStateReconfiguring:
|
||||
case XenbusStateReconfigured:
|
||||
break;
|
||||
|
||||
case XenbusStateUnknown:
|
||||
wake_up_all(&module_unload_q);
|
||||
break;
|
||||
|
||||
case XenbusStateInitWait:
|
||||
@ -2034,12 +2032,10 @@ static void netback_changed(struct xenbus_device *dev,
|
||||
break;
|
||||
|
||||
case XenbusStateClosed:
|
||||
wake_up_all(&module_unload_q);
|
||||
if (dev->state == XenbusStateClosed)
|
||||
break;
|
||||
/* Missed the backend's CLOSING state -- fallthrough */
|
||||
case XenbusStateClosing:
|
||||
wake_up_all(&module_unload_q);
|
||||
xenbus_frontend_closed(dev);
|
||||
break;
|
||||
}
|
||||
@ -2147,14 +2143,14 @@ static int xennet_remove(struct xenbus_device *dev)
|
||||
|
||||
if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) {
|
||||
xenbus_switch_state(dev, XenbusStateClosing);
|
||||
wait_event(module_unload_q,
|
||||
wait_event(module_wq,
|
||||
xenbus_read_driver_state(dev->otherend) ==
|
||||
XenbusStateClosing ||
|
||||
xenbus_read_driver_state(dev->otherend) ==
|
||||
XenbusStateUnknown);
|
||||
|
||||
xenbus_switch_state(dev, XenbusStateClosed);
|
||||
wait_event(module_unload_q,
|
||||
wait_event(module_wq,
|
||||
xenbus_read_driver_state(dev->otherend) ==
|
||||
XenbusStateClosed ||
|
||||
xenbus_read_driver_state(dev->otherend) ==
|
||||
|
Loading…
Reference in New Issue
Block a user