interface: rx queue infra rework, part one

Type: improvement
Change-Id: I4008cadfd5141f921afbdc09a3ebcd1dcf88eb29
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vnet/devices/devices.h b/src/vnet/devices/devices.h
index 917c872..02eb5cf 100644
--- a/src/vnet/devices/devices.h
+++ b/src/vnet/devices/devices.h
@@ -68,6 +68,7 @@
 {
   vnet_device_and_queue_t *devices_and_queues;
   vlib_node_state_t enabled_node_state;
+  u32 pad;
 } vnet_device_input_runtime_t;
 
 extern vnet_device_main_t vnet_device_main;
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index 11c2480..7e7d3d5 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -739,16 +739,8 @@
     {
       virtio_set_packet_coalesce (vif);
     }
-  vnet_hw_interface_set_input_node (vnm, vif->hw_if_index,
-				    virtio_input_node.index);
 
-  for (i = 0; i < vif->num_rxqs; i++)
-    {
-      vnet_hw_interface_assign_rx_thread (vnm, vif->hw_if_index, i, ~0);
-      vnet_hw_interface_set_rx_mode (vnm, vif->hw_if_index, i,
-				     VNET_HW_IF_RX_MODE_DEFAULT);
-      virtio_vring_set_numa_node (vm, vif, RX_QUEUE (i));
-    }
+  virtio_vring_set_rx_queues (vm, vif);
 
   vif->per_interface_next_index = ~0;
   vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
@@ -788,7 +780,6 @@
 {
   vnet_main_t *vnm = vnet_get_main ();
   virtio_main_t *mm = &virtio_main;
-  int i;
   virtio_if_t *vif;
   vnet_hw_interface_t *hw;
 
@@ -804,8 +795,6 @@
   /* bring down the interface */
   vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
   vnet_sw_interface_set_flags (vnm, vif->sw_if_index, 0);
-  for (i = 0; i < vif->num_rxqs; i++)
-    vnet_hw_interface_unassign_rx_thread (vnm, vif->hw_if_index, i);
 
   if (vif->type == VIRTIO_IF_TYPE_TAP)
     ethernet_delete_interface (vnm, vif->hw_if_index);
diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c
index 1e75ca4..788cc61 100644
--- a/src/vnet/devices/virtio/node.c
+++ b/src/vnet/devices/virtio/node.c
@@ -26,15 +26,14 @@
 #include <vlib/vlib.h>
 #include <vlib/unix/unix.h>
 #include <vnet/ethernet/ethernet.h>
-#include <vnet/devices/devices.h>
 #include <vnet/feature/feature.h>
 #include <vnet/gso/gro_func.h>
+#include <vnet/interface/rx_queue_funcs.h>
 #include <vnet/ip/ip4_packet.h>
 #include <vnet/ip/ip6_packet.h>
 #include <vnet/udp/udp_packet.h>
 #include <vnet/devices/virtio/virtio.h>
 
-
 #define foreach_virtio_input_error \
   _(BUFFER_ALLOC, "buffer alloc error") \
   _(UNKNOWN, "unknown")
@@ -638,30 +637,27 @@
 				  vlib_frame_t * frame)
 {
   u32 n_rx = 0;
-  virtio_main_t *nm = &virtio_main;
-  vnet_device_input_runtime_t *rt = (void *) node->runtime_data;
-  vnet_device_and_queue_t *dq;
+  virtio_main_t *vim = &virtio_main;
+  vnet_hw_if_rxq_poll_vector_t *p,
+    *pv = vnet_hw_if_get_rxq_poll_vector (vm, node);
 
-  foreach_device_and_queue (dq, rt->devices_and_queues)
-  {
-    virtio_if_t *vif;
-    vif = vec_elt_at_index (nm->interfaces, dq->dev_instance);
-    if (vif->flags & VIRTIO_IF_FLAG_ADMIN_UP)
-      {
-	if (vif->type == VIRTIO_IF_TYPE_TAP)
-	  n_rx += virtio_device_input_inline (vm, node, frame, vif,
-					      dq->queue_id,
-					      VIRTIO_IF_TYPE_TAP);
-	else if (vif->type == VIRTIO_IF_TYPE_PCI)
-	  n_rx += virtio_device_input_inline (vm, node, frame, vif,
-					      dq->queue_id,
-					      VIRTIO_IF_TYPE_PCI);
-	else if (vif->type == VIRTIO_IF_TYPE_TUN)
-	  n_rx += virtio_device_input_inline (vm, node, frame, vif,
-					      dq->queue_id,
-					      VIRTIO_IF_TYPE_TUN);
-      }
-  }
+  vec_foreach (p, pv)
+    {
+      virtio_if_t *vif;
+      vif = vec_elt_at_index (vim->interfaces, p->dev_instance);
+      if (vif->flags & VIRTIO_IF_FLAG_ADMIN_UP)
+	{
+	  if (vif->type == VIRTIO_IF_TYPE_TAP)
+	    n_rx += virtio_device_input_inline (
+	      vm, node, frame, vif, p->queue_id, VIRTIO_IF_TYPE_TAP);
+	  else if (vif->type == VIRTIO_IF_TYPE_PCI)
+	    n_rx += virtio_device_input_inline (
+	      vm, node, frame, vif, p->queue_id, VIRTIO_IF_TYPE_PCI);
+	  else if (vif->type == VIRTIO_IF_TYPE_TUN)
+	    n_rx += virtio_device_input_inline (
+	      vm, node, frame, vif, p->queue_id, VIRTIO_IF_TYPE_TUN);
+	}
+    }
 
   return n_rx;
 }
