interface: add tx-queue cli support for new tx infra 30/32430/5
authorMohsin Kazmi <sykazmi@cisco.com>
Mon, 24 May 2021 16:33:50 +0000 (18:33 +0200)
committerDamjan Marion <dmarion@me.com>
Thu, 27 May 2021 12:53:02 +0000 (12:53 +0000)
Type: improvement

set interface tx-queue tap1 queue 2 threads 1-2
show hardware-interfaces tap1
              Name                Idx   Link  Hardware
tap1                               2     up   tap1
  Link speed: unknown
  RX Queues:
    queue thread         mode
    0     vpp_wk_1 (2)   polling
  TX Queues:
    queue shared thread(s)
    0     no     0
    1     no     1
    2     yes    1-2
    3     no     3
    4     no     4
  Ethernet address 02:fe:09:3a:48:ff
  VIRTIO interface
     instance 1

set interface tx-queue tap0 queue 4 threads
show hardware-interfaces tap0
              Name                Idx   Link  Hardware
tap0                               1     up   tap0
  Link speed: unknown
  RX Queues:
    queue thread         mode
    0     vpp_wk_0 (1)   polling
  TX Queues:
    queue shared thread(s)
    0     no     0
    1     no     1
    2     no     2
    3     no     3
    4     no
  Ethernet address 02:fe:03:6a:66:fc
  VIRTIO interface
     instance 0

Change-Id: I6154476ec9ff0b14287098529c88a14b779371a5
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
src/vnet/interface/runtime.c
src/vnet/interface/tx_queue.c
src/vnet/interface_cli.c

index e899d7a..462f7bb 100644 (file)
@@ -196,7 +196,6 @@ vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index)
              something_changed_on_tx = 1;
              rt->frame.queue_id = txq->queue_id;
              rt->frame.shared_queue = txq->shared_queue;
-             rt->frame.shared_queue = n_threads > 1 ? 1 : 0;
              rt->n_threads = n_threads;
            }
        }
index 3041a58..8a6cd9d 100644 (file)
@@ -112,8 +112,12 @@ vnet_hw_if_tx_queue_assign_thread (vnet_main_t *vnm, u32 queue_index,
   vnet_hw_if_tx_queue_t *txq = vnet_hw_if_get_tx_queue (vnm, queue_index);
   vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, txq->hw_if_index);
   txq->threads = clib_bitmap_set (txq->threads, thread_index, 1);
-  log_debug ("assign_thread: interface %v queue-id %u thread %u", hi->name,
-            txq->queue_id, thread_index);
+  if (clib_bitmap_count_set_bits (txq->threads) > 1)
+    txq->shared_queue = 1;
+  log_debug (
+    "assign_thread: interface %v queue-id %u thread %u queue-shared %s",
+    hi->name, txq->queue_id, thread_index,
+    (txq->shared_queue == 1 ? "yes" : "no"));
 }
 
 void
@@ -123,6 +127,10 @@ vnet_hw_if_tx_queue_unassign_thread (vnet_main_t *vnm, u32 queue_index,
   vnet_hw_if_tx_queue_t *txq = vnet_hw_if_get_tx_queue (vnm, queue_index);
   vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, txq->hw_if_index);
   txq->threads = clib_bitmap_set (txq->threads, thread_index, 0);
-  log_debug ("unassign_thread: interface %v queue-id %u thread %u", hi->name,
-            txq->queue_id, thread_index);
+  if (clib_bitmap_count_set_bits (txq->threads) < 2)
+    txq->shared_queue = 0;
+  log_debug (
+    "unassign_thread: interface %v queue-id %u thread %u queue-shared %s",
+    hi->name, txq->queue_id, thread_index,
+    (txq->shared_queue == 1 ? "yes" : "no"));
 }
index 6dadbb8..e5d0ab2 100644 (file)
@@ -52,6 +52,7 @@
 #include <vnet/l2/l2_input.h>
 #include <vnet/classify/vnet_classify.h>
 #include <vnet/interface/rx_queue_funcs.h>
