From 08602d129be6b633a3619ad3699aa2cf6ad31dd5 Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Sat, 4 Jun 2016 14:10:59 -0400 Subject: [PATCH] Add dpdk config parameter: poll-sleep Sleep milliseconds after each dpdk input device poll, useful when oversubscribing CPUs. Change-Id: I90ad1f21dae7eeeda56bfe845911118aa46f83ec Signed-off-by: Dave Barach --- vnet/vnet/devices/dpdk/dpdk.h | 3 +++ vnet/vnet/devices/dpdk/init.c | 4 +++- vnet/vnet/devices/dpdk/node.c | 38 ++++++++++++++++++-------------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/vnet/vnet/devices/dpdk/dpdk.h b/vnet/vnet/devices/dpdk/dpdk.h index 144333fb384..1a861e904f1 100644 --- a/vnet/vnet/devices/dpdk/dpdk.h +++ b/vnet/vnet/devices/dpdk/dpdk.h @@ -411,6 +411,9 @@ typedef struct { frame_queue_trace_t *frame_queue_traces; frame_queue_nelt_counter_t *frame_queue_histogram; + /* Sleep for this many MS after each device poll */ + u32 poll_sleep; + /* convenience */ vlib_main_t * vlib_main; vnet_main_t * vnet_main; diff --git a/vnet/vnet/devices/dpdk/init.c b/vnet/vnet/devices/dpdk/init.c index 28659a9d136..3a3c86af49a 100644 --- a/vnet/vnet/devices/dpdk/init.c +++ b/vnet/vnet/devices/dpdk/init.c @@ -805,6 +805,7 @@ static clib_error_t * dpdk_config (vlib_main_t * vm, unformat_input_t * input) { clib_error_t * error = 0; + dpdk_main_t * dm = &dpdk_main; dpdk_config_main_t * conf = &dpdk_config_main; vlib_thread_main_t * tm = vlib_get_thread_main(); vlib_node_runtime_t * rt = vlib_node_get_runtime (vm, dpdk_input_node.index); @@ -904,7 +905,8 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) conf->use_virtio_vhost = 0; else if (unformat (input, "rss %d", &conf->use_rss)) ; - + else if (unformat (input, "poll-sleep %d", &dm->poll_sleep)) + ; #define _(a) \ else if (unformat(input, #a)) \ { \ diff --git a/vnet/vnet/devices/dpdk/node.c b/vnet/vnet/devices/dpdk/node.c index ca94511b411..0dd3cfcdd77 100644 --- a/vnet/vnet/devices/dpdk/node.c +++ b/vnet/vnet/devices/dpdk/node.c @@ -759,24 +759,22 @@ static inline u32 dpdk_device_input ( dpdk_main_t * dm, return mb_index; } -#if VIRL > 0 -#define VIRL_SPEED_LIMIT() \ - /* Limit the input rate to 1000 vectors / sec */ \ - { \ - struct timespec ts, tsrem; \ - \ - ts.tv_sec = 0; \ - ts.tv_nsec = 1000*1000; /* 1ms */ \ - \ - while (nanosleep(&ts, &tsrem) < 0) \ - { \ - ts = tsrem; \ - } \ - } -#else -#define VIRL_SPEED_LIMIT() -#endif +static inline void poll_rate_limit(dpdk_main_t * dm) +{ + /* Limit the poll rate by sleeping for N msec between polls */ + if (PREDICT_FALSE (dm->poll_sleep != 0)) + { + struct timespec ts, tsrem; + + ts.tv_sec = 0; + ts.tv_nsec = 1000*1000*dm->poll_sleep; /* 1ms */ + while (nanosleep(&ts, &tsrem) < 0) + { + ts = tsrem; + } + } +} static uword dpdk_input (vlib_main_t * vm, @@ -799,7 +797,7 @@ dpdk_input (vlib_main_t * vm, n_rx_packets += dpdk_device_input (dm, xd, node, cpu_index, 0, 0); } - VIRL_SPEED_LIMIT() + poll_rate_limit(dm); return n_rx_packets; } @@ -824,7 +822,7 @@ dpdk_input_rss (vlib_main_t * vm, n_rx_packets += dpdk_device_input (dm, xd, node, cpu_index, dq->queue_id, 0); } - VIRL_SPEED_LIMIT() + poll_rate_limit(dm); return n_rx_packets; } @@ -849,7 +847,7 @@ dpdk_input_efd (vlib_main_t * vm, n_rx_packets += dpdk_device_input (dm, xd, node, cpu_index, dq->queue_id, 1); } - VIRL_SPEED_LIMIT() + poll_rate_limit(dm); return n_rx_packets; } -- 2.16.6