dpdk: use common interface placement infra 54/6054/7
authorDamjan Marion <damarion@cisco.com>
Wed, 5 Apr 2017 10:28:38 +0000 (12:28 +0200)
committerDave Barach <openvpp@barachs.net>
Tue, 11 Apr 2017 16:26:11 +0000 (16:26 +0000)
This pathch deprecates "show dpdk placement" and
"set dpdk placement" CLI commands.

Change-Id: I4e052ec3e8b8e6c54b4816e1e689e5b7a24892db
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/plugins/dpdk/device/cli.c
src/plugins/dpdk/device/device.c
src/plugins/dpdk/device/dpdk.h
src/plugins/dpdk/device/format.c
src/plugins/dpdk/device/init.c
src/plugins/dpdk/device/node.c

index d2def2f..17d1bfe 100644 (file)
@@ -563,61 +563,6 @@ VLIB_CLI_COMMAND (cmd_set_dpdk_if_desc,static) = {
 };
 /* *INDENT-ON* */
 
-static clib_error_t *
-show_dpdk_if_placement (vlib_main_t * vm, unformat_input_t * input,
-                       vlib_cli_command_t * cmd)
-{
-  vlib_thread_main_t *tm = vlib_get_thread_main ();
-  dpdk_main_t *dm = &dpdk_main;
-  dpdk_device_and_queue_t *dq;
-  int cpu;
-
-  if (tm->n_vlib_mains == 1)
-    vlib_cli_output (vm, "All interfaces are handled by main thread");
-
-  for (cpu = 0; cpu < vec_len (dm->devices_by_cpu); cpu++)
-    {
-      if (cpu >= dm->input_cpu_first_index &&
-         cpu < (dm->input_cpu_first_index + dm->input_cpu_count))
-       vlib_cli_output (vm, "Thread %u (%s at lcore %u):", cpu,
-                        vlib_worker_threads[cpu].name,
-                        vlib_worker_threads[cpu].lcore_id);
-
-      /* *INDENT-OFF* */
-      vec_foreach(dq, dm->devices_by_cpu[cpu])
-        {
-          u32 hw_if_index = dm->devices[dq->device].vlib_hw_if_index;
-          vnet_hw_interface_t * hi =  vnet_get_hw_interface(dm->vnet_main, hw_if_index);
-          vlib_cli_output(vm, "  %v queue %u", hi->name, dq->queue_id);
-        }
-      /* *INDENT-ON* */
-    }
-  return 0;
-}
-
-/*?
- * This command is used to display the thread and core each
- * DPDK interface and queue is assigned too.
- *
- * @cliexpar
- * Example of how to display the DPDK interface placement:
- * @cliexstart{show dpdk interface placement}
- * Thread 1 (vpp_wk_0 at lcore 1):
- *   GigabitEthernet0/8/0 queue 0
- *   GigabitEthernet0/9/0 queue 0
- * Thread 2 (vpp_wk_1 at lcore 2):
- *   GigabitEthernet0/8/0 queue 1
- *   GigabitEthernet0/9/0 queue 1
- * @cliexend
-?*/
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (cmd_show_dpdk_if_placement,static) = {
-    .path = "show dpdk interface placement",
-    .short_help = "show dpdk interface placement",
-    .function = show_dpdk_if_placement,
-};
-/* *INDENT-ON* */
-
 static int
 dpdk_device_queue_sort (void *a1, void *a2)
 {
@@ -636,131 +581,6 @@ dpdk_device_queue_sort (void *a1, void *a2)
     return 0;
 }
 
