Merge 4.14.73 into android-4.14-p
[GitHub/moto-9609/android_kernel_motorola_exynos9610.git] / drivers / net / xen-netfront.c
index 8b8689c6d8877863dddad9f9c10215d311f5fa6f..1a40fc3517a8f0b6d443c5e16c94b18c700a4847 100644 (file)
@@ -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_wq);
+
 struct netfront_stats {
        u64                     packets;
        u64                     bytes;
@@ -237,7 +239,7 @@ static void rx_refill_timeout(unsigned long data)
 static int netfront_tx_slot_available(struct netfront_queue *queue)
 {
        return (queue->tx.req_prod_pvt - queue->tx.rsp_cons) <
-               (NET_TX_RING_SIZE - MAX_SKB_FRAGS - 2);
+               (NET_TX_RING_SIZE - XEN_NETIF_NR_SLOTS_MIN - 1);
 }
 
 static void xennet_maybe_wake_tx(struct netfront_queue *queue)
@@ -349,6 +351,9 @@ static int xennet_open(struct net_device *dev)
        unsigned int i = 0;
        struct netfront_queue *queue = NULL;
 
+       if (!np->queues)
+               return -ENODEV;
+
        for (i = 0; i < num_queues; ++i) {
                queue = &np->queues[i];
                napi_enable(&queue->napi);
@@ -785,7 +790,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
        RING_IDX cons = queue->rx.rsp_cons;
        struct sk_buff *skb = xennet_get_rx_skb(queue, cons);
        grant_ref_t ref = xennet_get_rx_ref(queue, cons);
-       int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD);
+       int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD);
        int slots = 1;
        int err = 0;
        unsigned long ret;
@@ -888,7 +893,6 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
                                  struct sk_buff *skb,
                                  struct sk_buff_head *list)
 {
-       struct skb_shared_info *shinfo = skb_shinfo(skb);
        RING_IDX cons = queue->rx.rsp_cons;
        struct sk_buff *nskb;
 
@@ -897,15 +901,20 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
                        RING_GET_RESPONSE(&queue->rx, ++cons);
                skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0];
 
-               if (shinfo->nr_frags == MAX_SKB_FRAGS) {
+               if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) {
                        unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
 
                        BUG_ON(pull_to <= skb_headlen(skb));
                        __pskb_pull_tail(skb, pull_to - skb_headlen(skb));
                }
-               BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS);
+               if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
+                       queue->rx.rsp_cons = ++cons;
+                       kfree_skb(nskb);
+                       return ~0U;
+               }
 
-               skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag),
+               skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+                               skb_frag_page(nfrag),
                                rx->offset, rx->status, PAGE_SIZE);
 
                skb_shinfo(nskb)->nr_frags = 0;
@@ -1039,6 +1048,8 @@ err:
                skb->len += rx->status;
 
                i = xennet_fill_frags(queue, skb, &tmpq);
+               if (unlikely(i == ~0U))
+                       goto err;
 
                if (rx->flags & XEN_NETRXF_csum_blank)
                        skb->ip_summed = CHECKSUM_PARTIAL;
@@ -1324,6 +1335,12 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
 
        netif_carrier_off(netdev);
 
+       xenbus_switch_state(dev, XenbusStateInitialising);
+       wait_event(module_wq,
+                  xenbus_read_driver_state(dev->otherend) !=
+                  XenbusStateClosed &&
+                  xenbus_read_driver_state(dev->otherend) !=
+                  XenbusStateUnknown);
        return netdev;
 
  exit:
@@ -1355,18 +1372,8 @@ static int netfront_probe(struct xenbus_device *dev,
 #ifdef CONFIG_SYSFS
        info->netdev->sysfs_groups[0] = &xennet_dev_group;
 #endif
-       err = register_netdev(info->netdev);
-       if (err) {
-               pr_warn("%s: register_netdev err=%d\n", __func__, err);
-               goto fail;
-       }
 
        return 0;
-
- fail:
-       xennet_free_netdev(netdev);
-       dev_set_drvdata(&dev->dev, NULL);
-       return err;
 }
 
 static void xennet_end_access(int ref, void *page)
