virtio: fix the msix for multiqueue
Type: fix Change-Id: Ie0cff37b474f8d85a3ae376e0f547a347fb1ad8a Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com> (cherry picked from commit 8046fdc10b14fd161ee81d0a25cfa79793ef698b)
This commit is contained in:

committed by
Dave Wallace

parent
49ab961abf
commit
9736d6f328
@ -314,19 +314,22 @@ virtio_pci_is_link_up (vlib_main_t * vm, virtio_if_t * vif)
|
||||
}
|
||||
|
||||
static void
|
||||
virtio_pci_irq_0_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h, u16 line)
|
||||
virtio_pci_irq_queue_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
|
||||
u16 line)
|
||||
{
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
virtio_main_t *vim = &virtio_main;
|
||||
uword pd = vlib_pci_get_private_data (vm, h);
|
||||
virtio_if_t *vif = pool_elt_at_index (vim->interfaces, pd);
|
||||
line--;
|
||||
u16 qid = line;
|
||||
|
||||
vnet_device_input_set_interrupt_pending (vnm, vif->hw_if_index, qid);
|
||||
}
|
||||
|
||||
static void
|
||||
virtio_pci_irq_1_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h, u16 line)
|
||||
virtio_pci_irq_config_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
|
||||
u16 line)
|
||||
{
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
virtio_main_t *vim = &virtio_main;
|
||||
@ -363,10 +366,13 @@ virtio_pci_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h)
|
||||
* been made by the device which requires servicing.
|
||||
*/
|
||||
if (isr & VIRTIO_PCI_ISR_INTR)
|
||||
virtio_pci_irq_0_handler (vm, h, line);
|
||||
{
|
||||
for (; line < vif->num_rxqs; line++)
|
||||
virtio_pci_irq_queue_handler (vm, h, (line + 1));
|
||||
}
|
||||
|
||||
if (isr & VIRTIO_PCI_ISR_CONFIG)
|
||||
virtio_pci_irq_1_handler (vm, h, line);
|
||||
virtio_pci_irq_config_handler (vm, h, line);
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -973,11 +979,13 @@ virtio_pci_read_caps (vlib_main_t * vm, virtio_if_t * vif)
|
||||
{
|
||||
virtio_log_debug (vif, "msix interrupt enabled");
|
||||
vif->msix_enabled = VIRTIO_MSIX_ENABLED;
|
||||
vif->msix_table_size = table_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
virtio_log_debug (vif, "msix interrupt disabled");
|
||||
vif->msix_enabled = VIRTIO_MSIX_DISABLED;
|
||||
vif->msix_table_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1106,6 +1114,20 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (vif->msix_enabled == VIRTIO_MSIX_ENABLED)
|
||||
{
|
||||
if (vif->msix_table_size <= vif->max_queue_pairs)
|
||||
{
|
||||
virtio_log_error (vif,
|
||||
"error MSIX lines (%u) <= Number of RXQs (%u)",
|
||||
vif->msix_table_size, vif->max_queue_pairs);
|
||||
return clib_error_return (error,
|
||||
"error MSIX lines (%u) <= Number of RXQs (%u)",
|
||||
vif->msix_table_size,
|
||||
vif->max_queue_pairs);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < vif->max_queue_pairs; i++)
|
||||
{
|
||||
if ((error = virtio_pci_vring_init (vm, vif, RX_QUEUE (i))))
|
||||
@ -1173,12 +1195,30 @@ virtio_pci_device_init (vlib_main_t * vm, virtio_if_t * vif,
|
||||
*/
|
||||
if (vif->msix_enabled == VIRTIO_MSIX_ENABLED)
|
||||
{
|
||||
if (virtio_pci_legacy_set_config_irq (vm, vif, 1) ==
|
||||
int i, j;
|
||||
if (virtio_pci_legacy_set_config_irq (vm, vif, 0) ==
|
||||
VIRTIO_MSI_NO_VECTOR)
|
||||
virtio_log_warning (vif, "config vector 1 is not set");
|
||||
if (virtio_pci_legacy_set_queue_irq (vm, vif, 0, 0) ==
|
||||
VIRTIO_MSI_NO_VECTOR)
|
||||
virtio_log_warning (vif, "queue vector 0 is not set");
|
||||
{
|
||||
virtio_log_warning (vif, "config vector 0 is not set");
|
||||
}
|
||||
else
|
||||
{
|
||||
virtio_log_debug (vif, "config msix vector is set at 0");
|
||||
}
|
||||
for (i = 0, j = 1; i < vif->max_queue_pairs; i++, j++)
|
||||
{
|
||||
if (virtio_pci_legacy_set_queue_irq (vm, vif, j, RX_QUEUE (i)) ==
|
||||
VIRTIO_MSI_NO_VECTOR)
|
||||
{
|
||||
virtio_log_warning (vif, "queue (%u) vector is not set at %u",
|
||||
RX_QUEUE (i), j);
|
||||
}
|
||||
else
|
||||
{
|
||||
virtio_log_debug (vif, "%s (%u) %s %u", "queue",
|
||||
RX_QUEUE (i), "msix vector is set at", j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1198,6 +1238,7 @@ virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
|
||||
virtio_if_t *vif;
|
||||
vlib_pci_dev_handle_t h;
|
||||
clib_error_t *error = 0;
|
||||
u32 interrupt_count = 0;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
pool_foreach (vif, vim->interfaces, ({
|
||||
@ -1250,18 +1291,21 @@ virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (vlib_pci_get_num_msix_interrupts (vm, h) > 1)
|
||||
interrupt_count = vlib_pci_get_num_msix_interrupts (vm, h);
|
||||
if (interrupt_count > 1)
|
||||
{
|
||||
if ((error = vlib_pci_register_msix_handler (vm, h, 0, 1,
|
||||
&virtio_pci_irq_0_handler)))
|
||||
&virtio_pci_irq_config_handler)))
|
||||
{
|
||||
args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
|
||||
virtio_log_error (vif,
|
||||
"error encountered on pci register msix handler 0");
|
||||
goto error;
|
||||
}
|
||||
if ((error = vlib_pci_register_msix_handler (vm, h, 1, 1,
|
||||
&virtio_pci_irq_1_handler)))
|
||||
|
||||
if ((error =
|
||||
vlib_pci_register_msix_handler (vm, h, 1, (interrupt_count - 1),
|
||||
&virtio_pci_irq_queue_handler)))
|
||||
{
|
||||
args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
|
||||
virtio_log_error (vif,
|
||||
@ -1269,7 +1313,7 @@ virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vlib_pci_enable_msix_irq (vm, h, 0, 2)))
|
||||
if ((error = vlib_pci_enable_msix_irq (vm, h, 0, interrupt_count)))
|
||||
{
|
||||
virtio_log_error (vif, "error encountered on pci enable msix irq");
|
||||
goto error;
|
||||
@ -1277,7 +1321,7 @@ virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
|
||||
vif->support_int_mode = 1;
|
||||
virtio_log_debug (vif, "device supports msix interrupts");
|
||||
}
|
||||
else if (vlib_pci_get_num_msix_interrupts (vm, h) == 1)
|
||||
else if (interrupt_count == 1)
|
||||
{
|
||||
/*
|
||||
* if msix table-size is 1, fall back to intX.
|
||||
|
@ -168,6 +168,7 @@ typedef struct
|
||||
u16 max_queue_pairs;
|
||||
u16 num_rxqs;
|
||||
u16 num_txqs;
|
||||
u16 msix_table_size;
|
||||
u8 status;
|
||||
u8 mac_addr[6];
|
||||
u8 *host_if_name;
|
||||
|
Reference in New Issue
Block a user