X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_user_ethdev.c;h=5637001dfccb7854ca8609857b82c7ef943f7421;hb=a3147ae9aff9d7fd8644083d7d9f87ba9cabc524;hp=893f48a5d196ffa32ba1428396e6deb940893b9c;hpb=35b2d13fd6fdcbd191f2a30d74648faeb1186c65;p=dpdk.git diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index 893f48a5d1..5637001dfc 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "virtio_ethdev.h" #include "virtio_logs.h" @@ -20,16 +21,53 @@ #include "virtqueue.h" #include "virtio_rxtx.h" #include "virtio_user/virtio_user_dev.h" +#include "virtio_user/vhost.h" #define virtio_user_get_dev(hw) \ ((struct virtio_user_dev *)(hw)->virtio_user_dev) +static void +virtio_user_reset_queues_packed(struct rte_eth_dev *dev) +{ + struct virtio_hw *hw = dev->data->dev_private; + struct virtnet_rx *rxvq; + struct virtnet_tx *txvq; + uint16_t i; + + /* Add lock to avoid queue contention. */ + rte_spinlock_lock(&hw->state_lock); + hw->started = 0; + + /* + * Waitting for datapath to complete before resetting queues. + * 1 ms should be enough for the ongoing Tx/Rx function to finish. + */ + rte_delay_ms(1); + + /* Vring reset for each Tx queue and Rx queue. */ + for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxvq = dev->data->rx_queues[i]; + virtqueue_rxvq_reset_packed(rxvq->vq); + virtio_dev_rx_queue_setup_finish(dev, i); + } + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txvq = dev->data->tx_queues[i]; + virtqueue_txvq_reset_packed(txvq->vq); + } + + hw->started = 1; + rte_spinlock_unlock(&hw->state_lock); +} + + static int virtio_user_server_reconnect(struct virtio_user_dev *dev) { int ret; int connectfd; struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id]; + struct virtio_hw *hw = eth_dev->data->dev_private; connectfd = accept(dev->listenfd, NULL, NULL); if (connectfd < 0) @@ -50,6 +88,13 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev) dev->features &= dev->device_features; + /* For packed ring, resetting queues is required in reconnection. */ + if (vtpci_packed_queue(hw)) { + PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped" + " when packed ring reconnecting."); + virtio_user_reset_queues_packed(eth_dev); + } + ret = virtio_user_start_device(dev); if (ret < 0) return -1; @@ -440,8 +485,6 @@ get_integer_arg(const char *key __rte_unused, return 0; } -static struct rte_vdev_driver virtio_user_driver; - static struct rte_eth_dev * virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev) { @@ -518,7 +561,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) const char *name = rte_vdev_device_name(dev); eth_dev = rte_eth_dev_attach_secondary(name); if (!eth_dev) { - RTE_LOG(ERR, PMD, "Failed to probe %s\n", name); + PMD_INIT_LOG(ERR, "Failed to probe %s", name); return -1; } @@ -697,8 +740,6 @@ virtio_user_pmd_remove(struct rte_vdev_device *vdev) { const char *name; struct rte_eth_dev *eth_dev; - struct virtio_hw *hw; - struct virtio_user_dev *dev; if (!vdev) return -EINVAL; @@ -706,8 +747,9 @@ virtio_user_pmd_remove(struct rte_vdev_device *vdev) name = rte_vdev_device_name(vdev); PMD_DRV_LOG(INFO, "Un-Initializing %s", name); eth_dev = rte_eth_dev_allocated(name); + /* Port has already been released by close. */ if (!eth_dev) - return -ENODEV; + return 0; if (rte_eal_process_type() != RTE_PROC_PRIMARY) return rte_eth_dev_release_port(eth_dev); @@ -715,12 +757,6 @@ virtio_user_pmd_remove(struct rte_vdev_device *vdev) /* make sure the device is stopped, queues freed */ rte_eth_dev_close(eth_dev->data->port_id); - hw = eth_dev->data->dev_private; - dev = hw->virtio_user_dev; - virtio_user_dev_uninit(dev); - - rte_eth_dev_release_port(eth_dev); - return 0; }