virtio: fix the tx queue thread binding

Type: fix

Change-Id: Ibbe7e20aebc9153ceba07e048dc0eaa45193f4ea
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
diff --git a/src/vnet/devices/virtio/pci.c b/src/vnet/devices/virtio/pci.c
index 925c6f5..ab21147 100644
--- a/src/vnet/devices/virtio/pci.c
+++ b/src/vnet/devices/virtio/pci.c
@@ -657,7 +657,6 @@
 virtio_pci_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 queue_num)
 {
   clib_error_t *error = 0;
-  vlib_thread_main_t *vtm = vlib_get_thread_main ();
   u16 queue_size = 0;
   virtio_vring_t *vring;
   struct vring vr;
@@ -679,8 +678,6 @@
 
   if (queue_num % 2)
     {
-      if (TX_QUEUE_ACCESS (queue_num) > vtm->n_vlib_mains)
-	return error;
       vec_validate_aligned (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num),
 			    CLIB_CACHE_LINE_BYTES);
       vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num));
@@ -918,6 +915,7 @@
 			virtio_pci_create_if_args_t * args)
 {
   clib_error_t *error = 0;
+  vlib_thread_main_t *vtm = vlib_get_thread_main ();
   u8 status = 0;
 
   if ((error = virtio_pci_read_caps (vm, vif)))
@@ -983,6 +981,22 @@
 	  vif->num_rxqs++;
 	}
 
+      if (i >= vtm->n_vlib_mains)
+	{
+	  /*
+	   * There is 1:1 mapping between tx queue and vpp worker thread.
+	   * tx queue 0 is bind with thread index 0, tx queue 1 on thread
+	   * index 1 and so on.
+	   * Multiple worker threads can poll same tx queue when number of
+	   * workers are more than tx queues. In this case, 1:N mapping
+	   * between tx queue and vpp worker thread.
+	   */
+	  virtio_log_debug (vif, "%s %u, %s", "tx-queue: number",
+			    TX_QUEUE (i),
+			    "no VPP worker thread is available");
+	  continue;
+	}
+
       if ((error = virtio_pci_vring_init (vm, vif, TX_QUEUE (i))))
 	{
 	  virtio_log_warning (vif, "%s (%u) %s", "error in txq-queue",