-#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;
- uint64_t protocol_features;
-
- connectfd = accept(dev->listenfd, NULL, NULL);
- if (connectfd < 0)
- return -1;
-
- dev->vhostfd = connectfd;
- if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
- &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;
-
- 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 (vtpci_packed_queue(hw) &&
- (vtpci_get_status(hw) & 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);
- }
-
- ret = virtio_user_start_device(dev);
- if (ret < 0)
- 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;
- }
- }
-}