summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Russell <brian@graphiant.com>2021-02-18 10:25:23 +0000
committerNeale Ranns <neale@graphiant.com>2021-02-19 10:53:15 +0000
commitfce88656cc1b0da8731a71c4a6efa759e0df3fa8 (patch)
tree52d58afa787b5d6b0ffcabc70f99e8313c4875df
parent6e6920d4e096bd158a0057ce0f8dd8a08cbabf72 (diff)
policer: move handoff checks into policer code
The IP punt policer currently checks if it needs to do worker thread handoff based on the thread index stored in the policer. Move this functionality into the policer code so it can be common for all users of the policer. Type: improvement Signed-off-by: Brian Russell <brian@graphiant.com> Change-Id: Ia8d11e62898a58b19d7b27b296f8369baa3e5aa1
-rw-r--r--src/vnet/ip/ip_punt_drop.h42
-rw-r--r--src/vnet/policer/node_funcs.c18
-rw-r--r--src/vnet/policer/police.h3
-rw-r--r--src/vnet/policer/police_inlines.h25
4 files changed, 41 insertions, 47 deletions
diff --git a/src/vnet/ip/ip_punt_drop.h b/src/vnet/ip/ip_punt_drop.h
index 046a86a0056..16d46ba190e 100644
--- a/src/vnet/ip/ip_punt_drop.h
+++ b/src/vnet/ip/ip_punt_drop.h
@@ -72,10 +72,6 @@ ip_punt_policer (vlib_main_t * vm,
u64 time_in_policer_periods;
vnet_feature_main_t *fm = &feature_main;
vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc_index];
- vnet_policer_main_t *pm = &vnet_policer_main;
- policer_t *pol = &pm->policers[policer_index];
- u32 pol_thread_index = pol->thread_index;
- u32 this_thread_index = vm->thread_index;
time_in_policer_periods =
clib_cpu_time_now () >> POLICER_TICKS_PER_PERIOD_SHIFT;
@@ -84,20 +80,6 @@ ip_punt_policer (vlib_main_t * vm,
n_left_from = frame->n_vectors;
next_index = node->cached_next_index;
- if (PREDICT_FALSE (pol_thread_index == ~0))
- {
- /*
- * This is the first packet to use this policer. Set the
- * thread index in the policer to this thread and any
- * packets seen by this node on other threads will
- * be handed off to this one.
- *
- * This could happen simultaneously on another thread.
- */
- clib_atomic_cmp_and_swap (&pol->thread_index, ~0, this_thread_index);
- pol_thread_index = this_thread_index;
- }
-
while (n_left_from > 0)
{
vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
@@ -121,7 +103,14 @@ ip_punt_policer (vlib_main_t * vm,
b0 = vlib_get_buffer (vm, bi0);
b1 = vlib_get_buffer (vm, bi1);
- if (PREDICT_FALSE (this_thread_index != pol_thread_index))
+ act0 = vnet_policer_police (vm, b0, policer_index,
+ time_in_policer_periods, POLICE_CONFORM,
+ true);
+ act1 = vnet_policer_police (vm, b1, policer_index,
+ time_in_policer_periods, POLICE_CONFORM,
+ true);
+
+ if (PREDICT_FALSE (act0 == QOS_ACTION_HANDOFF))
{
next0 = next1 = IP_PUNT_POLICER_NEXT_HANDOFF;
}
@@ -133,13 +122,6 @@ ip_punt_policer (vlib_main_t * vm,
vnet_get_config_data (&cm->config_main,
&b1->current_config_index, &next1, 0);
- act0 =
- vnet_policer_police (vm, b0, policer_index,
- time_in_policer_periods, POLICE_CONFORM);
- act1 =
- vnet_policer_police (vm, b1, policer_index,
- time_in_policer_periods, POLICE_CONFORM);
-
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = IP_PUNT_POLICER_NEXT_DROP;
@@ -188,7 +170,10 @@ ip_punt_policer (vlib_main_t * vm,
b0 = vlib_get_buffer (vm, bi0);
- if (PREDICT_FALSE (this_thread_index != pol_thread_index))
+ act0 = vnet_policer_police (vm, b0, policer_index,
+ time_in_policer_periods, POLICE_CONFORM,
+ true);
+ if (PREDICT_FALSE (act0 == QOS_ACTION_HANDOFF))
{
next0 = IP_PUNT_POLICER_NEXT_HANDOFF;
}
@@ -197,9 +182,6 @@ ip_punt_policer (vlib_main_t * vm,
vnet_get_config_data (&cm->config_main,
&b0->current_config_index, &next0, 0);
- act0 =
- vnet_policer_police (vm, b0, policer_index,
- time_in_policer_periods, POLICE_CONFORM);
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = IP_PUNT_POLICER_NEXT_DROP;
diff --git a/src/vnet/policer/node_funcs.c b/src/vnet/policer/node_funcs.c
index 30e5c505364..be8ce58799a 100644
--- a/src/vnet/policer/node_funcs.c
+++ b/src/vnet/policer/node_funcs.c
@@ -127,10 +127,10 @@ vnet_policer_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
pi1 = pm->policer_index_by_sw_if_index[sw_if_index1];
act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods,
- POLICE_CONFORM /* no chaining */ );
+ POLICE_CONFORM /* no chaining */, false);
act1 = vnet_policer_police (vm, b1, pi1, time_in_policer_periods,
- POLICE_CONFORM /* no chaining */ );
+ POLICE_CONFORM /* no chaining */, false);
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) /* drop action */
{
@@ -201,7 +201,7 @@ vnet_policer_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
pi0 = pm->policer_index_by_sw_if_index[sw_if_index0];
act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods,
- POLICE_CONFORM /* no chaining */ );
+ POLICE_CONFORM /* no chaining */, false);
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) /* drop action */
{
@@ -496,11 +496,9 @@ policer_classify_inline (vlib_main_t * vm,
if (e0)
{
- act0 = vnet_policer_police (vm,
- b0,
- e0->next_index,
+ act0 = vnet_policer_police (vm, b0, e0->next_index,
time_in_policer_periods,
- e0->opaque_index);
+ e0->opaque_index, false);
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
@@ -530,11 +528,9 @@ policer_classify_inline (vlib_main_t * vm,
vnet_classify_find_entry (t0, (u8 *) h0, hash0, now);
if (e0)
{
- act0 = vnet_policer_police (vm,
- b0,
- e0->next_index,
+ act0 = vnet_policer_police (vm, b0, e0->next_index,
time_in_policer_periods,
- e0->opaque_index);
+ e0->opaque_index, false);
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
diff --git a/src/vnet/policer/police.h b/src/vnet/policer/police.h
index f780bf65c50..5ad249ef40e 100644
--- a/src/vnet/policer/police.h
+++ b/src/vnet/policer/police.h
@@ -28,7 +28,8 @@ typedef enum
{
QOS_ACTION_DROP = 0,
QOS_ACTION_TRANSMIT,
- QOS_ACTION_MARK_AND_TRANSMIT
+ QOS_ACTION_MARK_AND_TRANSMIT,
+ QOS_ACTION_HANDOFF
} __clib_packed qos_action_type_en;
// This is the hardware representation of the policer.
diff --git a/src/vnet/policer/police_inlines.h b/src/vnet/policer/police_inlines.h
index fe0c754b7d4..9f56e1134d6 100644
--- a/src/vnet/policer/police_inlines.h
+++ b/src/vnet/policer/police_inlines.h
@@ -56,11 +56,9 @@ vnet_policer_mark (vlib_buffer_t *b, ip_dscp_t dscp)
}
static_always_inline u8
-vnet_policer_police (vlib_main_t * vm,
- vlib_buffer_t * b,
- u32 policer_index,
+vnet_policer_police (vlib_main_t *vm, vlib_buffer_t *b, u32 policer_index,
u64 time_in_policer_periods,
- policer_result_e packet_color)
+ policer_result_e packet_color, bool handoff)
{
qos_action_type_en act;
u32 len;
@@ -72,8 +70,25 @@ vnet_policer_police (vlib_main_t * vm,
vlib_prefetch_combined_counter (&policer_counters[POLICE_CONFORM],
vm->thread_index, policer_index);
- len = vlib_buffer_length_in_chain (vm, b);
pol = &pm->policers[policer_index];
+
+ if (handoff)
+ {
+ if (PREDICT_FALSE (pol->thread_index == ~0))
+ /*
+ * This is the first packet to use this policer. Set the
+ * thread index in the policer to this thread and any
+ * packets seen by this node on other threads will
+ * be handed off to this one.
+ *
+ * This could happen simultaneously on another thread.
+ */
+ clib_atomic_cmp_and_swap (&pol->thread_index, ~0, vm->thread_index);
+ else if (PREDICT_FALSE (pol->thread_index != vm->thread_index))
+ return QOS_ACTION_HANDOFF;
+ }
+
+ len = vlib_buffer_length_in_chain (vm, b);
col = vnet_police_packet (pol, len, packet_color, time_in_policer_periods);
act = pol->action[col];
vlib_increment_combined_counter (&policer_counters[col], vm->thread_index,