diff options
author | James Morris <james.l.morris@oracle.com> | 2017-12-11 17:01:08 +1100 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2017-12-11 17:01:08 +1100 |
commit | d21bd6898336a7892914d308d5e0868f0b863571 (patch) | |
tree | f5f756c25348b5a6c1ce9ddbaa7d1ecd1bef40b0 /drivers/net/xen-netfront.c | |
parent | 34d8751fd4ffa34e85ee7e85d34168b3f3f62b42 (diff) | |
parent | 50c4c4e268a2d7a3e58ebb698ac74da0de40ae36 (diff) |
Sync to v4.15-rc3 for security subsystem developers to work against.
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r-- | drivers/net/xen-netfront.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 523387e71a80..c5a34671abda 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -87,6 +87,8 @@ 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_unload_q); + struct netfront_stats { u64 packets; u64 bytes; @@ -228,9 +230,9 @@ static bool xennet_can_sg(struct net_device *dev) } -static void rx_refill_timeout(unsigned long data) +static void rx_refill_timeout(struct timer_list *t) { - struct netfront_queue *queue = (struct netfront_queue *)data; + struct netfront_queue *queue = from_timer(queue, t, rx_refill_timer); napi_schedule(&queue->napi); } @@ -1316,7 +1318,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) netdev->features |= netdev->hw_features; netdev->ethtool_ops = &xennet_ethtool_ops; - netdev->min_mtu = 0; + netdev->min_mtu = ETH_MIN_MTU; netdev->max_mtu = XEN_NETIF_MAX_TX_SIZE; SET_NETDEV_DEV(netdev, &dev->dev); @@ -1605,8 +1607,7 @@ static int xennet_init_queue(struct netfront_queue *queue) spin_lock_init(&queue->tx_lock); spin_lock_init(&queue->rx_lock); - setup_timer(&queue->rx_refill_timer, rx_refill_timeout, - (unsigned long)queue); + timer_setup(&queue->rx_refill_timer, rx_refill_timeout, 0); snprintf(queue->name, sizeof(queue->name), "%s-q%u", queue->info->netdev->name, queue->id); @@ -2021,10 +2022,12 @@ 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; } @@ -2130,6 +2133,20 @@ static int xennet_remove(struct xenbus_device *dev) dev_dbg(&dev->dev, "%s\n", dev->nodename); + if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { + xenbus_switch_state(dev, XenbusStateClosing); + wait_event(module_unload_q, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosing); + + xenbus_switch_state(dev, XenbusStateClosed); + wait_event(module_unload_q, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev->otherend) == + XenbusStateUnknown); + } + xennet_disconnect_backend(info); unregister_netdev(info->netdev); |