[PATCH v3 3/5] net/virtio-user: add rxq interrupt mode support
From: Jianfeng Tan <hidden>
Date: 2017-03-31 19:44:17
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
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 <redacted> --- doc/guides/rel_notes/release_17_05.rst | 7 ++++++ drivers/net/virtio/virtio_user/virtio_user_dev.c | 27 ++++++++++++++++++++++++ drivers/net/virtio/virtio_user/virtio_user_dev.h | 1 + drivers/net/virtio/virtio_user_ethdev.c | 12 ++++++++++- 4 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index bb64428..2b5eaab 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst@@ -57,6 +57,13 @@ 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 8ff23c5..ce4ead0 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c@@ -254,6 +254,30 @@ virtio_user_dev_init_notify(struct virtio_user_dev *dev) } 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->portid]; + + 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) { uint32_t q;
@@ -265,6 +289,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 bd2e4ca..44c4e68 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 portid; 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 2961e6b..335d70d 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,
@@ -307,7 +317,7 @@ virtio_user_eth_dev_alloc(const char *name) return NULL; } - hw->port_id = data->port_id; + dev->portid = hw->port_id = data->port_id; virtio_hw_internal[hw->port_id].vtpci_ops = &virtio_user_ops; hw->use_msix = 0; hw->modern = 0;
--
2.7.4