summaryrefslogtreecommitdiffstats
path: root/src/vnet/policer
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/policer')
-rw-r--r--src/vnet/policer/police.h2
-rw-r--r--src/vnet/policer/police_inlines.h6
-rw-r--r--src/vnet/policer/policer.c56
-rw-r--r--src/vnet/policer/policer.h2
4 files changed, 58 insertions, 8 deletions
diff --git a/src/vnet/policer/police.h b/src/vnet/policer/police.h
index 1005a620ccd..d135e43ef3e 100644
--- a/src/vnet/policer/police.h
+++ b/src/vnet/policer/police.h
@@ -22,6 +22,8 @@ typedef enum
POLICE_VIOLATE = 2,
} policer_result_e;
+#define NUM_POLICE_RESULTS 3
+
// This is the hardware representation of the policer.
// To be multithread-safe, the policer is accessed through a spin-lock
// on the lock field. (For a policer update operation, 24B needs to be
diff --git a/src/vnet/policer/police_inlines.h b/src/vnet/policer/police_inlines.h
index afcc7724cef..0ed973079a6 100644
--- a/src/vnet/policer/police_inlines.h
+++ b/src/vnet/policer/police_inlines.h
@@ -68,10 +68,16 @@ vnet_policer_police (vlib_main_t * vm,
policer_read_response_type_st *pol;
vnet_policer_main_t *pm = &vnet_policer_main;
+ /* Speculative prefetch assuming a conform result */
+ 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];
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,
+ policer_index, 1, len);
if (PREDICT_TRUE (act == SSE2_QOS_ACTION_MARK_AND_TRANSMIT))
vnet_policer_mark (b, pol->mark_dscp[col]);
diff --git a/src/vnet/policer/policer.c b/src/vnet/policer/policer.c
index 80fa1e6f68d..fbb30551402 100644
--- a/src/vnet/policer/policer.c
+++ b/src/vnet/policer/policer.c
@@ -32,6 +32,21 @@ format_policer_handoff_trace (u8 *s, va_list *args)
return s;
}
+vlib_combined_counter_main_t policer_counters[] = {
+ {
+ .name = "Policer-Conform",
+ .stat_segment_name = "/net/policer/conform",
+ },
+ {
+ .name = "Policer-Exceed",
+ .stat_segment_name = "/net/policer/exceed",
+ },
+ {
+ .name = "Policer-Violate",
+ .stat_segment_name = "/net/policer/violate",
+ },
+};
+
clib_error_t *
policer_add_del (vlib_main_t * vm,
u8 * name,
@@ -86,6 +101,7 @@ policer_add_del (vlib_main_t * vm,
{
policer_read_response_type_st *pp;
sse2_qos_pol_cfg_params_st *cp;
+ int i;
pool_get (pm->configs, cp);
pool_get (pm->policer_templates, pp);
@@ -102,6 +118,12 @@ policer_add_del (vlib_main_t * vm,
hash_set_mem (pm->policer_index_by_name, name, pi);
*policer_index = pi;
policer->thread_index = ~0;
+
+ for (i = 0; i < NUM_POLICE_RESULTS; i++)
+ {
+ vlib_validate_combined_counter (&policer_counters[i], pi);
+ vlib_zero_combined_counter (&policer_counters[i], pi);
+ }
}
else
{
@@ -117,6 +139,15 @@ format_policer_instance (u8 * s, va_list * va)
{
policer_read_response_type_st *i
= va_arg (*va, policer_read_response_type_st *);
+ uword pi = va_arg (*va, uword);
+ int result;
+ vlib_counter_t counts[NUM_POLICE_RESULTS];
+
+ for (result = 0; result < NUM_POLICE_RESULTS; result++)
+ {
+ vlib_get_combined_counter (&policer_counters[result], pi,
+ &counts[result]);
+ }
s = format (s, "policer at %llx: %s rate, %s color-aware\n",
i, i->single_rate ? "single" : "dual",
@@ -127,6 +158,12 @@ format_policer_instance (u8 * s, va_list * va)
i->current_limit,
i->current_bucket, i->extended_limit, i->extended_bucket);
s = format (s, "last update %llu\n", i->last_update_time);
+ s = format (s, "conform %llu packets, %llu bytes\n",
+ counts[POLICE_CONFORM].packets, counts[POLICE_CONFORM].bytes);
+ s = format (s, "exceed %llu packets, %llu bytes\n",
+ counts[POLICE_EXCEED].packets, counts[POLICE_EXCEED].bytes);
+ s = format (s, "violate %llu packets, %llu bytes\n",
+ counts[POLICE_VIOLATE].packets, counts[POLICE_VIOLATE].bytes);
return s;
}
@@ -496,6 +533,7 @@ show_policer_command_fn (vlib_main_t * vm,
u32 pool_index;
u8 *match_name = 0;
u8 *name;
+ uword *pi;
sse2_qos_pol_cfg_params_st *config;
policer_read_response_type_st *templ;
@@ -507,14 +545,16 @@ show_policer_command_fn (vlib_main_t * vm,
name = (u8 *) p->key;
if (match_name == 0 || !strcmp((char *) name, (char *) match_name))
{
- pool_index = p->value[0];
- config = pool_elt_at_index (pm->configs, pool_index);
- templ = pool_elt_at_index (pm->policer_templates, pool_index);
- vlib_cli_output (vm, "Name \"%s\" %U ",
- name, format_policer_config, config);
- vlib_cli_output (vm, "Template %U",
- format_policer_instance, templ);
- vlib_cli_output (vm, "-----------");
+ pi = hash_get_mem (pm->policer_index_by_name, name);
+
+ pool_index = p->value[0];
+ config = pool_elt_at_index (pm->configs, pool_index);
+ templ = pool_elt_at_index (pm->policer_templates, pool_index);
+ vlib_cli_output (vm, "Name \"%s\" %U ", name, format_policer_config,
+ config);
+ vlib_cli_output (vm, "Template %U", format_policer_instance, templ,
+ pi[0]);
+ vlib_cli_output (vm, "-----------");
}
}));
/* *INDENT-ON* */
diff --git a/src/vnet/policer/policer.h b/src/vnet/policer/policer.h
index b7c1d616cef..2e57e4654bd 100644
--- a/src/vnet/policer/policer.h
+++ b/src/vnet/policer/policer.h
@@ -46,6 +46,8 @@ typedef struct
extern vnet_policer_main_t vnet_policer_main;
+extern vlib_combined_counter_main_t policer_counters[];
+
typedef enum
{
VNET_POLICER_INDEX_BY_SW_IF_INDEX,