From: Arthur de Kerhor Date: Tue, 17 Jun 2025 14:30:51 +0000 (+0200) Subject: policer: don't compute CPU clock frequency for each API call X-Git-Tag: v26.02-rc0~206 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F17%2F43217%2F10;p=vpp.git policer: don't compute CPU clock frequency for each API call In some virtualized environments, where we can't get TSC from clib_get_cpuid, os_cpu_clock_frequency can take more than 1ms to return. As the TSC value is invariant over time, it can be cached in policer_init instead of being recalculated everytime a policer is created/updated. Type: improvement Change-Id: Icfd00feac76f35d562546a17e4830efb91dba219 Signed-off-by: Arthur de Kerhor --- diff --git a/src/vnet/policer/policer.c b/src/vnet/policer/policer.c index 00180d9c993..a24edb3c127 100644 --- a/src/vnet/policer/policer.c +++ b/src/vnet/policer/policer.c @@ -1037,6 +1037,19 @@ VLIB_CLI_COMMAND (show_policer_pools_command, static) = { .function = show_policer_pools_command_fn, }; +/* + * Return the number of hardware TSC timer ticks per second for the dataplane. + * This is approximately, but not exactly, the clock speed. + */ +static u64 +get_tsc_hz (void) +{ + f64 cpu_freq; + + cpu_freq = os_cpu_clock_frequency (); + return (u64) cpu_freq; +} + clib_error_t * policer_init (vlib_main_t * vm) { @@ -1052,6 +1065,7 @@ policer_init (vlib_main_t * vm) pm->policer_config_by_name = hash_create_string (0, sizeof (uword)); pm->policer_index_by_name = hash_create_string (0, sizeof (uword)); + pm->tsc_hz = get_tsc_hz (); vnet_classify_register_unformat_policer_next_index_fn (unformat_policer_classify_next_index); diff --git a/src/vnet/policer/policer.h b/src/vnet/policer/policer.h index 7ce7fc79d47..9eef408fd86 100644 --- a/src/vnet/policer/policer.h +++ b/src/vnet/policer/policer.h @@ -50,6 +50,9 @@ typedef struct /* frame queue for thread handoff */ u32 fq_index[VLIB_N_RX_TX]; + /* cached TSC value. No need to re-compute for each new policer */ + u64 tsc_hz; + u16 msg_id_base; } vnet_policer_main_t; diff --git a/src/vnet/policer/xlate.c b/src/vnet/policer/xlate.c index bffd208716d..26b0f593b14 100644 --- a/src/vnet/policer/xlate.c +++ b/src/vnet/policer/xlate.c @@ -843,19 +843,6 @@ pol_compute_hw_params (qos_pol_cfg_params_st *cfg, qos_pol_hw_params_st *hw) return 0; } -/* - * Return the number of hardware TSC timer ticks per second for the dataplane. - * This is approximately, but not exactly, the clock speed. - */ -static u64 -get_tsc_hz (void) -{ - f64 cpu_freq; - - cpu_freq = os_cpu_clock_frequency (); - return (u64) cpu_freq; -} - /* * Convert rates into bytes_per_period and scale. * Return 0 if ok or 1 if error. @@ -948,8 +935,8 @@ compute_policer_params (u64 hz, /* CPU speed in clocks per second */ int x86_pol_compute_hw_params (qos_pol_cfg_params_st *cfg, policer_t *hw) { + vnet_policer_main_t *pm = &vnet_policer_main; const int BYTES_PER_KBIT = (1000 / 8); - u64 hz; u32 cap; if (!cfg || !hw) @@ -958,7 +945,6 @@ x86_pol_compute_hw_params (qos_pol_cfg_params_st *cfg, policer_t *hw) return (-1); } - hz = get_tsc_hz (); hw->last_update_time = 0; /* @@ -1001,10 +987,9 @@ x86_pol_compute_hw_params (qos_pol_cfg_params_st *cfg, policer_t *hw) return (-1); } - if (compute_policer_params (hz, - (u64) cfg->rb.kbps.cir_kbps * - BYTES_PER_KBIT, 0, &hw->current_limit, - &hw->extended_limit, + if (compute_policer_params (pm->tsc_hz, + (u64) cfg->rb.kbps.cir_kbps * BYTES_PER_KBIT, + 0, &hw->current_limit, &hw->extended_limit, &hw->cir_tokens_per_period, &hw->pir_tokens_per_period, &hw->scale)) { @@ -1025,14 +1010,11 @@ x86_pol_compute_hw_params (qos_pol_cfg_params_st *cfg, policer_t *hw) return (-1); } - if (compute_policer_params (hz, - (u64) cfg->rb.kbps.cir_kbps * - BYTES_PER_KBIT, - (u64) cfg->rb.kbps.eir_kbps * - BYTES_PER_KBIT, &hw->current_limit, - &hw->extended_limit, - &hw->cir_tokens_per_period, - &hw->pir_tokens_per_period, &hw->scale)) + if (compute_policer_params ( + pm->tsc_hz, (u64) cfg->rb.kbps.cir_kbps * BYTES_PER_KBIT, + (u64) cfg->rb.kbps.eir_kbps * BYTES_PER_KBIT, &hw->current_limit, + &hw->extended_limit, &hw->cir_tokens_per_period, + &hw->pir_tokens_per_period, &hw->scale)) { QOS_DEBUG_ERROR ("Policer parameter computation failed."); return (-1);