Merge branch 'upstream-16.11-stable' into 16.11.x
[deb_dpdk.git] / drivers / net / vhost / rte_eth_vhost.c
index 766d4ef..12922df 100644 (file)
@@ -115,9 +115,7 @@ struct pmd_internal {
        char *dev_name;
        char *iface_name;
        uint16_t max_queues;
-       uint64_t flags;
-
-       volatile uint16_t once;
+       int vid;
 };
 
 struct internal_list {
@@ -324,6 +322,7 @@ vhost_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
                                *(uint64_t *)(((char *)vq)
                                + vhost_rxport_stat_strings[t].offset);
                }
+               xstats[count].id = count;
                count++;
        }
        for (t = 0; t < VHOST_NB_XSTATS_TXPORT; t++) {
@@ -336,6 +335,7 @@ vhost_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
                                *(uint64_t *)(((char *)vq)
                                + vhost_txport_stat_strings[t].offset);
                }
+               xstats[count].id = count;
                count++;
        }
        return count;
@@ -559,7 +559,7 @@ new_device(int vid)
                rte_atomic32_set(&vq->allow_queuing, 1);
        }
 
-       RTE_LOG(INFO, PMD, "New connection established\n");
+       RTE_LOG(INFO, PMD, "Vhost device %d created\n", vid);
 
        _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
 
@@ -626,7 +626,7 @@ destroy_device(int vid)
        state->max_vring = 0;
        rte_spinlock_unlock(&state->lock);
 
-       RTE_LOG(INFO, PMD, "Connection closed\n");
+       RTE_LOG(INFO, PMD, "Vhost device %d destroyed\n", vid);
 
        _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
 }
@@ -774,35 +774,40 @@ vhost_driver_session_stop(void)
 }
 
 static int
-eth_dev_start(struct rte_eth_dev *dev)
+eth_dev_start(struct rte_eth_dev *dev __rte_unused)
 {
-       struct pmd_internal *internal = dev->data->dev_private;
-       int ret = 0;
-
-       if (rte_atomic16_cmpset(&internal->once, 0, 1)) {
-               ret = rte_vhost_driver_register(internal->iface_name,
-                                               internal->flags);
-               if (ret)
-                       return ret;
-       }
-
-       /* We need only one message handling thread */
-       if (rte_atomic16_add_return(&nb_started_ports, 1) == 1)
-               ret = vhost_driver_session_start();
+       return 0;
+}
 
-       return ret;
+static void
+eth_dev_stop(struct rte_eth_dev *dev __rte_unused)
+{
 }
 
 static void
-eth_dev_stop(struct rte_eth_dev *dev)
+eth_dev_close(struct rte_eth_dev *dev)
 {
-       struct pmd_internal *internal = dev->data->dev_private;
+       struct pmd_internal *internal;
+       struct internal_list *list;
 
-       if (rte_atomic16_cmpset(&internal->once, 1, 0))
-               rte_vhost_driver_unregister(internal->iface_name);
+       internal = dev->data->dev_private;
+       if (!internal)
+               return;
 
-       if (rte_atomic16_sub_return(&nb_started_ports, 1) == 0)
-               vhost_driver_session_stop();
+       rte_vhost_driver_unregister(internal->iface_name);
+
+       list = find_internal_resource(internal->iface_name);
+       if (!list)
+               return;
+
+       pthread_mutex_lock(&internal_list_lock);
+       TAILQ_REMOVE(&internal_list, list, next);
+       pthread_mutex_unlock(&internal_list_lock);
+       rte_free(list);
+
+       free(internal->dev_name);
+       free(internal->iface_name);
+       rte_free(internal);
 }
 
 static int
@@ -973,6 +978,7 @@ rte_eth_vhost_feature_get(void)
 static const struct eth_dev_ops ops = {
        .dev_start = eth_dev_start,
        .dev_stop = eth_dev_stop,
+       .dev_close = eth_dev_close,
        .dev_configure = eth_dev_configure,
        .dev_infos_get = eth_dev_info,
        .rx_queue_setup = eth_rx_queue_setup,
@@ -1046,7 +1052,6 @@ eth_dev_vhost_create(const char *name, char *iface_name, int16_t queues,
        internal->iface_name = strdup(iface_name);
        if (internal->iface_name == NULL)
                goto error;
-       internal->flags = flags;
 
        list->eth_dev = eth_dev;
        pthread_mutex_lock(&internal_list_lock);
@@ -1062,6 +1067,7 @@ eth_dev_vhost_create(const char *name, char *iface_name, int16_t queues,
        data->nb_rx_queues = queues;
        data->nb_tx_queues = queues;
        internal->max_queues = queues;
+       internal->vid = -1;
        data->dev_link = pmd_link;
        data->mac_addrs = eth_addr;
 
@@ -1081,6 +1087,15 @@ eth_dev_vhost_create(const char *name, char *iface_name, int16_t queues,
        eth_dev->rx_pkt_burst = eth_vhost_rx;
        eth_dev->tx_pkt_burst = eth_vhost_tx;
 
+       if (rte_vhost_driver_register(iface_name, flags))
+               goto error;
+
+       /* We need only one message handling thread */
+       if (rte_atomic16_add_return(&nb_started_ports, 1) == 1) {
+               if (vhost_driver_session_start())
+                       goto error;
+       }
+
        return data->port_id;
 
 error:
@@ -1192,8 +1207,6 @@ static int
 rte_pmd_vhost_remove(const char *name)
 {
        struct rte_eth_dev *eth_dev = NULL;
-       struct pmd_internal *internal;
-       struct internal_list *list;
        unsigned int i;
 
        RTE_LOG(INFO, PMD, "Un-Initializing pmd_vhost for %s\n", name);
@@ -1203,27 +1216,16 @@ rte_pmd_vhost_remove(const char *name)
        if (eth_dev == NULL)
                return -ENODEV;
 
-       internal = eth_dev->data->dev_private;
-       if (internal == NULL)
-               return -ENODEV;
-
-       list = find_internal_resource(internal->iface_name);
-       if (list == NULL)
-               return -ENODEV;
+       eth_dev_stop(eth_dev);
 
-       pthread_mutex_lock(&internal_list_lock);
-       TAILQ_REMOVE(&internal_list, list, next);
-       pthread_mutex_unlock(&internal_list_lock);
-       rte_free(list);
+       eth_dev_close(eth_dev);
 
-       eth_dev_stop(eth_dev);
+       if (rte_atomic16_sub_return(&nb_started_ports, 1) == 0)
+               vhost_driver_session_stop();
 
        rte_free(vring_states[eth_dev->data->port_id]);
        vring_states[eth_dev->data->port_id] = NULL;
 
-       free(internal->dev_name);
-       free(internal->iface_name);
-
        for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
                rte_free(eth_dev->data->rx_queues[i]);
        for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
@@ -1231,7 +1233,6 @@ rte_pmd_vhost_remove(const char *name)
 
        rte_free(eth_dev->data->mac_addrs);
        rte_free(eth_dev->data);
-       rte_free(internal);
 
        rte_eth_dev_release_port(eth_dev);