From 3a7956383420a1d2f5f28b5bd3d3b3f5dda0420d Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Wed, 5 Apr 2017 12:28:38 +0200 Subject: dpdk: use common interface placement infra This pathch deprecates "show dpdk placement" and "set dpdk placement" CLI commands. Change-Id: I4e052ec3e8b8e6c54b4816e1e689e5b7a24892db Signed-off-by: Damjan Marion --- src/plugins/dpdk/device/cli.c | 184 +-------------------------------------- src/plugins/dpdk/device/device.c | 4 +- src/plugins/dpdk/device/dpdk.h | 7 +- src/plugins/dpdk/device/format.c | 2 +- src/plugins/dpdk/device/init.c | 159 +++++++++++---------------------- src/plugins/dpdk/device/node.c | 9 +- 6 files changed, 64 insertions(+), 301 deletions(-) diff --git a/src/plugins/dpdk/device/cli.c b/src/plugins/dpdk/device/cli.c index d2def2fc..17d1bfe1 100644 --- a/src/plugins/dpdk/device/cli.c +++ b/src/plugins/dpdk/device/cli.c @@ -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 '/etc/vpp/startup.conf' - * for the initial thread creation. If the 'queue' 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 [queue ] thread ", - .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; diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index 91661246..e84d524f 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -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 */ diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index 06d89adb..9afd0b35 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -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; diff --git a/src/plugins/dpdk/device/format.c b/src/plugins/dpdk/device/format.c index a09a3f83..f1cca3f7 100644 --- a/src/plugins/dpdk/device/format.c +++ b/src/plugins/dpdk/device/format.c @@ -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) diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 39d919e2..d3763e0b 100755 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -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 diff --git a/src/plugins/dpdk/device/node.c b/src/plugins/dpdk/device/node.c index 0549ba5d..5cc611cd 100644 --- a/src/plugins/dpdk/device/node.c +++ b/src/plugins/dpdk/device/node.c @@ -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 -- cgit 1.2.3-korg