Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+10 −14
Original line number Diff line number Diff line
@@ -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,7 +1331,7 @@ 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,
	wait_event(module_wq,
		   xenbus_read_driver_state(dev->otherend) !=
		   XenbusStateClosed &&
		   xenbus_read_driver_state(dev->otherend) !=
@@ -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) ==