diff options
-rw-r--r-- | src/vnet/policer/police_inlines.h | 67 | ||||
-rw-r--r-- | src/vnet/policer/policer.c | 14 |
2 files changed, 81 insertions, 0 deletions
diff --git a/src/vnet/policer/police_inlines.h b/src/vnet/policer/police_inlines.h index 64386e6f1bf..afcc7724cef 100644 --- a/src/vnet/policer/police_inlines.h +++ b/src/vnet/policer/police_inlines.h @@ -78,6 +78,73 @@ vnet_policer_police (vlib_main_t * vm, return act; } +typedef enum +{ + POLICER_HANDOFF_ERROR_CONGESTION_DROP, +} policer_handoff_error_t; + +typedef struct policer_handoff_trace_t_ +{ + u32 policer_index; + u32 current_worker_index; + u32 next_worker_index; +} policer_handoff_trace_t; + +extern u8 *format_policer_handoff_trace (u8 *s, va_list *args); + +/* Do worker handoff based on the policer's thread_index */ +static_always_inline uword +policer_handoff (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, u32 fq_index, u32 policer_index) +{ + vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b; + u16 thread_indices[VLIB_FRAME_SIZE], *ti; + u32 n_enq, n_left_from, *from; + vnet_policer_main_t *pm; + policer_read_response_type_st *policer; + u32 this_thread, policer_thread; + + pm = &vnet_policer_main; + policer = &pm->policers[policer_index]; + policer_thread = policer->thread_index; + + this_thread = vm->thread_index; + from = vlib_frame_vector_args (frame); + n_left_from = frame->n_vectors; + vlib_get_buffers (vm, from, bufs, n_left_from); + + b = bufs; + ti = thread_indices; + + while (n_left_from > 0) + { + ti[0] = policer_thread; + + if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && + b[0]->flags & VLIB_BUFFER_IS_TRACED)) + { + policer_handoff_trace_t *t = + vlib_add_trace (vm, node, b[0], sizeof (*t)); + t->current_worker_index = this_thread; + t->next_worker_index = policer_thread; + t->policer_index = policer_index; + } + + n_left_from--; + ti++; + b++; + } + + n_enq = vlib_buffer_enqueue_to_thread (vm, fq_index, from, thread_indices, + frame->n_vectors, 1); + + if (n_enq < frame->n_vectors) + vlib_node_increment_counter (vm, node->node_index, + POLICER_HANDOFF_ERROR_CONGESTION_DROP, + frame->n_vectors - n_enq); + + return n_enq; +} #endif // __POLICE_INLINES_H__ /* diff --git a/src/vnet/policer/policer.c b/src/vnet/policer/policer.c index 7ad87a6ebdf..80fa1e6f68d 100644 --- a/src/vnet/policer/policer.c +++ b/src/vnet/policer/policer.c @@ -14,10 +14,24 @@ */ #include <stdint.h> #include <vnet/policer/policer.h> +#include <vnet/policer/police_inlines.h> #include <vnet/classify/vnet_classify.h> vnet_policer_main_t vnet_policer_main; +u8 * +format_policer_handoff_trace (u8 *s, va_list *args) +{ + CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); + CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); + policer_handoff_trace_t *t = va_arg (*args, policer_handoff_trace_t *); + + s = format (s, "policer %d, handoff thread %d to %d", t->policer_index, + t->current_worker_index, t->next_worker_index); + + return s; +} + clib_error_t * policer_add_del (vlib_main_t * vm, u8 * name, |