virtio: fix the interrupt
[vpp.git] / src / vnet / devices / virtio / virtio.c
index e84490b..b8054d1 100644 (file)
@@ -30,6 +30,7 @@
 #include <vnet/ip/ip4_packet.h>
 #include <vnet/ip/ip6_packet.h>
 #include <vnet/devices/virtio/virtio.h>
+#include <vnet/devices/virtio/virtio_inline.h>
 #include <vnet/devices/virtio/pci.h>
 #include <vnet/interface/rx_queue_funcs.h>
 
@@ -109,10 +110,13 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz)
   if (idx & 1)
     {
       clib_memset_u32 (vring->buffers, ~0, sz);
+      // tx path: suppress the interrupts from kernel
+      vring->call_fd = -1;
     }
+  else
+    vring->call_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
 
   vring->size = sz;
-  vring->call_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
   vring->kick_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
   virtio_log_debug (vif, "vring %u size %u call_fd %d kick_fd %d", idx,
                    vring->size, vring->call_fd, vring->kick_fd);
@@ -163,9 +167,7 @@ virtio_vring_free_tx (vlib_main_t * vm, virtio_if_t * vif, u32 idx)
   virtio_vring_t *vring =
     vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (idx));
 
-  clib_file_del_by_index (&file_main, vring->call_file_index);
   close (vring->kick_fd);
-  close (vring->call_fd);
   if (vring->used)
     {
       virtio_free_buffers (vm, vring);
@@ -219,11 +221,25 @@ virtio_set_packet_buffering (virtio_if_t * vif, u16 buffering_size)
   return error;
 }
 
+static void
+virtio_vring_fill (vlib_main_t *vm, virtio_if_t *vif, virtio_vring_t *vring)
+{
+  if (vif->is_packed)
+    virtio_refill_vring_packed (vm, vif, vif->type, vring,
+                               vif->virtio_net_hdr_sz,
+                               virtio_input_node.index);
+  else
+    virtio_refill_vring_split (vm, vif, vif->type, vring,
+                              vif->virtio_net_hdr_sz,
+                              virtio_input_node.index);
+}
+
 void
 virtio_vring_set_rx_queues (vlib_main_t *vm, virtio_if_t *vif)
 {
   vnet_main_t *vnm = vnet_get_main ();
   virtio_vring_t *vring;
+  u32 i = 0;
 
   vnet_hw_if_set_input_node (vnm, vif->hw_if_index, virtio_input_node.index);
 
@@ -250,6 +266,20 @@ virtio_vring_set_rx_queues (vlib_main_t *vm, virtio_if_t *vif)
          vnet_hw_if_set_rx_queue_file_index (vnm, vring->queue_index,
                                              vring->call_file_index);
        }
+      else if ((vif->type == VIRTIO_IF_TYPE_PCI) && (vif->support_int_mode) &&
+              (vif->msix_enabled == VIRTIO_MSIX_ENABLED))
+       {
+         u32 file_index;
+         file_index =
+           vlib_pci_get_msix_file_index (vm, vif->pci_dev_handle, i + 1);
+         vnet_hw_if_set_rx_queue_file_index (vnm, vring->queue_index,
+                                             file_index);
+         i++;
+       }
+      vnet_hw_if_set_rx_queue_mode (vnm, vring->queue_index,
+                                   VNET_HW_IF_RX_MODE_POLLING);
+      vring->mode = VNET_HW_IF_RX_MODE_POLLING;
+      virtio_vring_fill (vm, vif, vring);
     }
   vnet_hw_if_update_runtime_data (vnm, vif->hw_if_index);
 }