Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2010-2014 Intel Corporation 3 : : */ 4 : : 5 : : #include <math.h> 6 : : #include <eal_export.h> 7 : : #include "rte_red.h" 8 : : #include <rte_random.h> 9 : : #include <rte_common.h> 10 : : 11 : : static int rte_red_init_done = 0; /**< Flag to indicate that global initialisation is done */ 12 : : RTE_EXPORT_SYMBOL(rte_red_rand_val) 13 : : uint32_t rte_red_rand_val = 0; /**< Random value cache */ 14 : : RTE_EXPORT_SYMBOL(rte_red_rand_seed) 15 : : uint32_t rte_red_rand_seed = 0; /**< Seed for random number generation */ 16 : : 17 : : /** 18 : : * table[i] = log2(1-Wq) * Scale * -1 19 : : * Wq = 1/(2^i) 20 : : */ 21 : : RTE_EXPORT_SYMBOL(rte_red_log2_1_minus_Wq) 22 : : uint16_t rte_red_log2_1_minus_Wq[RTE_RED_WQ_LOG2_NUM]; 23 : : 24 : : /** 25 : : * table[i] = 2^(i/16) * Scale 26 : : */ 27 : : RTE_EXPORT_SYMBOL(rte_red_pow2_frac_inv) 28 : : uint16_t rte_red_pow2_frac_inv[16]; 29 : : 30 : : /** 31 : : * @brief Initialize tables used to compute average 32 : : * queue size when queue is empty. 33 : : */ 34 : : static void 35 : 0 : __rte_red_init_tables(void) 36 : : { 37 : : uint32_t i = 0; 38 : : double scale = 0.0; 39 : : double table_size = 0.0; 40 : : 41 : : scale = (double)(1 << RTE_RED_SCALING); 42 : : table_size = (double)(RTE_DIM(rte_red_pow2_frac_inv)); 43 : : 44 [ # # ]: 0 : for (i = 0; i < RTE_DIM(rte_red_pow2_frac_inv); i++) { 45 : 0 : double m = (double)i; 46 : : 47 : 0 : rte_red_pow2_frac_inv[i] = (uint16_t) round(scale / pow(2, m / table_size)); 48 : : } 49 : : 50 : : scale = 1024.0; 51 : : 52 : : RTE_ASSERT(RTE_RED_WQ_LOG2_NUM == RTE_DIM(rte_red_log2_1_minus_Wq)); 53 : : 54 [ # # ]: 0 : for (i = RTE_RED_WQ_LOG2_MIN; i <= RTE_RED_WQ_LOG2_MAX; i++) { 55 : 0 : double n = (double)i; 56 : 0 : double Wq = pow(2, -n); 57 : 0 : uint32_t index = i - RTE_RED_WQ_LOG2_MIN; 58 : : 59 : 0 : rte_red_log2_1_minus_Wq[index] = (uint16_t) round(-1.0 * scale * log2(1.0 - Wq)); 60 : : /** 61 : : * Table entry of zero, corresponds to a Wq of zero 62 : : * which is not valid (avg would remain constant no 63 : : * matter how long the queue is empty). So we have 64 : : * to check for zero and round up to one. 65 : : */ 66 [ # # ]: 0 : if (rte_red_log2_1_minus_Wq[index] == 0) { 67 : 0 : rte_red_log2_1_minus_Wq[index] = 1; 68 : : } 69 : : } 70 : 0 : } 71 : : 72 : : RTE_EXPORT_SYMBOL(rte_red_rt_data_init) 73 : : int 74 : 0 : rte_red_rt_data_init(struct rte_red *red) 75 : : { 76 [ # # ]: 0 : if (red == NULL) 77 : : return -1; 78 : : 79 : 0 : red->avg = 0; 80 : 0 : red->count = 0; 81 : 0 : red->q_time = 0; 82 : 0 : return 0; 83 : : } 84 : : 85 : : RTE_EXPORT_SYMBOL(rte_red_config_init) 86 : : int 87 : 0 : rte_red_config_init(struct rte_red_config *red_cfg, 88 : : const uint16_t wq_log2, 89 : : const uint16_t min_th, 90 : : const uint16_t max_th, 91 : : const uint16_t maxp_inv) 92 : : { 93 [ # # ]: 0 : if (red_cfg == NULL) { 94 : : return -1; 95 : : } 96 [ # # ]: 0 : if (max_th > RTE_RED_MAX_TH_MAX) { 97 : : return -2; 98 : : } 99 [ # # ]: 0 : if (min_th >= max_th) { 100 : : return -3; 101 : : } 102 [ # # ]: 0 : if (wq_log2 > RTE_RED_WQ_LOG2_MAX) { 103 : : return -4; 104 : : } 105 [ # # ]: 0 : if (wq_log2 < RTE_RED_WQ_LOG2_MIN) { 106 : : return -5; 107 : : } 108 [ # # ]: 0 : if (maxp_inv < RTE_RED_MAXP_INV_MIN) { 109 : : return -6; 110 : : } 111 [ # # ]: 0 : if (maxp_inv > RTE_RED_MAXP_INV_MAX) { 112 : : return -7; 113 : : } 114 : : 115 : : /** 116 : : * Initialize the RED module if not already done 117 : : */ 118 [ # # ]: 0 : if (!rte_red_init_done) { 119 : 0 : rte_red_rand_seed = rte_rand(); 120 : 0 : rte_red_rand_val = rte_fast_rand(); 121 : 0 : __rte_red_init_tables(); 122 : 0 : rte_red_init_done = 1; 123 : : } 124 : : 125 : 0 : red_cfg->min_th = ((uint32_t) min_th) << (wq_log2 + RTE_RED_SCALING); 126 : 0 : red_cfg->max_th = ((uint32_t) max_th) << (wq_log2 + RTE_RED_SCALING); 127 : 0 : red_cfg->pa_const = (2 * (max_th - min_th) * maxp_inv) << RTE_RED_SCALING; 128 : 0 : red_cfg->maxp_inv = maxp_inv; 129 : 0 : red_cfg->wq_log2 = wq_log2; 130 : : 131 : 0 : return 0; 132 : : }