diff --git a/src/vnet/devices/virtio/pci.c b/src/vnet/devices/virtio/pci.c
index 93ea70b..908aba7 100644
--- a/src/vnet/devices/virtio/pci.c
+++ b/src/vnet/devices/virtio/pci.c
@@ -24,6 +24,7 @@
 #include <vnet/ip/ip6_packet.h>
 #include <vnet/devices/virtio/virtio.h>
 #include <vnet/devices/virtio/pci.h>
+#include <vnet/interface/rx_queue_funcs.h>
 
 #define PCI_VENDOR_ID_VIRTIO				0x1af4
 #define PCI_DEVICE_ID_VIRTIO_NIC			0x1000
@@ -115,7 +116,8 @@
   line--;
   u16 qid = line;
 
-  vnet_device_input_set_interrupt_pending (vnm, vif->hw_if_index, qid);
+  virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, qid);
+  vnet_hw_if_rx_queue_set_int_pending (vnm, vring->queue_index);
 }
 
 static void
@@ -1519,17 +1521,8 @@
 	}
     }
 
-  vnet_hw_interface_set_input_node (vnm, vif->hw_if_index,
-				    virtio_input_node.index);
-  u32 i = 0;
-  vec_foreach_index (i, vif->rxq_vrings)
-  {
-    vnet_hw_interface_assign_rx_thread (vnm, vif->hw_if_index, i, ~0);
-    virtio_vring_set_numa_node (vm, vif, RX_QUEUE (i));
-    /* Set default rx mode to POLLING */
-    vnet_hw_interface_set_rx_mode (vnm, vif->hw_if_index, i,
-				   VNET_HW_IF_RX_MODE_POLLING);
-  }
+  virtio_vring_set_rx_queues (vm, vif);
+
   if (virtio_pci_is_link_up (vm, vif) & VIRTIO_NET_S_LINK_UP)
     {
       vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
@@ -1584,10 +1577,6 @@
   if (vif->hw_if_index)
     {
       vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
-      vec_foreach_index (i, vif->rxq_vrings)
-      {
-	vnet_hw_interface_unassign_rx_thread (vnm, vif->hw_if_index, i);
-      }
       ethernet_delete_interface (vnm, vif->hw_if_index);
     }
 
diff --git a/src/vnet/devices/virtio/vhost_user.c b/src/vnet/devices/virtio/vhost_user.c
index daa1260..b45b18b 100644
--- a/src/vnet/devices/virtio/vhost_user.c
+++ b/src/vnet/devices/virtio/vhost_user.c
@@ -36,6 +36,7 @@
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/devices/devices.h>
 #include <vnet/feature/feature.h>
+#include <vnet/interface/rx_queue_funcs.h>
 
 #include <vnet/devices/virtio/vhost_user.h>
 #include <vnet/devices/virtio/vhost_user_inline.h>
@@ -165,17 +166,19 @@
 
   ASSERT ((qid & 1) == 1);	// should be odd
   // Assign new queue mappings for the interface
-  vnet_hw_interface_set_input_node (vnm, vui->hw_if_index,
-				    vhost_user_input_node.index);
-  vnet_hw_interface_assign_rx_thread (vnm, vui->hw_if_index, q, ~0);
+  vnet_hw_if_set_input_node (vnm, vui->hw_if_index,
+			     vhost_user_input_node.index);
+  txvq->queue_index = vnet_hw_if_register_rx_queue (vnm, vui->hw_if_index, q,
+						    VNET_HW_IF_RXQ_THREAD_ANY);
   if (txvq->mode == VNET_HW_IF_RX_MODE_UNKNOWN)
     /* Set polling as the default */
     txvq->mode = VNET_HW_IF_RX_MODE_POLLING;
   txvq->qid = q;
-  rv = vnet_hw_interface_set_rx_mode (vnm, vui->hw_if_index, q, txvq->mode);
+  rv = vnet_hw_if_set_rx_queue_mode (vnm, txvq->queue_index, txvq->mode);
   if (rv)
     vu_log_warn (vui, "unable to set rx mode for interface %d, "
 		 "queue %d: rc=%d", vui->hw_if_index, q, rv);
+  vnet_hw_if_update_runtime_data (vnm, vui->hw_if_index);
 }
 
 /** @brief Returns whether at least one TX and one RX vring are enabled */
