[dpdk-dev] [PATCH v4] sched: make RED scaling configurable
Dumitrescu, Cristian
cristian.dumitrescu at intel.com
Tue Jan 2 17:21:51 CET 2018
> -----Original Message-----
> From: Dumitrescu, Cristian
> Sent: Tuesday, October 3, 2017 6:16 PM
> To: alangordondewar at gmail.com; Kantecki, Tomasz
> <tomasz.kantecki at intel.com>
> Cc: dev at dpdk.org; Alan Dewar <alan.dewar at att.com>
> Subject: RE: [PATCH v4] sched: make RED scaling configurable
>
> Adding Tomasz.
>
> > -----Original Message-----
> > From: alangordondewar at gmail.com
> [mailto:alangordondewar at gmail.com]
> > Sent: Tuesday, October 3, 2017 10:22 AM
> > To: Dumitrescu, Cristian <cristian.dumitrescu at intel.com>
> > Cc: dev at dpdk.org; Alan Dewar <alan.dewar at att.com>
> > Subject: [PATCH v4] sched: make RED scaling configurable
> >
> > From: Alan Dewar <alan.dewar at 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.dewar at 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
Tomasz,
Any feedback from you?
Regards,
Cristian
More information about the dev
mailing list