28 #define QOS_DEBUG_ERROR(msg, args...) \ 29 vlib_log_err (vnet_policer_main.log_class, msg, ##args); 31 #define QOS_DEBUG_INFO(msg, args...) \ 32 vlib_log_info (vnet_policer_main.log_class, msg, ##args); 35 #define MIN(x,y) (((x)<(y))?(x):(y)) 39 #define MAX(x,y) (((x)>(y))?(x):(y)) 42 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AH_OFFSET 0 43 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AH_MASK 8 44 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AH_SHIFT 24 46 #define IPE_POLICER_FULL_WRITE_REQUEST_TYPE_OFFSET 2 47 #define IPE_POLICER_FULL_WRITE_REQUEST_TYPE_MASK 2 48 #define IPE_POLICER_FULL_WRITE_REQUEST_TYPE_SHIFT 10 50 #define IPE_POLICER_FULL_WRITE_REQUEST_CMD_OFFSET 3 51 #define IPE_POLICER_FULL_WRITE_REQUEST_CMD_MASK 2 52 #define IPE_POLICER_FULL_WRITE_REQUEST_CMD_SHIFT 0 54 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AL_OFFSET 4 55 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AL_MASK 32 56 #define IPE_POLICER_FULL_WRITE_REQUEST_M40AL_SHIFT 0 58 #define IPE_POLICER_FULL_WRITE_REQUEST_RFC_OFFSET 8 59 #define IPE_POLICER_FULL_WRITE_REQUEST_RFC_MASK 2 60 #define IPE_POLICER_FULL_WRITE_REQUEST_RFC_SHIFT 30 62 #define IPE_POLICER_FULL_WRITE_REQUEST_AN_OFFSET 8 63 #define IPE_POLICER_FULL_WRITE_REQUEST_AN_MASK 1 64 #define IPE_POLICER_FULL_WRITE_REQUEST_AN_SHIFT 29 66 #define IPE_POLICER_FULL_WRITE_REQUEST_REXP_OFFSET 8 67 #define IPE_POLICER_FULL_WRITE_REQUEST_REXP_MASK 4 68 #define IPE_POLICER_FULL_WRITE_REQUEST_REXP_SHIFT 22 70 #define IPE_POLICER_FULL_WRITE_REQUEST_ARM_OFFSET 9 71 #define IPE_POLICER_FULL_WRITE_REQUEST_ARM_MASK 11 72 #define IPE_POLICER_FULL_WRITE_REQUEST_ARM_SHIFT 11 74 #define IPE_POLICER_FULL_WRITE_REQUEST_PRM_OFFSET 10 75 #define IPE_POLICER_FULL_WRITE_REQUEST_PRM_MASK 11 76 #define IPE_POLICER_FULL_WRITE_REQUEST_PRM_SHIFT 0 78 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLE_OFFSET 12 79 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLE_MASK 5 80 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLE_SHIFT 27 82 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLM_OFFSET 12 83 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLM_MASK 7 84 #define IPE_POLICER_FULL_WRITE_REQUEST_CBLM_SHIFT 20 86 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLE_OFFSET 13 87 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLE_MASK 5 88 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLE_SHIFT 15 90 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLM_OFFSET 14 91 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLM_MASK 7 92 #define IPE_POLICER_FULL_WRITE_REQUEST_EBLM_SHIFT 8 94 #define IPE_POLICER_FULL_WRITE_REQUEST_CB_OFFSET 16 95 #define IPE_POLICER_FULL_WRITE_REQUEST_CB_MASK 31 96 #define IPE_POLICER_FULL_WRITE_REQUEST_CB_SHIFT 0 98 #define IPE_POLICER_FULL_WRITE_REQUEST_EB_OFFSET 20 99 #define IPE_POLICER_FULL_WRITE_REQUEST_EB_MASK 31 100 #define IPE_POLICER_FULL_WRITE_REQUEST_EB_SHIFT 0 102 #define IPE_RFC_RFC2697 0x00000000 103 #define IPE_RFC_RFC2698 0x00000001 104 #define IPE_RFC_RFC4115 0x00000002 105 #define IPE_RFC_MEF5CF1 0x00000003 110 #define QOS_POLICER_FIXED_PKT_SIZE 256 112 #define QOS_POL_TICKS_PER_SEC 1000LL 117 #define QOS_POL_DEF_BURST_BYTE 100 122 #define QOS_POL_MIN_BURST_BYTE 9 * 1024 128 #define QOS_POL_ALLOW_NEGATIVE 1 132 #define QOS_POL_COMM_BKT_MAX (1 << IPE_POLICER_FULL_WRITE_REQUEST_CB_MASK) 133 #define QOS_POL_EXTD_BKT_MAX (1 << IPE_POLICER_FULL_WRITE_REQUEST_EB_MASK) 135 #define QOS_POL_RATE_EXP_SIZE (IPE_POLICER_FULL_WRITE_REQUEST_REXP_MASK) 136 #define QOS_POL_RATE_EXP_MAX ((1 << QOS_POL_RATE_EXP_SIZE) - 1) 137 #define QOS_POL_AVG_RATE_MANT_SIZE (IPE_POLICER_FULL_WRITE_REQUEST_ARM_MASK) 138 #define QOS_POL_AVG_RATE_MANT_MAX ((1 << QOS_POL_AVG_RATE_MANT_SIZE) - 1) 139 #define QOS_POL_AVG_RATE_MAX \ 140 (QOS_POL_AVG_RATE_MANT_MAX << QOS_POL_RATE_EXP_MAX) 142 #define QOS_POL_PEAK_RATE_MANT_SIZE (IPE_POLICER_FULL_WRITE_REQUEST_PRM_MASK) 143 #define QOS_POL_PEAK_RATE_MANT_MAX ((1 << QOS_POL_PEAK_RATE_MANT_SIZE) - 1) 144 #define QOS_POL_PEAK_RATE_MAX \ 145 (QOS_POL_PEAK_RATE_MANT_MAX << QOS_POL_RATE_EXP_MAX) 147 #define QOS_POL_COMM_BKT_LIMIT_MANT_SIZE \ 148 (IPE_POLICER_FULL_WRITE_REQUEST_CBLM_MASK) 149 #define QOS_POL_COMM_BKT_LIMIT_MANT_MAX \ 150 ((1 << QOS_POL_COMM_BKT_LIMIT_MANT_SIZE) - 1) 151 #define QOS_POL_COMM_BKT_LIMIT_EXP_SIZE \ 152 (IPE_POLICER_FULL_WRITE_REQUEST_CBLE_MASK) 153 #define QOS_POL_COMM_BKT_LIMIT_EXP_MAX \ 154 ((1 << QOS_POL_COMM_BKT_LIMIT_EXP_SIZE) - 1) 155 #define QOS_POL_COMM_BKT_LIMIT_MAX \ 156 ((u64) QOS_POL_COMM_BKT_LIMIT_MANT_MAX \ 157 << (u64) QOS_POL_COMM_BKT_LIMIT_EXP_MAX) 159 #define QOS_POL_EXTD_BKT_LIMIT_MANT_SIZE \ 160 (IPE_POLICER_FULL_WRITE_REQUEST_EBLM_MASK) 161 #define QOS_POL_EXTD_BKT_LIMIT_MANT_MAX \ 162 ((1 << QOS_POL_EXTD_BKT_LIMIT_MANT_SIZE) - 1) 163 #define QOS_POL_EXTD_BKT_LIMIT_EXP_SIZE \ 164 (IPE_POLICER_FULL_WRITE_REQUEST_EBLE_MASK) 165 #define QOS_POL_EXTD_BKT_LIMIT_EXP_MAX \ 166 ((1 << QOS_POL_EXTD_BKT_LIMIT_EXP_SIZE) - 1) 167 #define QOS_POL_EXT_BKT_LIMIT_MAX \ 168 ((u64) QOS_POL_EXTD_BKT_LIMIT_MANT_MAX \ 169 << (u64) QOS_POL_EXTD_BKT_LIMIT_EXP_MAX) 180 #define RATE256 (256114688000LL / 8LL / QOS_POL_TICKS_PER_SEC) 181 #define RATE128 (128057344000LL / 8LL / QOS_POL_TICKS_PER_SEC) 182 #define RATE64 (64028672000LL / 8LL / QOS_POL_TICKS_PER_SEC) 184 #define RATE_OVER256_UNIT 8LL 185 #define RATE_128TO256_UNIT 4LL 186 #define RATE_64TO128_UNIT 2LL 190 qos_round_type_en round_type)
194 if (denominator == 0)
203 *rounded_value = ((numerator + (denominator >> 1)) / denominator);
207 *rounded_value = (numerator / denominator);
208 if ((*rounded_value * denominator) < numerator)
215 *rounded_value = (numerator / denominator);
230 u64 numer, denom, rnd_value;
253 cir_hw = (
u32) rnd_value;
262 eir_hw = (
u32) rnd_value;
267 "max supported value (%u)",
275 "max supported value (%u). Capping it to the max. " 283 if ((cfg->
rb.
kbps.cir_kbps == 0) && cfg->
rb.
kbps.cb_bytes)
289 if ((cfg->
rb.
kbps.eir_kbps == 0) &&
314 u16 max_mant_value, qos_round_type_en
type,
326 while (temp_exp <= max_exp_value)
328 if (temp_mant <= max_mant_value)
337 temp_mant = rnd_value;
340 if (temp_exp > max_exp_value)
346 temp_mant = max_mant_value;
350 *mant = (
u32) temp_mant;
352 QOS_DEBUG_INFO (
"value: 0x%llx, mant: %u, exp: %u", value, *mant, *exp);
361 u32 cir_hw, eir_hw, hi_mant, hi_rate, cir_rnded, eir_rnded, eir_kbps;
362 u64 numer, denom, rnd_value;
378 cir_hw = (
u32) rnd_value;
380 if (cfg->
rb.
kbps.cir_kbps && (cir_hw == 0))
394 eir_kbps = cfg->
rb.
kbps.cir_kbps;
398 eir_kbps = cfg->
rb.
kbps.eir_kbps - cfg->
rb.
kbps.cir_kbps;
402 eir_kbps = cfg->
rb.
kbps.eir_kbps;
405 numer = (
u64) eir_kbps;
413 eir_hw = (
u32) rnd_value;
415 if (eir_kbps && (eir_hw == 0))
423 QOS_DEBUG_INFO (
"cir_hw: %u bytes/tick, eir_hw: %u bytes/tick", cir_hw,
435 if ((cir_hw == 0) && (eir_hw == 0))
453 denom = (1ULL <<
exp);
454 if (hi_rate == eir_hw)
499 "kbps (mant: %u, exp: %u, rate: %u bytes/tick)",
504 "kbps (mant: %u, exp: %u, rate: %u bytes/tick)",
536 return (bkt_max - 1);
593 u64 bkt_max = max_bkt_value;
598 bkt_limit_max = ((
u64) max_mant_value << (
u64) max_exp_value);
600 bkt_max =
MIN (bkt_max, bkt_limit_max);
610 if (cfg_burst > bkt_max)
613 "supported value 0x%llx bytes. Capping it to the " 626 "supported value %u bytes. Rounding it up to " 636 rnd_burst = ((
u64) (*mant) << (
u64) (*exp));
638 *bkt_value = (
u32) temp_bkt_value;
646 u32 temp_mant, rate_hw;
658 &temp_exp, &temp_mant, &bkt_value);
659 QOS_DEBUG_INFO (
"Committed burst, burst_limit: 0x%llx mant : %u, " 660 "exp: %u, rnded: 0x%llx cb:%u bytes",
661 cfg->
rb.
kbps.cb_bytes, temp_mant, temp_exp,
662 ((
u64) temp_mant << (
u64) temp_exp), bkt_value);
683 "Excess burst, burst: 0x%llx mant: %u, " 684 "exp: %u, rnded: 0x%llx bytes",
692 eb_bytes = cfg->
rb.
kbps.cb_bytes + cfg->
rb.
kbps.eb_bytes;
696 eb_bytes = cfg->
rb.
kbps.eb_bytes - cfg->
rb.
kbps.cb_bytes;
700 eb_bytes = cfg->
rb.
kbps.eb_bytes;
707 &temp_mant, &bkt_value);
710 "exp: %u, rnded: 0x%llx eb:%u bytes",
711 cfg->
rb.
kbps.eb_bytes, temp_mant, temp_exp,
712 ((
u64) temp_mant << (
u64) temp_exp), bkt_value);
766 QOS_DEBUG_ERROR (
"Unable to convert config rates to hw. Error: %d", rc);
773 QOS_DEBUG_ERROR (
"Unable to convert config burst to hw. Error: %d", rc);
783 u64 numer, rnd_value = 0;
788 return ((
u32) rnd_value);
794 u64 numer, rnd_value = 0;
796 numer = (
u64) ((
u64) burst_ms * (
u64) rate_kbps);
800 return ((
u32) rnd_value);
856 return (
u64) cpu_freq;
873 u32 *cir_bytes_per_period,
u32 *pir_bytes_per_period,
877 double internal_cir_bytes_per_period;
878 double internal_pir_bytes_per_period;
882 u32 __attribute__ ((unused)) orig_current_limit = *current_limit;
891 internal_cir_bytes_per_period = (double) cir_rate / period;
892 internal_pir_bytes_per_period = (double) pir_rate / period;
904 #define MAX_RATE_SHIFT 10 905 max =
MAX (*current_limit, *extended_limit);
908 scale_shift = __builtin_clz (max);
910 scale_amount = 1 << scale_shift;
911 *scale = scale_shift;
914 *current_limit = *current_limit << scale_shift;
915 *extended_limit = *extended_limit << scale_shift;
918 internal_cir_bytes_per_period =
919 internal_cir_bytes_per_period * ((double) scale_amount);
920 internal_pir_bytes_per_period =
921 internal_pir_bytes_per_period * ((double) scale_amount);
927 if (internal_cir_bytes_per_period < 1.0)
929 internal_cir_bytes_per_period = 1.0;
931 if (internal_pir_bytes_per_period < 1.0)
933 internal_pir_bytes_per_period = 1.0;
936 *cir_bytes_per_period = (
u32) internal_cir_bytes_per_period;
937 *pir_bytes_per_period = (
u32) internal_pir_bytes_per_period;
951 const int BYTES_PER_KBIT = (1000 / 8);
969 (cfg->
rb.
kbps.cb_bytes > 0xFFFFFFFF) ? 0xFFFFFFFF : cfg->
rb.
kbps.cb_bytes;
972 (cfg->
rb.
kbps.eb_bytes > 0xFFFFFFFF) ? 0xFFFFFFFF : cfg->
rb.
kbps.eb_bytes;
975 if ((cfg->
rb.
kbps.cir_kbps == 0) && (cfg->
rb.
kbps.cb_bytes == 0)
976 && (cfg->
rb.
kbps.eb_bytes == 0))
996 if ((cfg->
rb.
kbps.cir_kbps == 0) ||
997 (cfg->
rb.
kbps.eir_kbps != 0) ||
998 ((cfg->
rb.
kbps.cb_bytes == 0) && (cfg->
rb.
kbps.eb_bytes == 0)))
1020 if ((cfg->
rb.
kbps.cir_kbps == 0) || (cfg->
rb.
kbps.eir_kbps == 0)
1022 || (cfg->
rb.
kbps.cb_bytes == 0) || (cfg->
rb.
kbps.eb_bytes == 0))
1045 "Config parameter validation failed. RFC not supported");
1085 kbps_cfg.
rb.
kbps.cir_kbps =
1087 kbps_cfg.
rb.
kbps.eir_kbps =
1148 if ((hw == NULL) || (cfg == NULL))
1185 cfg->
rb.
kbps.cir_kbps = (
u32) temp_rate;
1190 cfg->
rb.
kbps.eir_kbps = (
u32) temp_rate;
1204 cfg->
rb.
kbps.eir_kbps = 0;
1221 QOS_DEBUG_INFO (
"configured params, cir: %u kbps, eir: %u kbps, cb " 1222 "burst: 0x%llx bytes, eb burst: 0x%llx bytes",
1232 u64 numer, denom, rnd_value = 0;
1234 numer = (
u64) ((
u64) rate_kbps * 1000LL);
1239 return ((
u32) rnd_value);
1245 u64 numer, denom, rnd_value = 0;
1247 numer = burst_bytes * 8LL;
1248 denom = (
u64) rate_kbps;
1252 return ((
u32) rnd_value);
1298 cfg->
rb.
pps.cir_pps =
1300 cfg->
rb.
pps.eir_pps =
#define QOS_POL_AVG_RATE_MANT_MAX
int pol_logical_2_physical(qos_pol_cfg_params_st *cfg, policer_t *phys)
static int pol_convert_cfg_burst_to_hw(qos_pol_cfg_params_st *cfg, qos_pol_hw_params_st *hw)
int x86_pol_compute_hw_params(qos_pol_cfg_params_st *cfg, policer_t *hw)
qos_pol_action_params_st exceed_action
Optimized string handling code, including c11-compliant "safe C library" variants.
#define QOS_POL_EXTD_BKT_LIMIT_EXP_MAX
static int pol_convert_cfg_to_hw_params(qos_pol_cfg_params_st *cfg, qos_pol_hw_params_st *hw)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define QOS_POL_PEAK_RATE_MAX
qos_round_type_en rnd_type
#define QOS_POL_COMM_BKT_MAX
u32 cir_tokens_per_period
#define QOS_POL_AVG_RATE_MAX
qos_action_type_en action_type
static int compute_policer_params(u64 hz, u64 cir_rate, u64 pir_rate, u32 *current_limit, u32 *extended_limit, u32 *cir_bytes_per_period, u32 *pir_bytes_per_period, u32 *scale)
u32 qos_convert_burst_bytes_to_ms(u64 burst_bytes, u32 rate_kbps)
u32 qos_convert_burst_ms_to_bytes(u32 burst_ms, u32 rate_kbps)
struct qos_pol_cfg_params_st_::@490::@491 kbps
qos_rate_type_en rate_type
#define QOS_POL_TICKS_PER_SEC
#define RATE_128TO256_UNIT
#define QOS_POL_MIN_BURST_BYTE
u64 pol_get_bkt_value(u64 rate_hw, u64 byte_value)
vl_api_fib_path_type_t type
static void qos_convert_pol_bucket_to_hw_fmt(policer_t *bkt, qos_pol_hw_params_st *hw_fmt)
#define QOS_POL_DEF_BURST_BYTE
qos_action_type_en action[3]
#define QOS_POL_EXTD_BKT_LIMIT_MANT_MAX
int pol_compute_hw_params(qos_pol_cfg_params_st *cfg, qos_pol_hw_params_st *hw)
#define QOS_POL_COMM_BKT_LIMIT_EXP_MAX
u64 pol_get_bkt_max(u64 rate_hw, u64 bkt_max)
u32 pir_tokens_per_period
static void qos_convert_value_to_exp_mant_fmt(u64 value, u16 max_exp_value, u16 max_mant_value, qos_round_type_en type, u8 *exp, u32 *mant)
static int qos_pol_round(u64 numerator, u64 denominator, u64 *rounded_value, qos_round_type_en round_type)
#define QOS_POL_RATE_EXP_MAX
#define RATE_OVER256_UNIT
#define RATE_64TO128_UNIT
qos_pol_action_params_st conform_action
#define QOS_POL_COMM_BKT_LIMIT_MANT_MAX
static u64 get_tsc_hz(void)
#define QOS_POL_EXTD_BKT_MAX
#define QOS_DEBUG_ERROR(msg, args...)
u32 qos_convert_kbps_to_pps(u32 rate_kbps)
struct qos_pol_cfg_params_st_::@490::@492 pps
union qos_pol_cfg_params_st_::@490 rb
#define QOS_DEBUG_INFO(msg, args...)
#define POLICER_TICKS_PER_PERIOD
#define QOS_POL_ALLOW_NEGATIVE
static void pol_rnd_burst_byte_fmt(u64 cfg_burst, u16 max_exp_value, u16 max_mant_value, u32 max_bkt_value, u32 rate_hw, u8 *exp, u32 *mant, u32 *bkt_value)
static int pol_convert_hw_to_cfg_params(qos_pol_hw_params_st *hw, qos_pol_cfg_params_st *cfg)
static int pol_convert_cfg_rates_to_hw(qos_pol_cfg_params_st *cfg, qos_pol_hw_params_st *hw)
#define QOS_POLICER_FIXED_PKT_SIZE
int pol_physical_2_logical(policer_t *phys, qos_pol_cfg_params_st *cfg)
static int pol_validate_cfg_params(qos_pol_cfg_params_st *cfg)
f64 os_cpu_clock_frequency(void)
u32 qos_convert_pps_to_kbps(u32 rate_pps)
qos_pol_action_params_st violate_action