From 3d4fb6fd250577411f904e02bfd5b703b69fbddf Mon Sep 17 00:00:00 2001 From: Jianfeng Tan Date: Fri, 31 Mar 2017 19:44:56 +0000 Subject: [PATCH] net/virtio-user: support Rx interrupt For rxq interrupt, the device (backend driver) will notify driver through callfd. Each virtqueue has a callfd. To keep compatible with the existing framework, we will give these callfds to interrupt thread for listening for interrupts. Before that, we need to allocate intr_handle, and fill callfds into it so that driver can use it to set up rxq interrupt mode. Signed-off-by: Jianfeng Tan --- doc/guides/rel_notes/release_17_05.rst | 8 ++++++ .../net/virtio/virtio_user/virtio_user_dev.c | 27 +++++++++++++++++++ .../net/virtio/virtio_user/virtio_user_dev.h | 1 + drivers/net/virtio/virtio_user_ethdev.c | 11 ++++++++ 4 files changed, 47 insertions(+) diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst index ee8eb6bbb6..d7ea0df133 100644 --- a/doc/guides/rel_notes/release_17_05.rst +++ b/doc/guides/rel_notes/release_17_05.rst @@ -161,6 +161,14 @@ New Features * Enable Vhost PMD's MTU get feature. * Get max MTU value from host in Virtio PMD +* **Added interrupt mode support for virtio-user.** + + Implemented Rxq interrupt mode support for virtio-user as a virtual + device. Supported cases: + + * Rxq interrupt for virtio-user + vhost-user as the backend. + * Rxq interrupt for virtio-user + vhost-kernel as the backend. + Resolved Issues --------------- diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index b0070d5ca4..847197570d 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -250,6 +250,30 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev) return 0; } +static int +virtio_user_fill_intr_handle(struct virtio_user_dev *dev) +{ + uint32_t i; + struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id]; + + if (!eth_dev->intr_handle) { + eth_dev->intr_handle = malloc(sizeof(*eth_dev->intr_handle)); + if (!eth_dev->intr_handle) { + PMD_DRV_LOG(ERR, "fail to allocate intr_handle"); + return -1; + } + memset(eth_dev->intr_handle, 0, sizeof(*eth_dev->intr_handle)); + } + + for (i = 0; i < dev->max_queue_pairs; ++i) + eth_dev->intr_handle->efds[i] = dev->callfds[i]; + eth_dev->intr_handle->nb_efd = dev->max_queue_pairs; + eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1; + eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV; + + return 0; +} + static int virtio_user_dev_setup(struct virtio_user_dev *dev) { @@ -262,6 +286,9 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) if (virtio_user_dev_init_notify(dev) < 0) return -1; + if (virtio_user_fill_intr_handle(dev) < 0) + return -1; + if (is_vhost_user_by_type(dev->path)) { dev->ops = &ops_user; } else { diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h index 8abaa68a5d..8361b6bdd7 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h @@ -60,6 +60,7 @@ struct virtio_user_dev { */ uint64_t device_features; /* supported features by device */ uint8_t status; + uint8_t port_id; uint8_t mac_addr[ETHER_ADDR_LEN]; char path[PATH_MAX]; struct vring vrings[VIRTIO_MAX_VIRTQUEUES]; diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index 740d7b1599..9dd55fa92f 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -148,6 +148,15 @@ virtio_user_set_config_irq(struct virtio_hw *hw __rte_unused, return VIRTIO_MSI_NO_VECTOR; } +static uint16_t +virtio_user_set_queue_irq(struct virtio_hw *hw __rte_unused, + struct virtqueue *vq __rte_unused, + uint16_t vec) +{ + /* pretend we have done that */ + return vec; +} + /* This function is to get the queue size, aka, number of descs, of a specified * queue. Different with the VHOST_USER_GET_QUEUE_NUM, which is used to get the * max supported queues. @@ -226,6 +235,7 @@ const struct virtio_pci_ops virtio_user_ops = { .set_features = virtio_user_set_features, .get_isr = virtio_user_get_isr, .set_config_irq = virtio_user_set_config_irq, + .set_queue_irq = virtio_user_set_queue_irq, .get_queue_num = virtio_user_get_queue_num, .setup_queue = virtio_user_setup_queue, .del_queue = virtio_user_del_queue, @@ -313,6 +323,7 @@ virtio_user_eth_dev_alloc(const char *name) } hw->port_id = data->port_id; + dev->port_id = data->port_id; virtio_hw_internal[hw->port_id].vtpci_ops = &virtio_user_ops; hw->use_msix = 0; hw->modern = 0; -- 2.20.1