-static clib_error_t *
-set_dpdk_if_placement (vlib_main_t * vm, unformat_input_t * input,
-                      vlib_cli_command_t * cmd)
-{
-  unformat_input_t _line_input, *line_input = &_line_input;
-  dpdk_main_t *dm = &dpdk_main;
-  dpdk_device_and_queue_t *dq;
-  vnet_hw_interface_t *hw;
-  dpdk_device_t *xd;
-  u32 hw_if_index = (u32) ~ 0;
-  u32 queue = (u32) 0;
-  u32 cpu = (u32) ~ 0;
-  int i;
-  clib_error_t *error = NULL;
-
-  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, dm->vnet_main,
-          &hw_if_index))
-       ;
-      else if (unformat (line_input, "queue %d", &queue))
-       ;
-      else if (unformat (line_input, "thread %d", &cpu))
-       ;
-      else
-       {
-         error = clib_error_return (0, "parse error: '%U'",
-                                    format_unformat_error, line_input);
-         goto done;
-       }
-    }
-
-  if (hw_if_index == (u32) ~ 0)
-    {
-      error = clib_error_return (0, "please specify valid interface name");
-      goto done;
-    }
-
-  if (cpu < dm->input_cpu_first_index ||
-      cpu >= (dm->input_cpu_first_index + dm->input_cpu_count))
-    {
-      error = clib_error_return (0, "please specify valid thread id");
-      goto done;
-    }
-
-  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
-  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
-
-  for (i = 0; i < vec_len (dm->devices_by_cpu); i++)
-    {
-      /* *INDENT-OFF* */
-      vec_foreach(dq, dm->devices_by_cpu[i])
-        {
-          if (hw_if_index == dm->devices[dq->device].vlib_hw_if_index &&
-              queue == dq->queue_id)
-            {
-              if (cpu == i) /* nothing to do */
-                goto done;
-
-              vec_del1(dm->devices_by_cpu[i], dq - dm->devices_by_cpu[i]);
-              vec_add2(dm->devices_by_cpu[cpu], dq, 1);
-              dq->queue_id = queue;
-              dq->device = xd->device_index;
-              xd->cpu_socket_id_by_queue[queue] =
-                rte_lcore_to_socket_id(vlib_worker_threads[cpu].lcore_id);
-
-              vec_sort_with_function(dm->devices_by_cpu[i],
-                                    dpdk_device_queue_sort);
-
-              vec_sort_with_function(dm->devices_by_cpu[cpu],
-                                    dpdk_device_queue_sort);
-
-              if (vec_len(dm->devices_by_cpu[i]) == 0)
-                vlib_node_set_state (vlib_mains[i], dpdk_input_node.index,
-                                    VLIB_NODE_STATE_DISABLED);
-
-              if (vec_len(dm->devices_by_cpu[cpu]) == 1)
-                vlib_node_set_state (vlib_mains[cpu], dpdk_input_node.index,
-                                    VLIB_NODE_STATE_POLLING);
-
-              goto done;
-            }
-        }
-      /* *INDENT-ON* */
-    }
-
-  error = clib_error_return (0, "not found");
-
-done:
-  unformat_free (line_input);
-
-  return error;
-}
-
-/*?
- * This command is used to assign a given interface, and optionally a
- * given queue, to a different thread. This will not create a thread,
- * so the thread must already exist. Use '<em>/etc/vpp/startup.conf</em>'
- * for the initial thread creation. If the '<em>queue</em>' is not provided,
- * it defaults to 0.
- *
- * @cliexpar
- * Example of how to display the DPDK interface placement:
- * @cliexstart{show dpdk interface placement}
- * Thread 1 (vpp_wk_0 at lcore 1):
- *   GigabitEthernet0/8/0 queue 0
- *   GigabitEthernet0/9/0 queue 0
- * Thread 2 (vpp_wk_1 at lcore 2):
- *   GigabitEthernet0/8/0 queue 1
- *   GigabitEthernet0/9/0 queue 1
- * @cliexend
- * Example of how to assign a DPDK interface and queue to a thread:
- * @cliexcmd{set dpdk interface placement GigabitEthernet0/8/0 queue 1 thread 1}
-?*/
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (cmd_set_dpdk_if_placement,static) = {
-    .path = "set dpdk interface placement",
-    .short_help = "set dpdk interface placement <interface> [queue <n>] thread <n>",
-    .function = set_dpdk_if_placement,
-};
-/* *INDENT-ON* */
 
 static clib_error_t *
 show_dpdk_if_hqos_placement (vlib_main_t * vm, unformat_input_t * input,
@@ -784,7 +604,7 @@ show_dpdk_if_hqos_placement (vlib_main_t * vm, unformat_input_t * input,
 
       vec_foreach (dq, dm->devices_by_hqos_cpu[cpu])
       {
-       u32 hw_if_index = dm->devices[dq->device].vlib_hw_if_index;
+       u32 hw_if_index = dm->devices[dq->device].hw_if_index;
        vnet_hw_interface_t *hi =
          vnet_get_hw_interface (dm->vnet_main, hw_if_index);
        vlib_cli_output (vm, "  %v queue %u", hi->name, dq->queue_id);
@@ -864,7 +684,7 @@ set_dpdk_if_hqos_placement (vlib_main_t * vm, unformat_input_t * input,
     {
       vec_foreach (dq, dm->devices_by_hqos_cpu[i])
       {
-       if (hw_if_index == dm->devices[dq->device].vlib_hw_if_index)
+       if (hw_if_index == dm->devices[dq->device].hw_if_index)
          {
            if (cpu == i)       /* nothing to do */
              goto done;
index 9166124..e84d524 100644 (file)
@@ -301,7 +301,7 @@ static_always_inline
          u32 node_index;
 
          node_index = vec_elt_at_index (im->hw_interfaces,
-                                        xd->vlib_hw_if_index)->tx_node_index;
+                                        xd->hw_if_index)->tx_node_index;
 
          vlib_error_count (vm, node_index, DPDK_TX_FUNC_ERROR_BAD_RETVAL, 1);
          clib_warning ("rte_eth_tx_burst[%d]: error %d", xd->device_index,
@@ -658,7 +658,7 @@ dpdk_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
       xd->flags &= ~DPDK_DEVICE_FLAG_ADMIN_UP;
 
       rte_eth_allmulticast_disable (xd->device_index);
-      vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index, 0);
+      vnet_hw_interface_set_flags (vnm, xd->hw_if_index, 0);
       rte_eth_dev_stop (xd->device_index);
 
       /* For bonded interface, stop slave links */
index 06d89ad..9afd0b3 100644 (file)
@@ -175,7 +175,7 @@ typedef struct
   /* Instance ID */
   u32 device_index;
 
-  u32 vlib_hw_if_index;
+  u32 hw_if_index;
   u32 vlib_sw_if_index;
 
   /* next node index if we decide to steal the rx graph arc */
@@ -353,7 +353,6 @@ typedef struct
 
   /* Devices */
   dpdk_device_t *devices;
-  dpdk_device_and_queue_t **devices_by_cpu;
   dpdk_device_and_queue_t **devices_by_hqos_cpu;
 
   /* per-thread recycle lists */
@@ -392,10 +391,6 @@ typedef struct
 
   u8 use_rss;
 
-  /* which cpus are running dpdk-input */
-  int input_cpu_first_index;
-  int input_cpu_count;
-
   /* which cpus are running I/O TX */
   int hqos_cpu_first_index;
   int hqos_cpu_count;
index a09a3f8..f1cca3f 100644 (file)
@@ -295,7 +295,7 @@ format_dpdk_link_status (u8 * s, va_list * args)
   dpdk_device_t *xd = va_arg (*args, dpdk_device_t *);
   struct rte_eth_link *l = &xd->link;
   vnet_main_t *vnm = vnet_get_main ();
-  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, xd->vlib_hw_if_index);
+  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, xd->hw_if_index);
 
   s = format (s, "%s ", l->link_status ? "up" : "down");
   if (l->link_status)
index 39d919e..d3763e0 100755 (executable)
@@ -328,7 +328,7 @@ dpdk_port_setup (dpdk_main_t * dm, dpdk_device_t * xd)
 
   if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
     {
-      vnet_hw_interface_set_flags (dm->vnet_main, xd->vlib_hw_if_index, 0);
+      vnet_hw_interface_set_flags (dm->vnet_main, xd->hw_if_index, 0);
       rte_eth_dev_stop (xd->device_index);
     }
 
@@ -359,20 +359,20 @@ dpdk_port_setup (dpdk_main_t * dm, dpdk_device_t * xd)
 
   for (j = 0; j < xd->rx_q_used; j++)
     {
+      uword tidx = vnet_get_device_input_thread_index (dm->vnet_main,
+                                                      xd->hw_if_index, j);
+      unsigned lcore = vlib_worker_threads[tidx].lcore_id;
+      u16 socket_id = rte_lcore_to_socket_id (lcore);
 
       rv = rte_eth_rx_queue_setup (xd->device_index, j, xd->nb_rx_desc,
                                   xd->cpu_socket, 0,
-                                  dm->
-                                  pktmbuf_pools[xd->cpu_socket_id_by_queue
-                                                [j]]);
+                                  dm->pktmbuf_pools[socket_id]);
 
       /* retry with any other CPU socket */
       if (rv < 0)
        rv = rte_eth_rx_queue_setup (xd->device_index, j, xd->nb_rx_desc,
                                     SOCKET_ID_ANY, 0,
-                                    dm->
-                                    pktmbuf_pools[xd->cpu_socket_id_by_queue
-                                                  [j]]);
+                                    dm->pktmbuf_pools[socket_id]);
       if (rv < 0)
        return clib_error_return (0, "rte_eth_rx_queue_setup[%d]: err %d",
                                  xd->device_index, rv);
@@ -485,35 +485,20 @@ dpdk_lib_init (dpdk_main_t * dm)
   clib_error_t *error;
   vlib_main_t *vm = vlib_get_main ();
   vlib_thread_main_t *tm = vlib_get_thread_main ();
+  vnet_device_main_t *vdm = &vnet_device_main;
   vnet_sw_interface_t *sw;
   vnet_hw_interface_t *hi;
   dpdk_device_t *xd;
   vlib_pci_addr_t last_pci_addr;
   u32 last_pci_addr_port = 0;
-  vlib_thread_registration_t *tr, *tr_hqos;
-  uword *p, *p_hqos;
+  vlib_thread_registration_t *tr_hqos;
+  uword *p_hqos;
 
-  u32 next_cpu = 0, next_hqos_cpu = 0;
+  u32 next_hqos_cpu = 0;
   u8 af_packet_port_id = 0;
   u8 bond_ether_port_id = 0;
   last_pci_addr.as_u32 = ~0;
 
-  dm->input_cpu_first_index = 0;
-  dm->input_cpu_count = 1;
-
-  /* find out which cpus will be used for input */
-  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
-  tr = p ? (vlib_thread_registration_t *) p[0] : 0;
-
-  if (tr && tr->count > 0)
-    {
-      dm->input_cpu_first_index = tr->first_index;
-      dm->input_cpu_count = tr->count;
-    }
-
-  vec_validate_aligned (dm->devices_by_cpu, tm->n_vlib_mains - 1,
-                       CLIB_CACHE_LINE_BYTES);
-
   dm->hqos_cpu_first_index = 0;
   dm->hqos_cpu_count = 0;
 
@@ -924,48 +909,6 @@ dpdk_lib_init (dpdk_main_t * dm)
       dpdk_device_and_queue_t *dq;
       int q;
 
-      if (devconf->workers)
-       {
-         int i;
-         q = 0;
-         /* *INDENT-OFF* */
-         clib_bitmap_foreach (i, devconf->workers, ({
-           int cpu = dm->input_cpu_first_index + i;
-           unsigned lcore = vlib_worker_threads[cpu].lcore_id;
-           vec_validate(xd->cpu_socket_id_by_queue, q);
-           xd->cpu_socket_id_by_queue[q] = rte_lcore_to_socket_id(lcore);
-           vec_add2(dm->devices_by_cpu[cpu], dq, 1);
-           dq->device = xd->device_index;
-           dq->queue_id = q++;
-         }));
-         /* *INDENT-ON* */
-       }
-      else
-       for (q = 0; q < xd->rx_q_used; q++)
-         {
-           int cpu = dm->input_cpu_first_index + next_cpu;
-           unsigned lcore = vlib_worker_threads[cpu].lcore_id;
-
-           /*
-            * numa node for worker thread handling this queue
-            * needed for taking buffers from the right mempool
-            */
-           vec_validate (xd->cpu_socket_id_by_queue, q);
-           xd->cpu_socket_id_by_queue[q] = rte_lcore_to_socket_id (lcore);
-
-           /*
-            * construct vector of (device,queue) pairs for each worker thread
-            */
-           vec_add2 (dm->devices_by_cpu[cpu], dq, 1);
-           dq->device = xd->device_index;
-           dq->queue_id = q;
-
-           next_cpu++;
-           if (next_cpu == dm->input_cpu_count)
-             next_cpu = 0;
-         }
-
-
       if (devconf->hqos_enabled)
        {
          xd->flags |= DPDK_DEVICE_FLAG_HQOS;
@@ -1022,17 +965,6 @@ dpdk_lib_init (dpdk_main_t * dm)
       vec_validate_aligned (xd->d_trace_buffers, tm->n_vlib_mains,
                            CLIB_CACHE_LINE_BYTES);
 
-      rv = dpdk_port_setup (dm, xd);
-
-      if (rv)
-       return rv;
-
-      if (devconf->hqos_enabled)
-       {
-         rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
-         if (rv)
-           return rv;
-       }
 
       /* count the number of descriptors used for this device */
       nb_desc += xd->nb_rx_desc + xd->nb_tx_desc * xd->tx_q_used;
@@ -1040,13 +972,46 @@ dpdk_lib_init (dpdk_main_t * dm)
       error = ethernet_register_interface
        (dm->vnet_main, dpdk_device_class.index, xd->device_index,
         /* ethernet address */ addr,
-        &xd->vlib_hw_if_index, dpdk_flag_change);
+        &xd->hw_if_index, dpdk_flag_change);
       if (error)
        return error;
 
-      sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->vlib_hw_if_index);
+      sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->hw_if_index);
       xd->vlib_sw_if_index = sw->sw_if_index;
-      hi = vnet_get_hw_interface (dm->vnet_main, xd->vlib_hw_if_index);
+      vnet_set_device_input_node (dm->vnet_main, xd->hw_if_index,
+                                 dpdk_input_node.index);
+
+      if (devconf->workers)
+       {
+         int i;
+         q = 0;
+         /* *INDENT-OFF* */
+         clib_bitmap_foreach (i, devconf->workers, ({
+           vnet_device_input_assign_thread (dm->vnet_main, xd->hw_if_index, q++,
+                                            vdm->first_worker_thread_index + i);
+         }));
+         /* *INDENT-ON* */
+       }
+      else
+       for (q = 0; q < xd->rx_q_used; q++)
+         {
+           vnet_device_input_assign_thread (dm->vnet_main, xd->hw_if_index, q, /* any */
+                                            ~1);
+         }
+
+      hi = vnet_get_hw_interface (dm->vnet_main, xd->hw_if_index);
+
+      rv = dpdk_port_setup (dm, xd);
+
+      if (rv)
+       return rv;
+
+      if (devconf->hqos_enabled)
+       {
+         rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
+         if (rv)
+           return rv;
+       }
 
       /*
        * For cisco VIC vNIC, set default to VLAN strip enabled, unless
@@ -1723,13 +1688,13 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
       ed->sw_if_index = xd->vlib_sw_if_index;
       ed->admin_up = (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) != 0;
       ed->old_link_state = (u8)
-       vnet_hw_interface_is_link_up (vnm, xd->vlib_hw_if_index);
+       vnet_hw_interface_is_link_up (vnm, xd->hw_if_index);
       ed->new_link_state = (u8) xd->link.link_status;
     }
 
   if ((xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) &&
       ((xd->link.link_status != 0) ^
-       vnet_hw_interface_is_link_up (vnm, xd->vlib_hw_if_index)))
+       vnet_hw_interface_is_link_up (vnm, xd->hw_if_index)))
     {
       hw_flags_chg = 1;
       hw_flags |= (xd->link.link_status ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
@@ -1798,7 +1763,7 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
          ed->sw_if_index = xd->vlib_sw_if_index;
          ed->flags = hw_flags;
        }
-      vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index, hw_flags);
+      vnet_hw_interface_set_flags (vnm, xd->hw_if_index, hw_flags);
     }
 }
 
@@ -1815,23 +1780,6 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
 
   error = dpdk_lib_init (dm);
 
-  /*
-   * Turn on the input node if we found some devices to drive
-   * and we're not running worker threads or i/o threads
-   */
-
-  if (error == 0 && vec_len (dm->devices) > 0)
-    {
-      if (tm->n_vlib_mains == 1)
-       vlib_node_set_state (vm, dpdk_input_node.index,
-                            VLIB_NODE_STATE_POLLING);
-      else
-       for (i = 0; i < tm->n_vlib_mains; i++)
-         if (vec_len (dm->devices_by_cpu[i]) > 0)
-           vlib_node_set_state (vlib_mains[i], dpdk_input_node.index,
-                                VLIB_NODE_STATE_POLLING);
-    }
-
   if (error)
     clib_error_report (error);
 
@@ -1881,7 +1829,7 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
 
                    /* Populate MAC of bonded interface in VPP hw tables */
                    bhi = vnet_get_hw_interface
-                     (vnm, dm->devices[i].vlib_hw_if_index);
+                     (vnm, dm->devices[i].hw_if_index);
                    bei = pool_elt_at_index
                      (em->interfaces, bhi->hw_instance);
                    clib_memcpy (bhi->hw_address, addr, 6);
@@ -1910,10 +1858,9 @@ dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
                          }
                        /* Set slaves bitmap for bonded interface */
                        bhi->bond_info = clib_bitmap_set
