diff options
author | Damjan Marion <damarion@cisco.com> | 2017-03-28 14:16:15 +0200 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2017-04-04 14:40:22 +0000 |
commit | 2c2b6407129461e183bc8ad5964cddc98ed1626c (patch) | |
tree | 6a16cebde5edfe4ed661f8f88860c77407813fef /src | |
parent | 8328534a2734b64e5da791007fd346c54cdb4d32 (diff) |
vlib: make vlib_node_interrupt_pending(...) thread safe
Change-Id: I24577bd32ae23fbe8515cc8d960eab5448ce3b5c
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vlib/main.c | 23 | ||||
-rw-r--r-- | src/vlib/node.h | 2 | ||||
-rw-r--r-- | src/vlib/node_funcs.h | 2 |
3 files changed, 22 insertions, 5 deletions
diff --git a/src/vlib/main.c b/src/vlib/main.c index a27268608f3..b22203f075b 100644 --- a/src/vlib/main.c +++ b/src/vlib/main.c @@ -1414,6 +1414,7 @@ vlib_main_or_worker_loop (vlib_main_t * vm, int is_main) uword i; u64 cpu_time_now; vlib_frame_queue_main_t *fqm; + u32 *last_node_runtime_indices = 0; /* Initialize pending node vector. */ if (is_main) @@ -1442,8 +1443,13 @@ vlib_main_or_worker_loop (vlib_main_t * vm, int is_main) vec_alloc (nm->data_from_advancing_timing_wheel, 32); } - /* Pre-allocate expired nodes. */ + /* Pre-allocate interupt runtime indices and lock. */ vec_alloc (nm->pending_interrupt_node_runtime_indices, 32); + vec_alloc (last_node_runtime_indices, 32); + if (!is_main) + clib_spinlock_init (&nm->pending_interrupt_lock); + + /* Pre-allocate expired nodes. */ if (!nm->polling_threshold_vector_length) nm->polling_threshold_vector_length = 10; if (!nm->interrupt_threshold_vector_length) @@ -1505,13 +1511,20 @@ vlib_main_or_worker_loop (vlib_main_t * vm, int is_main) uword i; if (l > 0) { - _vec_len (nm->pending_interrupt_node_runtime_indices) = 0; + u32 *tmp; + if (!is_main) + clib_spinlock_lock (&nm->pending_interrupt_lock); + tmp = nm->pending_interrupt_node_runtime_indices; + nm->pending_interrupt_node_runtime_indices = + last_node_runtime_indices; + last_node_runtime_indices = tmp; + _vec_len (last_node_runtime_indices) = 0; + if (!is_main) + clib_spinlock_unlock (&nm->pending_interrupt_lock); for (i = 0; i < l; i++) { n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT], - nm-> - pending_interrupt_node_runtime_indices - [i]); + last_node_runtime_indices[i]); cpu_time_now = dispatch_node (vm, n, VLIB_NODE_TYPE_INPUT, VLIB_NODE_STATE_INTERRUPT, diff --git a/src/vlib/node.h b/src/vlib/node.h index 2a532cc3988..fc7e7da2b85 100644 --- a/src/vlib/node.h +++ b/src/vlib/node.h @@ -42,6 +42,7 @@ #include <vppinfra/cpu.h> #include <vppinfra/longjmp.h> +#include <vppinfra/lock.h> #include <vppinfra/timing_wheel.h> #include <vlib/trace.h> /* for vlib_trace_filter_t */ @@ -644,6 +645,7 @@ typedef struct /* Node runtime indices for input nodes with pending interrupts. */ u32 *pending_interrupt_node_runtime_indices; + clib_spinlock_t pending_interrupt_lock; /* Input nodes are switched from/to interrupt to/from polling mode when average vector length goes above/below polling/interrupt diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h index 8ccfc438020..1f7d94e1ecf 100644 --- a/src/vlib/node_funcs.h +++ b/src/vlib/node_funcs.h @@ -183,7 +183,9 @@ vlib_node_set_interrupt_pending (vlib_main_t * vm, u32 node_index) vlib_node_main_t *nm = &vm->node_main; vlib_node_t *n = vec_elt (nm->nodes, node_index); ASSERT (n->type == VLIB_NODE_TYPE_INPUT); + clib_spinlock_lock_if_init (&nm->pending_interrupt_lock); vec_add1 (nm->pending_interrupt_node_runtime_indices, n->runtime_index); + clib_spinlock_unlock_if_init (&nm->pending_interrupt_lock); } always_inline vlib_process_t * |