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 <jianfeng.tan@intel.com>
This commit is contained in:
parent
e6e7ad8b30
commit
3d4fb6fd25
@ -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
|
||||
---------------
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user