@@ -213,15 +216,20 @@
 {
   u32 qid;
   vnet_main_t *vnm = vnet_get_main ();
+  vhost_user_vring_t *txvq;
 
   qid = ifq & 0xff;
   if ((qid & 1) == 0)
     /* Only care about the odd number, or TX, virtqueue */
     return;
 
-  if (vhost_user_intf_ready (vui))
-    // qid >> 1 is to convert virtqueue number to vring queue index
-    vnet_device_input_set_interrupt_pending (vnm, vui->hw_if_index, qid >> 1);
+  // qid >> 1 is to convert virtqueue number to vring queue index
+  qid >>= 1;
+  txvq = &vui->vrings[VHOST_VRING_IDX_TX (qid)];
+  if (vhost_user_intf_ready (vui) &&
+      ((txvq->mode == VNET_HW_IF_RX_MODE_ADAPTIVE) ||
+       (txvq->mode == VNET_HW_IF_RX_MODE_INTERRUPT)))
+    vnet_hw_if_rx_queue_set_int_pending (vnm, txvq->queue_index);
 }
 
 static clib_error_t *
@@ -1370,24 +1378,6 @@
 
   for (q = 0; q < vui->num_qid; q++)
     {
-      // Remove existing queue mapping for the interface
-      if (q & 1)
-	{
-	  int rv;
-	  vnet_main_t *vnm = vnet_get_main ();
-	  vhost_user_vring_t *txvq = &vui->vrings[q];
-
-	  if (txvq->qid != -1)
-	    {
-	      rv = vnet_hw_interface_unassign_rx_thread (vnm,
-							 vui->hw_if_index,
-							 q >> 1);
-	      if (rv)
-		vu_log_warn (vui, "unable to unassign interface %d, "
-			     "queue %d: rc=%d", vui->hw_if_index, q >> 1, rv);
-	    }
-	}
-
       clib_spinlock_free (&vui->vrings[q].vring_lock);
     }
 
