diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/interface/runtime.c | 1 | ||||
-rw-r--r-- | src/vnet/interface/tx_queue.c | 16 | ||||
-rw-r--r-- | src/vnet/interface_cli.c | 97 |
3 files changed, 109 insertions, 5 deletions
diff --git a/src/vnet/interface/runtime.c b/src/vnet/interface/runtime.c index e899d7ab9c8..462f7bbfba7 100644 --- a/src/vnet/interface/runtime.c +++ b/src/vnet/interface/runtime.c @@ -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; } } diff --git a/src/vnet/interface/tx_queue.c b/src/vnet/interface/tx_queue.c index 3041a58414d..8a6cd9da304 100644 --- a/src/vnet/interface/tx_queue.c +++ b/src/vnet/interface/tx_queue.c @@ -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")); } diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index 6dadbb8e8d3..e5d0ab280db 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -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) { @@ -1809,6 +1810,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) { |