+#include <vnet/interface/tx_queue_funcs.h>
 static int
 compare_interface_names (void *a1, void *a2)
 {
@@ -1808,6 +1809,102 @@ VLIB_CLI_COMMAND (cmd_set_if_rx_placement,static) = {
 };
 /* *INDENT-ON* */
 
+clib_error_t *
+set_hw_interface_tx_queue (u32 hw_if_index, u32 queue_id, uword *bitmap)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  vnet_device_main_t *vdm = &vnet_device_main;
+  vnet_hw_interface_t *hw;
+  vnet_hw_if_tx_queue_t *txq;
+  u32 queue_index;
+  u32 thread_index;
+
+  hw = vnet_get_hw_interface (vnm, hw_if_index);
+
+  /* highest set bit in bitmap should not exceed last worker thread index */
+  thread_index =
+    clib_bitmap_last_set (bitmap) + vdm->first_worker_thread_index;
+  if (thread_index > vdm->last_worker_thread_index)
+    return clib_error_return (0, "please specify valid thread(s)");
+
+  queue_index =
+    vnet_hw_if_get_tx_queue_index_by_id (vnm, hw_if_index, queue_id);
+  if (queue_index == ~0)
+    return clib_error_return (0, "unknown queue %u on interface %s", queue_id,
+                             hw->name);
+
+  txq = vnet_hw_if_get_tx_queue (vnm, queue_index);
+
+  // free the existing bitmap
+  if (clib_bitmap_count_set_bits (txq->threads))
+    {
+      txq->shared_queue = 0;
+      clib_bitmap_free (txq->threads);
+    }
+
+  clib_bitmap_foreach (thread_index, bitmap)
+    vnet_hw_if_tx_queue_assign_thread (vnm, queue_index, thread_index);
+
+  vnet_hw_if_update_runtime_data (vnm, hw_if_index);
+  return 0;
+}
+
+static clib_error_t *
+set_interface_tx_queue (vlib_main_t *vm, unformat_input_t *input,
+                       vlib_cli_command_t *cmd)
+{
+  clib_error_t *error = 0;
+  unformat_input_t _line_input, *line_input = &_line_input;
+  vnet_main_t *vnm = vnet_get_main ();
+  u32 hw_if_index = (u32) ~0;
+  u32 queue_id = (u32) 0;
+  uword *bitmap = 0;
+
+  if (!unformat_user (input, unformat_line_input, line_input))
+    return 0;
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "%U", unformat_vnet_hw_interface, vnm,
+                   &hw_if_index))
+       ;
+      else if (unformat (line_input, "queue %d", &queue_id))
+       ;
+      else if (unformat (line_input, "threads %U", unformat_bitmap_list,
+                        &bitmap))
+       ;
+      else
+       {
+         error = clib_error_return (0, "parse error: '%U'",
+                                    format_unformat_error, line_input);
+         unformat_free (line_input);
+         return error;
+       }
+    }
+
+  unformat_free (line_input);
+
+  if (hw_if_index == (u32) ~0)
+    {
+      error = clib_error_return (0, "please specify valid interface name");
+      goto error;
+    }
+
+  error = set_hw_interface_tx_queue (hw_if_index, queue_id, bitmap);
+
+error:
+  clib_bitmap_free (bitmap);
+  return (error);
+}
+
+VLIB_CLI_COMMAND (cmd_set_if_tx_queue, static) = {
+  .path = "set interface tx-queue",
+  .short_help = "set interface tx-queue <interface> queue <n> "
+               "threads <list>",
+  .function = set_interface_tx_queue,
+  .is_mp_safe = 1,
+};
+
 clib_error_t *
 set_interface_rss_queues (vlib_main_t * vm, u32 hw_if_index,
                          clib_bitmap_t * bitmap)