@@ -2224,19 +2214,14 @@
 	{
 	  vnet_main_t *vnm = vnet_get_main ();
 	  uword thread_index;
-	  vnet_hw_if_rx_mode mode;
 	  vhost_user_vring_t *txvq = &vui->vrings[qid];
 
 	  if (txvq->qid == -1)
 	    continue;
 	  thread_index =
-	    vnet_get_device_input_thread_index (vnm, vui->hw_if_index,
-						qid >> 1);
-	  vnet_hw_interface_get_rx_mode (vnm, vui->hw_if_index, qid >> 1,
-					 &mode);
-	  vlib_cli_output (vm, "   thread %d on vring %d, %U\n",
-			   thread_index, qid,
-			   format_vnet_hw_if_rx_mode, mode);
+	    vnet_hw_if_get_rx_queue_thread_index (vnm, txvq->queue_index);
+	  vlib_cli_output (vm, "   thread %d on vring %d, %U\n", thread_index,
+			   qid, format_vnet_hw_if_rx_mode, txvq->mode);
 	}
 
       vlib_cli_output (vm, " tx placement: %s\n",
diff --git a/src/vnet/devices/virtio/vhost_user.h b/src/vnet/devices/virtio/vhost_user.h
index 604e557..06c78bc 100644
--- a/src/vnet/devices/virtio/vhost_user.h
+++ b/src/vnet/devices/virtio/vhost_user.h
@@ -227,9 +227,9 @@
 
   u16 used_wrap_counter;
   u16 avail_wrap_counter;
-
   u16 last_kick;
   u8 first_kick;
+  u32 queue_index;
 } vhost_user_vring_t;
 
 #define VHOST_USER_EVENT_START_TIMER 1
diff --git a/src/vnet/devices/virtio/vhost_user_input.c b/src/vnet/devices/virtio/vhost_user_input.c
index 7ea70c6..62b59f6 100644
--- a/src/vnet/devices/virtio/vhost_user_input.c
+++ b/src/vnet/devices/virtio/vhost_user_input.c
@@ -37,6 +37,7 @@
 #include <vnet/devices/devices.h>
 #include <vnet/feature/feature.h>
 #include <vnet/udp/udp_packet.h>
+#include <vnet/interface/rx_queue_funcs.h>
 
 #include <vnet/devices/virtio/vhost_user.h>
 #include <vnet/devices/virtio/vhost_user_inline.h>
@@ -372,11 +373,9 @@
 }
 
 static_always_inline u32