@@ -1601,6 +1608,7 @@ static int xennet_init_queue(struct netfront_queue *queue)
 {
        unsigned short i;
        int err = 0;
+       char *devid;
 
        spin_lock_init(&queue->tx_lock);
        spin_lock_init(&queue->rx_lock);
@@ -1608,8 +1616,9 @@ static int xennet_init_queue(struct netfront_queue *queue)
        setup_timer(&queue->rx_refill_timer, rx_refill_timeout,
                    (unsigned long)queue);
 
-       snprintf(queue->name, sizeof(queue->name), "%s-q%u",
-                queue->info->netdev->name, queue->id);
+       devid = strrchr(queue->info->xbdev->nodename, '/') + 1;
+       snprintf(queue->name, sizeof(queue->name), "vif%s-q%u",
+                devid, queue->id);
 
        /* Initialise tx_skbs as a free chain containing every entry. */
        queue->tx_skb_freelist = 0;
@@ -1735,8 +1744,6 @@ static void xennet_destroy_queues(struct netfront_info *info)
 {
        unsigned int i;
 
-       rtnl_lock();
-
        for (i = 0; i < info->netdev->real_num_tx_queues; i++) {
                struct netfront_queue *queue = &info->queues[i];
 
@@ -1745,8 +1752,6 @@ static void xennet_destroy_queues(struct netfront_info *info)
                netif_napi_del(&queue->napi);
        }
 
-       rtnl_unlock();
-
        kfree(info->queues);
        info->queues = NULL;
 }
@@ -1762,8 +1767,6 @@ static int xennet_create_queues(struct netfront_info *info,
        if (!info->queues)
                return -ENOMEM;
 
-       rtnl_lock();
-
        for (i = 0; i < *num_queues; i++) {
                struct netfront_queue *queue = &info->queues[i];
 
@@ -1772,7 +1775,7 @@ static int xennet_create_queues(struct netfront_info *info,
 
                ret = xennet_init_queue(queue);
                if (ret < 0) {
-                       dev_warn(&info->netdev->dev,
+                       dev_warn(&info->xbdev->dev,
                                 "only created %d queues\n", i);
                        *num_queues = i;
                        break;
@@ -1786,10 +1789,8 @@ static int xennet_create_queues(struct netfront_info *info,
 
        netif_set_real_num_tx_queues(info->netdev, *num_queues);
 
-       rtnl_unlock();
-
        if (*num_queues == 0) {
-               dev_err(&info->netdev->dev, "no queues\n");
+               dev_err(&info->xbdev->dev, "no queues\n");
                return -EINVAL;
        }
        return 0;
@@ -1826,6 +1827,7 @@ static int talk_to_netback(struct xenbus_device *dev,
                goto out;
        }
 
+       rtnl_lock();
        if (info->queues)
                xennet_destroy_queues(info);
 
@@ -1836,6 +1838,7 @@ static int talk_to_netback(struct xenbus_device *dev,
                info->queues = NULL;
                goto out;
        }
+       rtnl_unlock();
 
        /* Create shared ring, alloc event channel -- for each queue */
        for (i = 0; i < num_queues; ++i) {
@@ -1932,8 +1935,10 @@ abort_transaction_no_dev_fatal:
        xenbus_transaction_end(xbt, 1);
  destroy_ring:
        xennet_disconnect_backend(info);
+       rtnl_lock();
        xennet_destroy_queues(info);
  out:
+       rtnl_unlock();
        device_unregister(&dev->dev);
        return err;
 }
@@ -1963,6 +1968,15 @@ static int xennet_connect(struct net_device *dev)
        netdev_update_features(dev);
        rtnl_unlock();
 
+       if (dev->reg_state == NETREG_UNINITIALIZED) {
+               err = register_netdev(dev);
+               if (err) {
+                       pr_warn("%s: register_netdev err=%d\n", __func__, err);
+                       device_unregister(&np->xbdev->dev);
+                       return err;
+               }
+       }
+
        /*
         * All public and private state should now be sane.  Get
         * ready to start sending and receiving packets and give the driver
@@ -2000,6 +2014,8 @@ 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:
@@ -2130,12 +2146,32 @@ 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_wq,
+                          xenbus_read_driver_state(dev->otherend) ==
+                          XenbusStateClosing ||
+                          xenbus_read_driver_state(dev->otherend) ==
+                          XenbusStateUnknown);
+
+               xenbus_switch_state(dev, XenbusStateClosed);
+               wait_event(module_wq,
+                          xenbus_read_driver_state(dev->otherend) ==
+                          XenbusStateClosed ||
+                          xenbus_read_driver_state(dev->otherend) ==
+                          XenbusStateUnknown);
+       }
+
        xennet_disconnect_backend(info);
 
-       unregister_netdev(info->netdev);
+       if (info->netdev->reg_state == NETREG_REGISTERED)
+               unregister_netdev(info->netdev);
 
-       if (info->queues)
+       if (info->queues) {
+               rtnl_lock();
                xennet_destroy_queues(info);
+               rtnl_unlock();
+       }
        xennet_free_netdev(info->netdev);
 
        return 0;