X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_user_ethdev.c;h=90fcd6e7cc2652767b81ced2b56a656f5eba16db;hb=1c9e61b3a45321b3cae742e8769b10c06c0324f0;hp=dc64120aa07829eda897776f4a394fb846450f2c;hpb=5b75b63c324a7a3b0101b4cf1e245b8b8a0f22bd;p=dpdk.git diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index dc64120aa0..90fcd6e7cc 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -28,146 +28,6 @@ #define virtio_user_get_dev(hwp) container_of(hwp, struct virtio_user_dev, hw) -static void -virtio_user_reset_queues_packed(struct rte_eth_dev *eth_dev) -{ - struct virtio_user_dev *dev = eth_dev->data->dev_private; - struct virtio_hw *hw = &dev->hw; - 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 < eth_dev->data->nb_rx_queues; i++) { - rxvq = eth_dev->data->rx_queues[i]; - virtqueue_rxvq_reset_packed(rxvq->vq); - virtio_dev_rx_queue_setup_finish(eth_dev, i); - } - - for (i = 0; i < eth_dev->data->nb_tx_queues; i++) { - txvq = eth_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, connectfd, old_status; - struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id]; - struct virtio_hw *hw = &dev->hw; - - connectfd = accept(dev->listenfd, NULL, NULL); - if (connectfd < 0) - return -1; - - dev->vhostfd = connectfd; - old_status = dev->status; - - virtio_reset(hw); - - virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK); - - virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); - - if (dev->ops->get_features(dev, &dev->device_features) < 0) { - PMD_INIT_LOG(ERR, "get_features failed: %s", - strerror(errno)); - return -1; - } - - dev->device_features |= dev->frontend_features; - - /* umask vhost-user unsupported features */ - dev->device_features &= ~(dev->unsupported_features); - - dev->features &= dev->device_features; - - /* For packed ring, resetting queues is required in reconnection. */ - if (virtio_with_packed_queue(hw) && - (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) { - PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped" - " when packed ring reconnecting."); - virtio_user_reset_queues_packed(eth_dev); - } - - virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK); - - /* Start the device */ - virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK); - if (!dev->started) - return -1; - - if (dev->queue_pairs > 1) { - ret = virtio_user_handle_mq(dev, dev->queue_pairs); - if (ret != 0) { - PMD_INIT_LOG(ERR, "Fails to enable multi-queue pairs!"); - return -1; - } - } - if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) { - if (rte_intr_disable(eth_dev->intr_handle) < 0) { - PMD_DRV_LOG(ERR, "interrupt disable failed"); - return -1; - } - rte_intr_callback_unregister(eth_dev->intr_handle, - virtio_interrupt_handler, - eth_dev); - eth_dev->intr_handle->fd = connectfd; - rte_intr_callback_register(eth_dev->intr_handle, - virtio_interrupt_handler, eth_dev); - - if (rte_intr_enable(eth_dev->intr_handle) < 0) { - PMD_DRV_LOG(ERR, "interrupt enable failed"); - return -1; - } - } - PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!"); - return 0; -} - -static void -virtio_user_delayed_handler(void *param) -{ - struct virtio_hw *hw = (struct virtio_hw *)param; - struct rte_eth_dev *eth_dev = &rte_eth_devices[hw->port_id]; - struct virtio_user_dev *dev = virtio_user_get_dev(hw); - - if (rte_intr_disable(eth_dev->intr_handle) < 0) { - PMD_DRV_LOG(ERR, "interrupt disable failed"); - return; - } - rte_intr_callback_unregister(eth_dev->intr_handle, - virtio_interrupt_handler, eth_dev); - if (dev->is_server) { - if (dev->vhostfd >= 0) { - close(dev->vhostfd); - dev->vhostfd = -1; - } - eth_dev->intr_handle->fd = dev->listenfd; - rte_intr_callback_register(eth_dev->intr_handle, - virtio_interrupt_handler, eth_dev); - if (rte_intr_enable(eth_dev->intr_handle) < 0) { - PMD_DRV_LOG(ERR, "interrupt enable failed"); - return; - } - } -} - static void virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, void *dst, int length) @@ -183,44 +43,7 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, } if (offset == offsetof(struct virtio_net_config, status)) { - char buf[128]; - - if (dev->vhostfd >= 0) { - int r; - int flags; - - flags = fcntl(dev->vhostfd, F_GETFL); - if (fcntl(dev->vhostfd, F_SETFL, - flags | O_NONBLOCK) == -1) { - PMD_DRV_LOG(ERR, "error setting O_NONBLOCK flag"); - return; - } - r = recv(dev->vhostfd, buf, 128, MSG_PEEK); - if (r == 0 || (r < 0 && errno != EAGAIN)) { - dev->net_status &= (~VIRTIO_NET_S_LINK_UP); - PMD_DRV_LOG(ERR, "virtio-user port %u is down", - hw->port_id); - - /* This function could be called in the process - * of interrupt handling, callback cannot be - * unregistered here, set an alarm to do it. - */ - rte_eal_alarm_set(1, - virtio_user_delayed_handler, - (void *)hw); - } else { - dev->net_status |= VIRTIO_NET_S_LINK_UP; - } - if (fcntl(dev->vhostfd, F_SETFL, - flags & ~O_NONBLOCK) == -1) { - PMD_DRV_LOG(ERR, "error clearing O_NONBLOCK flag"); - return; - } - } else if (dev->is_server) { - dev->net_status &= (~VIRTIO_NET_S_LINK_UP); - if (virtio_user_server_reconnect(dev) >= 0) - dev->net_status |= VIRTIO_NET_S_LINK_UP; - } + virtio_user_dev_update_link_state(dev); *(uint16_t *)dst = dev->net_status; } @@ -237,12 +60,15 @@ virtio_user_write_dev_config(struct virtio_hw *hw, size_t offset, struct virtio_user_dev *dev = virtio_user_get_dev(hw); if ((offset == offsetof(struct virtio_net_config, mac)) && - (length == RTE_ETHER_ADDR_LEN)) + (length == RTE_ETHER_ADDR_LEN)) { for (i = 0; i < RTE_ETHER_ADDR_LEN; ++i) dev->mac_addr[i] = ((const uint8_t *)src)[i]; - else + virtio_user_dev_set_mac(dev); + virtio_user_dev_get_mac(dev); + } else { PMD_DRV_LOG(ERR, "not supported offset=%zu, len=%d", offset, length); + } } static void @@ -287,7 +113,8 @@ virtio_user_get_features(struct virtio_hw *hw) struct virtio_user_dev *dev = virtio_user_get_dev(hw); /* unmask feature bits defined in vhost user protocol */ - return dev->device_features & VIRTIO_PMD_SUPPORTED_GUEST_FEATURES; + return (dev->device_features | dev->frontend_features) & + VIRTIO_PMD_SUPPORTED_GUEST_FEATURES; } static void @@ -295,7 +122,7 @@ virtio_user_set_features(struct virtio_hw *hw, uint64_t features) { struct virtio_user_dev *dev = virtio_user_get_dev(hw); - dev->features = features & dev->device_features; + dev->features = features & (dev->device_features | dev->frontend_features); } static int @@ -426,7 +253,7 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq) uint64_t buf = 1; struct virtio_user_dev *dev = virtio_user_get_dev(hw); - if (hw->cvq && (hw->cvq->vq == vq)) { + if (hw->cvq && (virtnet_cq_to_vq(hw->cvq) == vq)) { if (virtio_with_packed_queue(vq->hw)) virtio_user_handle_cq_packed(dev, vq->vq_queue_index); else @@ -537,7 +364,7 @@ vdpa_dynamic_major_num(void) { FILE *fp; char *line = NULL; - size_t size; + size_t size = 0; char name[11]; bool found = false; uint32_t num; @@ -557,6 +384,7 @@ vdpa_dynamic_major_num(void) break; } } + free(line); fclose(fp); return found ? num : UNNAMED_MAJOR; } @@ -605,7 +433,6 @@ virtio_user_eth_dev_alloc(struct rte_vdev_device *vdev) hw = &dev->hw; hw->port_id = data->port_id; - dev->port_id = data->port_id; VIRTIO_OPS(hw) = &virtio_user_ops; hw->intr_lsc = 1;