-vhost_user_if_input (vlib_main_t * vm,
-		     vhost_user_main_t * vum,
-		     vhost_user_intf_t * vui,
-		     u16 qid, vlib_node_runtime_t * node,
-		     vnet_hw_if_rx_mode mode, u8 enable_csum)
+vhost_user_if_input (vlib_main_t *vm, vhost_user_main_t *vum,
+		     vhost_user_intf_t *vui, u16 qid,
+		     vlib_node_runtime_t *node, u8 enable_csum)
 {
   vhost_user_vring_t *txvq = &vui->vrings[VHOST_VRING_IDX_TX (qid)];
   vnet_feature_main_t *fm = &feature_main;
@@ -411,7 +410,7 @@
    * When the traffic subsides, the scheduler switches the node back to
    * interrupt mode. We must tell the driver we want interrupt.
    */
-  if (PREDICT_FALSE (mode == VNET_HW_IF_RX_MODE_ADAPTIVE))
+  if (PREDICT_FALSE (txvq->mode == VNET_HW_IF_RX_MODE_ADAPTIVE))
     {
       if ((node->flags &
 	   VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE) ||
@@ -1081,10 +1080,9 @@
 }
 
 static_always_inline u32
-vhost_user_if_input_packed (vlib_main_t * vm, vhost_user_main_t * vum,
-			    vhost_user_intf_t * vui, u16 qid,
-			    vlib_node_runtime_t * node,
-			    vnet_hw_if_rx_mode mode, u8 enable_csum)
+vhost_user_if_input_packed (vlib_main_t *vm, vhost_user_main_t *vum,
+			    vhost_user_intf_t *vui, u16 qid,
+			    vlib_node_runtime_t *node, u8 enable_csum)
 {
   vhost_user_vring_t *txvq = &vui->vrings[VHOST_VRING_IDX_TX (qid)];
   vnet_feature_main_t *fm = &feature_main;
@@ -1126,7 +1124,7 @@
    * When the traffic subsides, the scheduler switches the node back to
    * interrupt mode. We must tell the driver we want interrupt.
    */
-  if (PREDICT_FALSE (mode == VNET_HW_IF_RX_MODE_ADAPTIVE))
+  if (PREDICT_FALSE (txvq->mode == VNET_HW_IF_RX_MODE_ADAPTIVE))
     {
       if ((node->flags &
 	   VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE) ||
@@ -1415,39 +1413,31 @@
   vhost_user_main_t *vum = &vhost_user_main;
   uword n_rx_packets = 0;
   vhost_user_intf_t *vui;
-  vnet_device_input_runtime_t *rt =
-    (vnet_device_input_runtime_t *) node->runtime_data;
-  vnet_device_and_queue_t *dq;
+  vnet_hw_if_rxq_poll_vector_t *pv = vnet_hw_if_get_rxq_poll_vector (vm, node);
+  vnet_hw_if_rxq_poll_vector_t *pve;
 
-  vec_foreach (dq, rt->devices_and_queues)
-  {
-    if ((node->state == VLIB_NODE_STATE_POLLING) ||
-	clib_atomic_swap_acq_n (&dq->interrupt_pending, 0))
-      {
-	vui =
-	  pool_elt_at_index (vum->vhost_user_interfaces, dq->dev_instance);
-	if (vhost_user_is_packed_ring_supported (vui))
-	  {
-	    if (vui->features & VIRTIO_FEATURE (VIRTIO_NET_F_CSUM))
-	      n_rx_packets += vhost_user_if_input_packed (vm, vum, vui,
-							  dq->queue_id, node,
-							  dq->mode, 1);
-	    else
-	      n_rx_packets += vhost_user_if_input_packed (vm, vum, vui,
-							  dq->queue_id, node,
-							  dq->mode, 0);
-	  }
-	else
-	  {
-	    if (vui->features & VIRTIO_FEATURE (VIRTIO_NET_F_CSUM))
-	      n_rx_packets += vhost_user_if_input (vm, vum, vui, dq->queue_id,
-						   node, dq->mode, 1);
-	    else
-	      n_rx_packets += vhost_user_if_input (vm, vum, vui, dq->queue_id,
-						   node, dq->mode, 0);
-	  }
-      }
-  }
+  vec_foreach (pve, pv)
+    {
+      vui = pool_elt_at_index (vum->vhost_user_interfaces, pve->dev_instance);
+      if (vhost_user_is_packed_ring_supported (vui))
+	{
+	  if (vui->features & VIRTIO_FEATURE (VIRTIO_NET_F_CSUM))
+	    n_rx_packets += vhost_user_if_input_packed (
+	      vm, vum, vui, pve->queue_id, node, 1);
+	  else
+	    n_rx_packets += vhost_user_if_input_packed (
+	      vm, vum, vui, pve->queue_id, node, 0);
+	}
+      else
+	{
+	  if (vui->features & VIRTIO_FEATURE (VIRTIO_NET_F_CSUM))
+	    n_rx_packets +=
+	      vhost_user_if_input (vm, vum, vui, pve->queue_id, node, 1);
+	  else
+	    n_rx_packets +=
+	      vhost_user_if_input (vm, vum, vui, pve->queue_id, node, 0);
+	}
+    }
 
   return n_rx_packets;
 }
diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c
index 99f581a..e84490b 100644
--- a/src/vnet/devices/virtio/virtio.c
+++ b/src/vnet/devices/virtio/virtio.c
@@ -31,6 +31,7 @@
 #include <vnet/ip/ip6_packet.h>
 #include <vnet/devices/virtio/virtio.h>
 #include <vnet/devices/virtio/pci.h>
+#include <vnet/interface/rx_queue_funcs.h>
 
 virtio_main_t virtio_main;
 
@@ -44,17 +45,11 @@
 static clib_error_t *
 call_read_ready (clib_file_t * uf)
 {
-  virtio_main_t *nm = &virtio_main;
   vnet_main_t *vnm = vnet_get_main ();
-  u16 qid = uf->private_data & 0xFFFF;
-  virtio_if_t *vif =
-    vec_elt_at_index (nm->interfaces, uf->private_data >> 16);
   u64 b;
 
   CLIB_UNUSED (ssize_t size) = read (uf->file_descriptor, &b, sizeof (b));
-  if ((qid & 1) == 0)
-    vnet_device_input_set_interrupt_pending (vnm, vif->hw_if_index,
-					     RX_QUEUE_ACCESS (qid));
+  vnet_hw_if_rx_queue_set_int_pending (vnm, uf->private_data);
 
   return 0;
 }
@@ -64,7 +59,6 @@
 virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz)
 {
   virtio_vring_t *vring;
-  clib_file_t t = { 0 };
   int i;
 
   if (!is_pow2 (sz))
@@ -123,13 +117,6 @@
   virtio_log_debug (vif, "vring %u size %u call_fd %d kick_fd %d", idx,
 		    vring->size, vring->call_fd, vring->kick_fd);
 
-  t.read_function = call_read_ready;
-  t.file_descriptor = vring->call_fd;
-  t.private_data = vif->dev_instance << 16 | idx;
-  t.description = format (0, "%U vring %u", format_virtio_device_name,
-			  vif->dev_instance, idx);
-  vring->call_file_index = clib_file_add (&file_main, &t);
-
   return 0;
 }
 
@@ -233,19 +220,38 @@
 }
 
 void
-virtio_vring_set_numa_node (vlib_main_t * vm, virtio_if_t * vif, u32 idx)
+virtio_vring_set_rx_queues (vlib_main_t *vm, virtio_if_t *vif)
 {
   vnet_main_t *vnm = vnet_get_main ();
-  u32 thread_index;
-  virtio_vring_t *vring =
-    vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS (idx));
-  thread_index =
-    vnet_get_device_input_thread_index (vnm, vif->hw_if_index,
-					RX_QUEUE_ACCESS (idx));
-  vring->buffer_pool_index =
-    vlib_buffer_pool_get_default_for_numa (vm,
-					   vlib_mains
-					   [thread_index]->numa_node);
+  virtio_vring_t *vring;
+
+  vnet_hw_if_set_input_node (vnm, vif->hw_if_index, virtio_input_node.index);
+
+  vec_foreach (vring, vif->rxq_vrings)
+    {
+      vring->queue_index = vnet_hw_if_register_rx_queue (
+	vnm, vif->hw_if_index, RX_QUEUE_ACCESS (vring->queue_id),
+	VNET_HW_IF_RXQ_THREAD_ANY);
+      vring->buffer_pool_index = vlib_buffer_pool_get_default_for_numa (
+	vm, vnet_hw_if_get_rx_queue_numa_node (vnm, vring->queue_index));
+      if (vif->type == VIRTIO_IF_TYPE_TAP || vif->type == VIRTIO_IF_TYPE_TUN)
+	{
+
+	  clib_file_t f = {
+	    .read_function = call_read_ready,
+	    .flags = UNIX_FILE_EVENT_EDGE_TRIGGERED,
+	    .file_descriptor = vring->call_fd,
+	    .private_data = vring->queue_index,
+	    .description = format (0, "%U vring %u", format_virtio_device_name,
+				   vif->dev_instance, vring->queue_id),
+	  };
+
+	  vring->call_file_index = clib_file_add (&file_main, &f);
+	  vnet_hw_if_set_rx_queue_file_index (vnm, vring->queue_index,
+					      vring->call_file_index);
+	}
+    }
+  vnet_hw_if_update_runtime_data (vnm, vif->hw_if_index);
 }
 
 inline void
diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h
index 035dc9c..c149ce4 100644
--- a/src/vnet/devices/virtio/virtio.h
+++ b/src/vnet/devices/virtio/virtio.h
@@ -82,6 +82,7 @@
   u32 *buffers;
   u16 size;
   u16 queue_id;
+  u32 queue_index;
   u16 desc_in_use;
   u16 desc_next;
   u16 last_used_idx;
@@ -230,8 +231,7 @@
 				    u32 idx);
 clib_error_t *virtio_vring_free_tx (vlib_main_t * vm, virtio_if_t * vif,
 				    u32 idx);
