vlib: support interrupt re-arm from node
Type: improvement
Change-Id: I13517bff4129497644e0efc3495d0ee7897fe5a7
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vlib/main.c b/src/vlib/main.c
index bada9bc..912f5a5 100644
--- a/src/vlib/main.c
+++ b/src/vlib/main.c
@@ -1679,14 +1679,15 @@
static_always_inline u64
dispatch_pending_interrupts (vlib_main_t * vm, vlib_node_main_t * nm,
- u64 cpu_time_now)
+ u64 cpu_time_now,
+ vlib_node_interrupt_t * interrupts)
{
vlib_node_runtime_t *n;
- for (int i = 0; i < _vec_len (nm->pending_local_interrupts); i++)
+ for (int i = 0; i < _vec_len (interrupts); i++)
{
vlib_node_interrupt_t *in;
- in = vec_elt_at_index (nm->pending_local_interrupts, i);
+ in = vec_elt_at_index (interrupts, i);
n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT],
in->node_runtime_index);
n->interrupt_data = in->data;
@@ -1694,7 +1695,6 @@
VLIB_NODE_STATE_INTERRUPT, /* frame */ 0,
cpu_time_now);
}
- vec_reset_length (nm->pending_local_interrupts);
return cpu_time_now;
}
@@ -1708,6 +1708,7 @@
f64 now;
vlib_frame_queue_main_t *fqm;
u32 frame_queue_check_counter = 0;
+ vlib_node_interrupt_t *empty_int_list = 0;
/* Initialize pending node vector. */
if (is_main)
@@ -1728,6 +1729,7 @@
/* Pre-allocate interupt runtime indices and lock. */
vec_alloc (nm->pending_local_interrupts, 32);
vec_alloc (nm->pending_remote_interrupts, 32);
+ vec_alloc (empty_int_list, 32);
vec_alloc_aligned (nm->pending_remote_interrupts_notify, 1,
CLIB_CACHE_LINE_BYTES);
clib_spinlock_init (&nm->pending_interrupt_lock);
@@ -1821,24 +1823,33 @@
/* handle local interruots */
if (_vec_len (nm->pending_local_interrupts))
- cpu_time_now = dispatch_pending_interrupts (vm, nm, cpu_time_now);
+ {
+ vlib_node_interrupt_t *interrupts = nm->pending_local_interrupts;
+ nm->pending_local_interrupts = empty_int_list;
+ cpu_time_now = dispatch_pending_interrupts (vm, nm, cpu_time_now,
+ interrupts);
+ empty_int_list = interrupts;
+ vec_reset_length (empty_int_list);
+ }
/* handle remote interruots */
if (PREDICT_FALSE (_vec_len (nm->pending_remote_interrupts)))
{
- vlib_node_interrupt_t *in;
+ vlib_node_interrupt_t *interrupts;
/* at this point it is known that
* vec_len (nm->pending_local_interrupts) is zero so we quickly swap
* local and remote vector under the spinlock */
clib_spinlock_lock (&nm->pending_interrupt_lock);
- in = nm->pending_local_interrupts;
- nm->pending_local_interrupts = nm->pending_remote_interrupts;
- nm->pending_remote_interrupts = in;
+ interrupts = nm->pending_remote_interrupts;
+ nm->pending_remote_interrupts = empty_int_list;
*nm->pending_remote_interrupts_notify = 0;
clib_spinlock_unlock (&nm->pending_interrupt_lock);
- cpu_time_now = dispatch_pending_interrupts (vm, nm, cpu_time_now);
+ cpu_time_now = dispatch_pending_interrupts (vm, nm, cpu_time_now,
+ interrupts);
+ empty_int_list = interrupts;
+ vec_reset_length (empty_int_list);
}
/* Input nodes may have added work to the pending vector.