| From foo@baz Wed Aug 1 08:19:18 CEST 2018 |
| From: Xiao Liang <xiliang@redhat.com> |
| Date: Fri, 27 Jul 2018 17:56:08 +0800 |
| Subject: xen-netfront: wait xenbus state change when load module manually |
| |
| From: Xiao Liang <xiliang@redhat.com> |
| |
| [ Upstream commit 822fb18a82abaf4ee7058793d95d340f5dab7bfc ] |
| |
| When loading module manually, after call xenbus_switch_state to initializes |
| the state of the netfront device, the driver state did not change so fast |
| that may lead no dev created in latest kernel. This patch adds wait to make |
| sure xenbus knows the driver is not in closed/unknown state. |
| |
| Current state: |
| [vm]# ethtool eth0 |
| Settings for eth0: |
| Link detected: yes |
| [vm]# modprobe -r xen_netfront |
| [vm]# modprobe xen_netfront |
| [vm]# ethtool eth0 |
| Settings for eth0: |
| Cannot get device settings: No such device |
| Cannot get wake-on-lan settings: No such device |
| Cannot get message level: No such device |
| Cannot get link status: No such device |
| No data available |
| |
| With the patch installed. |
| [vm]# ethtool eth0 |
| Settings for eth0: |
| Link detected: yes |
| [vm]# modprobe -r xen_netfront |
| [vm]# modprobe xen_netfront |
| [vm]# ethtool eth0 |
| Settings for eth0: |
| Link detected: yes |
| |
| Signed-off-by: Xiao Liang <xiliang@redhat.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/xen-netfront.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/drivers/net/xen-netfront.c |
| +++ b/drivers/net/xen-netfront.c |
| @@ -87,6 +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); |
| |
| struct netfront_stats { |
| @@ -1330,6 +1331,11 @@ static struct net_device *xennet_create_ |
| 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); |
| return netdev; |
| |
| exit: |