Adding Tomasz.
> -----Original Message-----
> From: alangordonde...@gmail.com [mailto:alangordonde...@gmail.com]
> Sent: Tuesday, October 3, 2017 10:22 AM
> To: Dumitrescu, Cristian <cristian.dumitre...@intel.com>
> Cc: dev@dpdk.org; Alan Dewar <alan.de...@att.com>
> Subject: [PATCH v4] sched: make RED scaling configurable
>
> From: Alan Dewar <alan.de...@att.com>
>
> The RED code stores the weighted moving average in a 32-bit integer as
> a pseudo fixed-point floating number with 10 fractional bits. Twelve
> other bits are used to encode the filter weight, leaving just 10 bits
> for the queue length. This limits the maximum queue length supported
> by RED queues to 1024 packets.
>
> Introduce a new API to allow the RED scaling factor to be configured
> based upon maximum queue length. If this API is not called, the RED
> scaling factor remains at its default value.
>
> Added some new RED scaling unit-tests to test with RED queue-lengths
> up to 8192 packets long.
>
> Signed-off-by: Alan Dewar <alan.de...@att.com>
> ---
> lib/librte_sched/rte_red.c | 53 ++++++-
> lib/librte_sched/rte_red.h | 63 ++++++--
> lib/librte_sched/rte_sched_version.map | 6 +
> test/test/test_red.c | 274
> ++++++++++++++++++++++++++++++++-
> 4 files changed, 374 insertions(+), 22 deletions(-)
>
> diff --git a/lib/librte_sched/rte_red.c b/lib/librte_sched/rte_red.c
> index ade57d1..0dc8d28 100644
> --- a/lib/librte_sched/rte_red.c
> +++ b/lib/librte_sched/rte_red.c
> @@ -43,6 +43,8 @@
> static int rte_red_init_done = 0; /**< Flag to indicate that global
> initialisation is done */
> uint32_t rte_red_rand_val = 0; /**< Random value cache */
> uint32_t rte_red_rand_seed = 0; /**< Seed for random number
> generation */
> +uint8_t rte_red_scaling = RTE_RED_SCALING_DEFAULT;
> +uint16_t rte_red_max_threshold = RTE_RED_DEFAULT_QUEUE_LENGTH -
> 1;
>
> /**
> * table[i] = log2(1-Wq) * Scale * -1
> @@ -66,7 +68,7 @@ __rte_red_init_tables(void)
> double scale = 0.0;
> double table_size = 0.0;
>
> - scale = (double)(1 << RTE_RED_SCALING);
> + scale = (double)(1 << rte_red_scaling);
> table_size = (double)(RTE_DIM(rte_red_pow2_frac_inv));
>
> for (i = 0; i < RTE_DIM(rte_red_pow2_frac_inv); i++) {
> @@ -119,7 +121,7 @@ rte_red_config_init(struct rte_red_config *red_cfg,
> if (red_cfg == NULL) {
> return -1;
> }
> - if (max_th > RTE_RED_MAX_TH_MAX) {
> + if (max_th > rte_red_max_threshold) {
> return -2;
> }
> if (min_th >= max_th) {
> @@ -148,11 +150,52 @@ rte_red_config_init(struct rte_red_config
> *red_cfg,
> rte_red_init_done = 1;
> }
>
> - red_cfg->min_th = ((uint32_t) min_th) << (wq_log2 +
> RTE_RED_SCALING);
> - red_cfg->max_th = ((uint32_t) max_th) << (wq_log2 +
> RTE_RED_SCALING);
> - red_cfg->pa_const = (2 * (max_th - min_th) * maxp_inv) <<
> RTE_RED_SCALING;
> + red_cfg->min_th = ((uint32_t) min_th) << (wq_log2 +
> rte_red_scaling);
> + red_cfg->max_th = ((uint32_t) max_th) << (wq_log2 +
> rte_red_scaling);
> + red_cfg->pa_const = (2 * (max_th - min_th) * maxp_inv) <<
> + rte_red_scaling;
> red_cfg->maxp_inv = maxp_inv;
> red_cfg->wq_log2 = wq_log2;
>
> return 0;
> }
> +
> +int
> +rte_red_set_scaling(uint16_t max_red_queue_length)
> +{
> + int8_t count;
> +
> + if (rte_red_init_done)
> + /**
> + * Can't change the scaling once the red table has been
> + * computed.
> + */
> + return -1;
> +
> + if (max_red_queue_length < RTE_RED_MIN_QUEUE_LENGTH)
> + return -2;
> +
> + if (max_red_queue_length > RTE_RED_MAX_QUEUE_LENGTH)
> + return -3;
> +
> + if (!rte_is_power_of_2(max_red_queue_length))
> + return -4;
> +
> + count = 0;
> + while (max_red_queue_length != 0) {
> + max_red_queue_length >>= 1;
> + count++;
> + }
> +
> + rte_red_scaling -= count - RTE_RED_SCALING_DEFAULT;
> + rte_red_max_threshold = max_red_queue_length - 1;
> + return 0;
> +}
> +
> +void
> +rte_red_reset_scaling(void)
> +{
> + rte_red_init_done = 0;
> + rte_red_scaling = RTE_RED_SCALING_DEFAULT;
> + rte_red_max_threshold = RTE_RED_DEFAULT_QUEUE_LENGTH - 1;
> +}
> diff --git a/lib/librte_sched/rte_red.h b/lib/librte_sched/rte_red.h
> index ca12227..be1fb0f 100644
> --- a/lib/librte_sched/rte_red.h
> +++ b/lib/librte_sched/rte_red.h
> @@ -52,14 +52,31 @@ extern "C" {
> #include <rte_cycles.h>
> #include <rte_branch_prediction.h>
>
> -#define RTE_RED_SCALING 10 /**< Fraction size
> for fixed-
> point */
> -#define RTE_RED_S (1 << 22) /**< Packet size
> multiplied by
> number of leaf queues */
> -#define RTE_RED_MAX_TH_MAX 1023 /**< Max threshold
> limit
> in fixed point format */
> -#define RTE_RED_WQ_LOG2_MIN 1 /**< Min inverse
> filter
> weight value */
> -#define RTE_RED_WQ_LOG2_MAX 12 /**< Max inverse
> filter
> weight value */
> -#define RTE_RED_MAXP_INV_MIN 1 /**< Min inverse mark
> probability value */
> -#define RTE_RED_MAXP_INV_MAX 255 /**< Max inverse mark
> probability value */
> -#define RTE_RED_2POW16 (1<<16) /**< 2 power 16 */
> +/**< Default fraction size for fixed-point */
> +#define RTE_RED_SCALING_DEFAULT 10
> +
> +/**< Packet size multiplied by number of leaf queues */
> +#define RTE_RED_S (1 << 22)
> +
> +/**< Minimum, default and maximum RED queue length */
> +#define RTE_RED_MIN_QUEUE_LENGTH 64
> +#define RTE_RED_DEFAULT_QUEUE_LENGTH 1024
> +#define RTE_RED_MAX_QUEUE_LENGTH 8192
> +
> +/**< Min inverse filter weight value */
> +#define RTE_RED_WQ_LOG2_MIN 1
> +
> +/**< Max inverse filter weight value */
> +#define RTE_RED_WQ_LOG2_MAX 12
> +
> +/**< Min inverse mark probability value */
> +#define RTE_RED_MAXP_INV_MIN 1
> +
> +/**< Max inverse mark probability value */
> +#define RTE_RED_MAXP_INV_MAX 255
> +
> +/**< 2 power 16 */
> +#define RTE_RED_2POW16 (1<<16)
> #define RTE_RED_INT16_NBITS (sizeof(uint16_t) * CHAR_BIT)
> #define RTE_RED_WQ_LOG2_NUM (RTE_RED_WQ_LOG2_MAX -
> RTE_RED_WQ_LOG2_MIN + 1)
>
> @@ -71,6 +88,8 @@ extern uint32_t rte_red_rand_val;
> extern uint32_t rte_red_rand_seed;
> extern uint16_t rte_red_log2_1_minus_Wq[RTE_RED_WQ_LOG2_NUM];
> extern uint16_t rte_red_pow2_frac_inv[16];
> +extern uint8_t rte_red_scaling;
> +extern uint16_t rte_red_max_threshold;
>
> /**
> * RED configuration parameters passed by user
> @@ -137,6 +156,26 @@ rte_red_config_init(struct rte_red_config *red_cfg,
> const uint16_t maxp_inv);
>
> /**
> + * @brief Configures the global setting for the RED scaling factor
> + *
> + * @param max_red_queue_length [in] must be a power of two
> + *
> + * @return Operation status
> + * @retval 0 success
> + * @retval !0 error
> + */
> +int
> +rte_red_set_scaling(uint16_t max_red_queue_length);
> +
> +/**
> + * @brief Reset the RED scaling factor - only for use by RED unit-tests
> + *
> + * @return Operation status
> + */
> +void
> +rte_red_reset_scaling(void);
> +
> +/**
> * @brief Generate random number for RED
> *
> * Implemenetation based on:
> @@ -206,7 +245,7 @@ __rte_red_calc_qempty_factor(uint8_t wq_log2,
> uint16_t m)
> f = (n >> 6) & 0xf;
> n >>= 10;
>
> - if (n < RTE_RED_SCALING)
> + if (n < rte_red_scaling)
> return (uint16_t) ((rte_red_pow2_frac_inv[f] + (1 << (n - 1)))
> >> n);
>
> return 0;
> @@ -258,7 +297,9 @@ rte_red_enqueue_empty(const struct
> rte_red_config *red_cfg,
> if (m >= RTE_RED_2POW16) {
> red->avg = 0;
> } else {
> - red->avg = (red->avg >> RTE_RED_SCALING) *
> __rte_red_calc_qempty_factor(red_cfg->wq_log2, (uint16_t) m);
> + red->avg = (red->avg >> rte_red_scaling) *
> + __rte_red_calc_qempty_factor(red_cfg->wq_log2,
> + (uint16_t) m);
> }
>
> return 0;
> @@ -365,7 +406,7 @@ rte_red_enqueue_nonempty(const struct
> rte_red_config *red_cfg,
> */
>
> /* avg update */
> - red->avg += (q << RTE_RED_SCALING) - (red->avg >> red_cfg-
> >wq_log2);
> + red->avg += (q << rte_red_scaling) - (red->avg >> red_cfg-
> >wq_log2);
>
> /* avg < min_th: do not mark the packet */
> if (red->avg < red_cfg->min_th) {
> diff --git a/lib/librte_sched/rte_sched_version.map
> b/lib/librte_sched/rte_sched_version.map
> index 3aa159a..92e51f8 100644
> --- a/lib/librte_sched/rte_sched_version.map
> +++ b/lib/librte_sched/rte_sched_version.map
> @@ -29,3 +29,9 @@ DPDK_2.1 {
> rte_sched_port_pkt_read_color;
>
> } DPDK_2.0;
> +
> +DPDK_17.08 {
> + global;
> +
> + rte_red_set_scaling;
> +} DPDK_2.1;
> diff --git a/test/test/test_red.c b/test/test/test_red.c
> index 348075d..f2d50ef 100644
> --- a/test/test/test_red.c
> +++ b/test/test/test_red.c
> @@ -67,6 +67,7 @@ struct test_rte_red_config { /**< Test structure for
> RTE_RED config */
> uint32_t min_th; /**< Queue minimum threshold */
> uint32_t max_th; /**< Queue maximum threshold */
> uint8_t *maxp_inv; /**< Inverse mark probability */
> + uint16_t max_queue_len; /**< Maximum queue length */
> };
>
> struct test_queue { /**< Test structure for RTE_RED Queues */
> @@ -181,7 +182,7 @@ static uint32_t rte_red_get_avg_int(const struct
> rte_red_config *red_cfg,
> /**
> * scale by 1/n and convert from fixed-point to integer
> */
> - return red->avg >> (RTE_RED_SCALING + red_cfg->wq_log2);
> + return red->avg >> (rte_red_scaling + red_cfg->wq_log2);
> }
>
> static double rte_red_get_avg_float(const struct rte_red_config *red_cfg,
> @@ -190,7 +191,7 @@ static double rte_red_get_avg_float(const struct
> rte_red_config *red_cfg,
> /**
> * scale by 1/n and convert from fixed-point to floating-point
> */
> - return ldexp((double)red->avg, -(RTE_RED_SCALING + red_cfg-
> >wq_log2));
> + return ldexp((double)red->avg, -(rte_red_scaling + red_cfg-
> >wq_log2));
> }
>
> static void rte_red_set_avg_int(const struct rte_red_config *red_cfg,
> @@ -200,7 +201,7 @@ static void rte_red_set_avg_int(const struct
> rte_red_config *red_cfg,
> /**
> * scale by n and convert from integer to fixed-point
> */
> - red->avg = avg << (RTE_RED_SCALING + red_cfg->wq_log2);
> + red->avg = avg << (rte_red_scaling + red_cfg->wq_log2);
> }
>
> static double calc_exp_avg_on_empty(double avg, uint32_t n, uint32_t
> time_diff)
> @@ -280,10 +281,23 @@ static enum test_result
> test_rte_red_init(struct test_config *tcfg)
> {
> unsigned i = 0;
> + int ret;
>
> tcfg->tvar->clk_freq = rte_get_timer_hz();
> init_port_ts( tcfg->tvar->clk_freq );
>
> + rte_red_reset_scaling();
> + ret = rte_red_set_scaling(tcfg->tconfig->max_queue_len);
> + if (ret) {
> + printf("rte_red_set_scaling failed: %d\n", ret);
> + return FAIL;
> + }
> + if (rte_red_max_threshold < tcfg->tconfig->max_th) {
> + printf("rte_red_max_th (%u) < tconfig->max_th (%u)\n",
> + rte_red_max_threshold, tcfg->tconfig->max_th);
> + return FAIL;
> + }
> +
> for (i = 0; i < tcfg->tconfig->num_cfg; i++) {
> if (rte_red_config_init(&tcfg->tconfig->rconfig[i],
> (uint16_t)tcfg->tconfig->wq_log2[i],
> @@ -385,6 +399,7 @@ static struct test_rte_red_config ft_tconfig = {
> .min_th = 32,
> .max_th = 128,
> .maxp_inv = ft_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_queue ft_tqueue = {
> @@ -554,6 +569,7 @@ static struct test_rte_red_config ft2_tconfig = {
> .min_th = 32,
> .max_th = 128,
> .maxp_inv = ft2_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_config func_test2_config = {
> @@ -576,6 +592,41 @@ static struct test_config func_test2_config = {
> .tlevel = ft2_tlevel,
> };
>
> +/**
> + * Test F2: functional test 2 - with long queues and smaller red-scaling
> factor
> + */
> +static uint32_t ft2_tlevel_scaling[] = {8190};
> +
> +static struct test_rte_red_config ft2_tconfig_scaling = {
> + .rconfig = ft2_rconfig,
> + .num_cfg = RTE_DIM(ft2_rconfig),
> + .wq_log2 = ft2_wq_log2,
> + .min_th = 32,
> + .max_th = 8191,
> + .maxp_inv = ft2_maxp_inv,
> + .max_queue_len = 8192,
> +};
> +
> +static struct test_config func_test2_config_scaling = {
> + .ifname = "functional test 2 interface",
> + .msg = "functional test 2 : use several RED configurations and long
> queues,\n"
> + " increase average queue size to just below
> maximum threshold,\n"
> + " compare drop rate to drop probability\n\n",
> + .htxt = "RED config "
> + "avg queue size "
> + "min threshold "
> + "max threshold "
> + "drop prob % "
> + "drop rate % "
> + "diff % "
> + "tolerance % "
> + "\n",
> + .tconfig = &ft2_tconfig_scaling,
> + .tqueue = &ft_tqueue,
> + .tvar = &ft_tvar,
> + .tlevel = ft2_tlevel_scaling,
> +};
> +
> static enum test_result func_test2(struct test_config *tcfg)
> {
> enum test_result result = PASS;
> @@ -662,6 +713,7 @@ static struct test_rte_red_config ft3_tconfig = {
> .min_th = 32,
> .max_th = 1023,
> .maxp_inv = ft_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_config func_test3_config = {
> @@ -683,6 +735,40 @@ static struct test_config func_test3_config = {
> .tlevel = ft3_tlevel,
> };
>
> +/**
> + * Test F3: functional test 3 - with large queues and smaller red scaling
> factor
> + */
> +static uint32_t ft3_tlevel_scaling[] = {8190};
> +
> +static struct test_rte_red_config ft3_tconfig_scaling = {
> + .rconfig = ft_wrconfig,
> + .num_cfg = RTE_DIM(ft_wrconfig),
> + .wq_log2 = ft_wq_log2,
> + .min_th = 32,
> + .max_th = 8191,
> + .maxp_inv = ft_maxp_inv,
> + .max_queue_len = 8192,
> +};
> +
> +static struct test_config func_test3_config_scaling = {
> + .ifname = "functional test 3 interface",
> + .msg = "functional test 3 : use one RED configuration and long
> queues,\n"
> + " increase average queue size to target level,\n"
> + " dequeue all packets until queue is empty,\n"
> + " confirm that average queue size is computed
> correctly while queue is empty\n\n",
> + .htxt = "q avg before "
> + "q avg after "
> + "expected "
> + "difference % "
> + "tolerance % "
> + "result "
> + "\n",
> + .tconfig = &ft3_tconfig_scaling,
> + .tqueue = &ft_tqueue,
> + .tvar = &ft_tvar,
> + .tlevel = ft3_tlevel_scaling,
> +};
> +
> static enum test_result func_test3(struct test_config *tcfg)
> {
> enum test_result result = PASS;
> @@ -776,6 +862,7 @@ static struct test_rte_red_config ft4_tconfig = {
> .max_th = 1023,
> .wq_log2 = ft4_wq_log2,
> .maxp_inv = ft_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_queue ft4_tqueue = {
> @@ -810,6 +897,42 @@ static struct test_config func_test4_config = {
> .tlevel = ft4_tlevel,
> };
>
> +/**
> + * Test F4: functional test 4
> + */
> +static uint32_t ft4_tlevel_scaling[] = {8190};
> +
> +static struct test_rte_red_config ft4_tconfig_scaling = {
> + .rconfig = ft_wrconfig,
> + .num_cfg = RTE_DIM(ft_wrconfig),
> + .min_th = 32,
> + .max_th = 8191,
> + .wq_log2 = ft4_wq_log2,
> + .maxp_inv = ft_maxp_inv,
> + .max_queue_len = 8192,
> +};
> +
> +static struct test_config func_test4_config_scaling = {
> + .ifname = "functional test 4 interface",
> + .msg = "functional test 4 : use one RED configuration on long
> queue,\n"
> + " increase average queue size to target level,\n"
> + " dequeue all packets until queue is empty,\n"
> + " confirm that average queue size is computed
> correctly while\n"
> + " queue is empty for more than 50 sec,\n"
> + " (this test takes 52 sec to run)\n\n",
> + .htxt = "q avg before "
> + "q avg after "
> + "expected "
> + "difference % "
> + "tolerance % "
> + "result "
> + "\n",
> + .tconfig = &ft4_tconfig_scaling,
> + .tqueue = &ft4_tqueue,
> + .tvar = &ft_tvar,
> + .tlevel = ft4_tlevel_scaling,
> +};
> +
> static enum test_result func_test4(struct test_config *tcfg)
> {
> enum test_result result = PASS;
> @@ -924,6 +1047,7 @@ static struct test_rte_red_config ft5_tconfig = {
> .max_th = 128,
> .wq_log2 = ft5_wq_log2,
> .maxp_inv = ft5_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_queue ft5_tqueue = {
> @@ -970,6 +1094,45 @@ static struct test_config func_test5_config = {
> .tlevel = ft5_tlevel,
> };
>
> +
> +/**
> + * Test F5: functional test 5
> + */
> +static uint32_t ft5_tlevel_scaling[] = {8190};
> +
> +static struct test_rte_red_config ft5_tconfig_scaling = {
> + .rconfig = ft5_config,
> + .num_cfg = RTE_DIM(ft5_config),
> + .min_th = 32,
> + .max_th = 8191,
> + .wq_log2 = ft5_wq_log2,
> + .maxp_inv = ft5_maxp_inv,
> + .max_queue_len = 8192,
> +};
> +
> +static struct test_config func_test5_config_scaling = {
> + .ifname = "functional test 5 interface",
> + .msg = "functional test 5 : use several long queues (each with its own
> run-time data),\n"
> + " use several RED configurations (such that each
> configuration is shared by multiple queues),\n"
> + " increase average queue size to just below
> maximum threshold,\n"
> + " compare drop rate to drop probability,\n"
> + " (this is a larger scale version of functional test
> 2)\n\n",
> + .htxt = "queue "
> + "config "
> + "avg queue size "
> + "min threshold "
> + "max threshold "
> + "drop prob % "
> + "drop rate % "
> + "diff % "
> + "tolerance % "
> + "\n",
> + .tconfig = &ft5_tconfig_scaling,
> + .tqueue = &ft5_tqueue,
> + .tvar = &ft5_tvar,
> + .tlevel = ft5_tlevel_scaling,
> +};
> +
> static enum test_result func_test5(struct test_config *tcfg)
> {
> enum test_result result = PASS;
> @@ -1062,6 +1225,7 @@ static struct test_rte_red_config ft6_tconfig = {
> .max_th = 1023,
> .wq_log2 = ft6_wq_log2,
> .maxp_inv = ft6_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_queue ft6_tqueue = {
> @@ -1078,7 +1242,7 @@ static struct test_queue ft6_tqueue = {
> static struct test_config func_test6_config = {
> .ifname = "functional test 6 interface",
> .msg = "functional test 6 : use several queues (each with its own run-
> time data),\n"
> - " use several RED configurations (such that each
> configuration is sharte_red by multiple queues),\n"
> + " use several RED configurations (such that each
> configuration is shared by multiple queues),\n"
> " increase average queue size to target level,\n"
> " dequeue all packets until queue is empty,\n"
> " confirm that average queue size is computed
> correctly while queue is empty\n"
> @@ -1097,6 +1261,44 @@ static struct test_config func_test6_config = {
> .tlevel = ft6_tlevel,
> };
>
> +/**
> + * Test F6: functional test 6
> + */
> +static uint32_t ft6_tlevel_scaling[] = {8190};
> +
> +static struct test_rte_red_config ft6_tconfig_scaling = {
> + .rconfig = ft6_config,
> + .num_cfg = RTE_DIM(ft6_config),
> + .min_th = 32,
> + .max_th = 8191,
> + .wq_log2 = ft6_wq_log2,
> + .maxp_inv = ft6_maxp_inv,
> + .max_queue_len = 8192,
> +};
> +
> +static struct test_config func_test6_config_scaling = {
> + .ifname = "functional test 6 interface",
> + .msg = "functional test 6 : use several long queues (each with its own
> run-time data),\n"
> + " use several RED configurations (such that each
> configuration is shared by multiple queues),\n"
> + " increase average queue size to target level,\n"
> + " dequeue all packets until queue is empty,\n"
> + " confirm that average queue size is computed
> correctly while queue is empty\n"
> + " (this is a larger scale version of functional test
> 3)\n\n",
> + .htxt = "queue "
> + "config "
> + "q avg before "
> + "q avg after "
> + "expected "
> + "difference % "
> + "tolerance % "
> + "result "
> + "\n",
> + .tconfig = &ft6_tconfig_scaling,
> + .tqueue = &ft6_tqueue,
> + .tvar = &ft_tvar,
> + .tlevel = ft6_tlevel_scaling,
> +};
> +
> static enum test_result func_test6(struct test_config *tcfg)
> {
> enum test_result result = PASS;
> @@ -1195,6 +1397,7 @@ static struct test_rte_red_config pt_tconfig = {
> .min_th = 32,
> .max_th = 128,
> .maxp_inv = pt_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_queue pt_tqueue = {
> @@ -1557,6 +1760,7 @@ static struct test_rte_red_config ovfl_tconfig = {
> .min_th = 32,
> .max_th = 1023,
> .maxp_inv = ovfl_maxp_inv,
> + .max_queue_len = RTE_RED_DEFAULT_QUEUE_LENGTH,
> };
>
> static struct test_queue ovfl_tqueue = {
> @@ -1598,7 +1802,7 @@ static struct test_config ovfl_test1_config = {
> .ifname = "queue avergage overflow test interface",
> .msg = "overflow test 1 : use one RED configuration,\n"
> " increase average queue size to target level,\n"
> - " check maximum number of bits requirte_red to
> represent avg_s\n\n",
> + " check maximum number of bits required to
> represent avg_s\n\n",
> .htxt = "avg queue size "
> "wq_log2 "
> "fraction bits "
> @@ -1615,6 +1819,39 @@ static struct test_config ovfl_test1_config = {
> .tlevel = ovfl_tlevel,
> };
>
> +static uint32_t ovfl_tlevel_scaling[] = {8191};
> +
> +static struct test_rte_red_config ovfl_tconfig_scaling = {
> + .rconfig = ovfl_wrconfig,
> + .num_cfg = RTE_DIM(ovfl_wrconfig),
> + .wq_log2 = ovfl_wq_log2,
> + .min_th = 32,
> + .max_th = 8191,
> + .maxp_inv = ovfl_maxp_inv,
> + .max_queue_len = 8192,
> +};
> +
> +static struct test_config ovfl_test1_config_scaling = {
> + .ifname = "queue average overflow test interface",
> + .msg = "overflow test 1 on long queue: use one RED
> configuration,\n"
> + " increase average queue size to target level,\n"
> + " check maximum number of bits required to
> represent avg_s\n\n",
> + .htxt = "avg queue size "
> + "wq_log2 "
> + "fraction bits "
> + "max queue avg "
> + "num bits "
> + "enqueued "
> + "dropped "
> + "drop prob % "
> + "drop rate % "
> + "\n",
> + .tconfig = &ovfl_tconfig_scaling,
> + .tqueue = &ovfl_tqueue,
> + .tvar = &ovfl_tvar,
> + .tlevel = ovfl_tlevel_scaling,
> +};
> +
> static enum test_result ovfl_test1(struct test_config *tcfg)
> {
> enum test_result result = PASS;
> @@ -1690,7 +1927,7 @@ static enum test_result ovfl_test1(struct
> test_config *tcfg)
> printf("%s", tcfg->htxt);
>
> printf("%-16u%-9u%-15u0x%08x %-10u%-10u%-10u%-13.2lf%-
> 13.2lf\n",
> - avg, *tcfg->tconfig->wq_log2, RTE_RED_SCALING,
> + avg, *tcfg->tconfig->wq_log2, rte_red_scaling,
> avg_max, avg_max_bits,
> *tcfg->tvar->enqueued, *tcfg->tvar->dropped,
> drop_prob * 100.0, drop_rate * 100.0);
> @@ -1730,6 +1967,15 @@ struct tests perf_tests[] = {
> { &perf2_test6_config, perf2_test },
> };
>
> +struct tests scale_tests[] = {
> + { &func_test2_config_scaling, func_test2 },
> + { &func_test3_config_scaling, func_test3 },
> + { &func_test4_config_scaling, func_test4 },
> + { &func_test5_config_scaling, func_test5 },
> + { &func_test6_config_scaling, func_test6 },
> + { &ovfl_test1_config_scaling, ovfl_test1 },
> +};
> +
> /**
> * function to execute the required_red tests
> */
> @@ -1866,6 +2112,20 @@ test_red_perf(void)
> }
>
> static int
> +test_red_scaling(void)
> +{
> + uint32_t num_tests = 0;
> + uint32_t num_pass = 0;
> +
> + if (test_invalid_parameters() < 0)
> + return -1;
> +
> + run_tests(scale_tests, RTE_DIM(scale_tests), &num_tests,
> &num_pass);
> + show_stats(num_tests, num_pass);
> + return tell_the_result(num_tests, num_pass);
> +}
> +
> +static int
> test_red_all(void)
> {
> uint32_t num_tests = 0;
> @@ -1876,10 +2136,12 @@ test_red_all(void)
>
> run_tests(func_tests, RTE_DIM(func_tests), &num_tests,
> &num_pass);
> run_tests(perf_tests, RTE_DIM(perf_tests), &num_tests,
> &num_pass);
> + run_tests(scale_tests, RTE_DIM(scale_tests), &num_tests,
> &num_pass);
> show_stats(num_tests, num_pass);
> return tell_the_result(num_tests, num_pass);
> }
>
> REGISTER_TEST_COMMAND(red_autotest, test_red);
> REGISTER_TEST_COMMAND(red_perf, test_red_perf);
> +REGISTER_TEST_COMMAND(red_scaling, test_red_scaling);
> REGISTER_TEST_COMMAND(red_all, test_red_all);
> --
> 2.1.4