aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2017-03-28 14:16:15 +0200
committerDave Barach <openvpp@barachs.net>2017-04-04 14:40:22 +0000
commit2c2b6407129461e183bc8ad5964cddc98ed1626c (patch)
tree6a16cebde5edfe4ed661f8f88860c77407813fef
parent8328534a2734b64e5da791007fd346c54cdb4d32 (diff)
vlib: make vlib_node_interrupt_pending(...) thread safe
Change-Id: I24577bd32ae23fbe8515cc8d960eab5448ce3b5c Signed-off-by: Damjan Marion <damarion@cisco.com>
-rw-r--r--src/vlib/main.c23
-rw-r--r--src/vlib/node.h2
-rw-r--r--src/vlib/node_funcs.h2
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 *