X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_user_ethdev.c;h=9314ca52047707c965e05862b4ef190aed555742;hb=b59d4d5502dcb1b57be81eb21b5e8bcb80de49e7;hp=8bbf4cf809561a0c647bb4bd0fae9cc8de997ec2;hpb=cc0151b34dee25aac9364c7e52c930efb6c10adb;p=dpdk.git diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index 8bbf4cf809..9314ca5204 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -28,174 +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; - uint64_t protocol_features; - - 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; - } - - if (dev->device_features & - (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)) { - if (dev->ops->send_request(dev, - VHOST_USER_GET_PROTOCOL_FEATURES, - &protocol_features)) - return -1; - - /* Offer VHOST_USER_PROTOCOL_F_STATUS */ - dev->protocol_features |= - (1ULL << VHOST_USER_PROTOCOL_F_STATUS); - dev->protocol_features &= protocol_features; - - if (dev->ops->send_request(dev, - VHOST_USER_SET_PROTOCOL_FEATURES, - &dev->protocol_features)) - return -1; - - if (!(dev->protocol_features & - (1ULL << VHOST_USER_PROTOCOL_F_MQ))) - dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ); - } - - 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; - /* Until the featuers are negotiated again, don't assume - * the backend supports VHOST_USER_PROTOCOL_F_STATUS - */ - dev->protocol_features &= - ~(1ULL << VHOST_USER_PROTOCOL_F_STATUS); - } - 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) @@ -211,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; } @@ -454,7 +249,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