-                         (bhi->bond_info, sdev->vlib_hw_if_index, 1);
+                         (bhi->bond_info, sdev->hw_if_index, 1);
                        /* Set slave link flags on slave interface */
-                       shi = vnet_get_hw_interface
-                         (vnm, sdev->vlib_hw_if_index);
+                       shi = vnet_get_hw_interface (vnm, sdev->hw_if_index);
                        ssi = vnet_get_sw_interface
                          (vnm, sdev->vlib_sw_if_index);
                        sei = pool_elt_at_index
index 0549ba5..5cc611c 100644 (file)
@@ -631,16 +631,17 @@ dpdk_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f)
   dpdk_main_t *dm = &dpdk_main;
   dpdk_device_t *xd;
   uword n_rx_packets = 0;
-  dpdk_device_and_queue_t *dq;
-  u32 thread_index = vlib_get_thread_index ();
+  vnet_device_input_runtime_t *rt = (void *) node->runtime_data;
+  vnet_device_and_queue_t *dq;
+  u32 thread_index = node->thread_index;
 
   /*
    * Poll all devices on this cpu for input/interrupts.
    */
   /* *INDENT-OFF* */
-  vec_foreach (dq, dm->devices_by_cpu[thread_index])
+  foreach_device_and_queue (dq, rt->devices_and_queues)
     {
-      xd = vec_elt_at_index(dm->devices, dq->device);
+      xd = vec_elt_at_index(dm->devices, dq->dev_instance);
       if (xd->flags & DPDK_DEVICE_FLAG_MAYBE_MULTISEG)
         n_rx_packets += dpdk_device_input (dm, xd, node, thread_index, dq->queue_id, /* maybe_multiseg */ 1);
       else