- /* Next handle interrupts. */
- {
- /* unlocked read, for performance */
- uword l = _vec_len (nm->pending_interrupt_node_runtime_indices);
- uword i;
- if (PREDICT_FALSE (l > 0))
- {
- u32 *tmp;
- if (!is_main)
- {
- clib_spinlock_lock (&nm->pending_interrupt_lock);
- /* Re-read w/ lock held, in case another thread added an item */
- l = _vec_len (nm->pending_interrupt_node_runtime_indices);
- }
+ /* handle local interruots */
+ if (_vec_len (nm->pending_local_interrupts))
+ {
+ 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 *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);
+ 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,
+ interrupts);
+ empty_int_list = interrupts;
+ vec_reset_length (empty_int_list);
+ }