-void virtio_vring_set_numa_node (vlib_main_t * vm, virtio_if_t * vif,
-				 u32 idx);
+void virtio_vring_set_rx_queues (vlib_main_t *vm, virtio_if_t *vif);
 extern void virtio_free_buffers (vlib_main_t * vm, virtio_vring_t * vring);
 extern void virtio_set_net_hdr_size (virtio_if_t * vif);
 extern void virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr,
diff --git a/src/vnet/devices/virtio/virtio_process.c b/src/vnet/devices/virtio/virtio_process.c
index 1689459..f347ef2 100644
--- a/src/vnet/devices/virtio/virtio_process.c
+++ b/src/vnet/devices/virtio/virtio_process.c
@@ -18,6 +18,7 @@
 #include <vlib/vlib.h>
 #include <vnet/devices/virtio/virtio.h>
 #include <vnet/gso/gro_func.h>
+#include <vnet/interface/rx_queue_funcs.h>
 
 static uword
 virtio_send_interrupt_process (vlib_main_t * vm,
@@ -45,22 +46,20 @@
 	  break;
 
 	case ~0:
-          /* *INDENT-OFF* */
-          pool_foreach (vif, vim->interfaces) {
-              if (vif->packet_coalesce || vif->packet_buffering)
-                {
-                  virtio_vring_t *vring;
-                  vec_foreach (vring, vif->rxq_vrings)
-                  {
-                    if (vring->mode == VNET_HW_IF_RX_MODE_INTERRUPT ||
-                        vring->mode == VNET_HW_IF_RX_MODE_ADAPTIVE)
-                      vnet_device_input_set_interrupt_pending (
-                                             vnet_get_main (), vif->hw_if_index,
-                                             RX_QUEUE_ACCESS (vring->queue_id));
-                  }
-                }
-          }
-          /* *INDENT-ON* */
+	  pool_foreach (vif, vim->interfaces)
+	    {
+	      if (vif->packet_coalesce || vif->packet_buffering)
+		{
+		  virtio_vring_t *vring;
+		  vec_foreach (vring, vif->rxq_vrings)
+		    {
+		      if (vring->mode == VNET_HW_IF_RX_MODE_INTERRUPT ||
+			  vring->mode == VNET_HW_IF_RX_MODE_ADAPTIVE)
+			vnet_hw_if_rx_queue_set_int_pending (
+			  vnet_get_main (), vring->queue_index);
+		    }
+		}
+	    }
 	  break;
 
 	default: