- /* Next handle interrupts. */
- {
- uword l = _vec_len (nm->pending_interrupt_node_runtime_indices);
- uword i;
- if (l > 0)
- {
- _vec_len (nm->pending_interrupt_node_runtime_indices) = 0;
- 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]);
- cpu_time_now =
- dispatch_node (vm, n, VLIB_NODE_TYPE_INPUT,
- VLIB_NODE_STATE_INTERRUPT,
- /* frame */ 0,
- cpu_time_now);
- }
- }
- }
+ if (__atomic_load_n (nm->pending_interrupts, __ATOMIC_ACQUIRE))
+ {
+ int int_num = -1;
+ *nm->pending_interrupts = 0;
+
+ while ((int_num =
+ clib_interrupt_get_next (nm->interrupts, int_num)) != -1)
+ {
+ vlib_node_runtime_t *n;
+ clib_interrupt_clear (nm->interrupts, int_num);
+ n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT],
+ int_num);
+ cpu_time_now = dispatch_node (vm, n, VLIB_NODE_TYPE_INPUT,
+ VLIB_NODE_STATE_INTERRUPT,
+ /* frame */ 0, cpu_time_now);
+ }
+ }
+
+ /* Input nodes may have added work to the pending vector.
+ Process pending vector until there is nothing left.
+ All pending vectors will be processed from input -> output. */
+ for (i = 0; i < _vec_len (nm->pending_frames); i++)
+ cpu_time_now = dispatch_pending_node (vm, i, cpu_time_now);
+ /* Reset pending vector for next iteration. */
+ _vec_len (nm->pending_frames) = 0;