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
u64 time_in_policer_periods;
vnet_feature_main_t *fm = &feature_main;
vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc_index];
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;
time_in_policer_periods =
clib_cpu_time_now () >> POLICER_TICKS_PER_PERIOD_SHIFT;
n_left_from = frame->n_vectors;
next_index = node->cached_next_index;
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);
while (n_left_from > 0)
{
vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
b0 = vlib_get_buffer (vm, bi0);
b1 = vlib_get_buffer (vm, bi1);
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;
}
{
next0 = next1 = IP_PUNT_POLICER_NEXT_HANDOFF;
}
vnet_get_config_data (&cm->config_main,
&b1->current_config_index, &next1, 0);
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;
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = IP_PUNT_POLICER_NEXT_DROP;
b0 = vlib_get_buffer (vm, bi0);
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;
}
{
next0 = IP_PUNT_POLICER_NEXT_HANDOFF;
}
vnet_get_config_data (&cm->config_main,
&b0->current_config_index, &next0, 0);
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;
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = IP_PUNT_POLICER_NEXT_DROP;
pi1 = pm->policer_index_by_sw_if_index[sw_if_index1];
act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods,
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,
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 */
{
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) /* drop action */
{
pi0 = pm->policer_index_by_sw_if_index[sw_if_index0];
act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods,
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 */
{
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP)) /* drop action */
{
- act0 = vnet_policer_police (vm,
- b0,
- e0->next_index,
+ act0 = vnet_policer_police (vm, b0, e0->next_index,
+ e0->opaque_index, false);
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
vnet_classify_find_entry (t0, (u8 *) h0, hash0, now);
if (e0)
{
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,
+ e0->opaque_index, false);
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
if (PREDICT_FALSE (act0 == QOS_ACTION_DROP))
{
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
{
QOS_ACTION_DROP = 0,
QOS_ACTION_TRANSMIT,
{
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.
} __clib_packed qos_action_type_en;
// This is the hardware representation of the policer.
}
static_always_inline u8
}
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,
u64 time_in_policer_periods,
- policer_result_e packet_color)
+ policer_result_e packet_color, bool handoff)
{
qos_action_type_en act;
u32 len;
{
qos_action_type_en act;
u32 len;
vlib_prefetch_combined_counter (&policer_counters[POLICE_CONFORM],
vm->thread_index, policer_index);
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];
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,
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,