From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 91F558E01 for ; Tue, 2 Jan 2018 17:21:55 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Jan 2018 08:21:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,498,1508828400"; d="scan'208";a="163607926" Received: from irsmsx153.ger.corp.intel.com ([163.33.192.75]) by orsmga004.jf.intel.com with ESMTP; 02 Jan 2018 08:21:52 -0800 Received: from irsmsx108.ger.corp.intel.com ([169.254.11.167]) by IRSMSX153.ger.corp.intel.com ([169.254.9.34]) with mapi id 14.03.0319.002; Tue, 2 Jan 2018 16:21:51 +0000 From: "Dumitrescu, Cristian" To: "'alangordondewar@gmail.com'" , "Kantecki, Tomasz" CC: "'dev@dpdk.org'" , 'Alan Dewar' Thread-Topic: [PATCH v4] sched: make RED scaling configurable Thread-Index: AQHTPCkmMC45iwutMkmJVpgYoHqKcqLSXfRAgI71FHA= Date: Tue, 2 Jan 2018 16:21:51 +0000 Message-ID: <3EB4FA525960D640B5BDFFD6A3D891267BAF7F0A@IRSMSX108.ger.corp.intel.com> References: <1505913120-5521-1-git-send-email-alan.dewar@att.com> <1507022514-21831-1-git-send-email-alan.dewar@att.com> <3EB4FA525960D640B5BDFFD6A3D891267BAC7088@IRSMSX108.ger.corp.intel.com> In-Reply-To: <3EB4FA525960D640B5BDFFD6A3D891267BAC7088@IRSMSX108.ger.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [163.33.239.181] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v4] sched: make RED scaling configurable X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Jan 2018 16:21:56 -0000 > -----Original Message----- > From: Dumitrescu, Cristian > Sent: Tuesday, October 3, 2017 6:16 PM > To: alangordondewar@gmail.com; Kantecki, Tomasz > > Cc: dev@dpdk.org; Alan Dewar > Subject: RE: [PATCH v4] sched: make RED scaling configurable >=20 > Adding Tomasz. >=20 > > -----Original Message----- > > From: alangordondewar@gmail.com > [mailto:alangordondewar@gmail.com] > > Sent: Tuesday, October 3, 2017 10:22 AM > > To: Dumitrescu, Cristian > > Cc: dev@dpdk.org; Alan Dewar > > Subject: [PATCH v4] sched: make RED scaling configurable > > > > From: Alan Dewar > > > > 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 > > --- > > 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 =3D 0; /**< Flag to indicate that glo= bal > > initialisation is done */ > > uint32_t rte_red_rand_val =3D 0; /**< Random value cache */ > > uint32_t rte_red_rand_seed =3D 0; /**< Seed for random number > > generation */ > > +uint8_t rte_red_scaling =3D RTE_RED_SCALING_DEFAULT; > > +uint16_t rte_red_max_threshold =3D RTE_RED_DEFAULT_QUEUE_LENGTH > - > > 1; > > > > /** > > * table[i] =3D log2(1-Wq) * Scale * -1 > > @@ -66,7 +68,7 @@ __rte_red_init_tables(void) > > double scale =3D 0.0; > > double table_size =3D 0.0; > > > > - scale =3D (double)(1 << RTE_RED_SCALING); > > + scale =3D (double)(1 << rte_red_scaling); > > table_size =3D (double)(RTE_DIM(rte_red_pow2_frac_inv)); > > > > for (i =3D 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 =3D=3D NULL) { > > return -1; > > } > > - if (max_th > RTE_RED_MAX_TH_MAX) { > > + if (max_th > rte_red_max_threshold) { > > return -2; > > } > > if (min_th >=3D max_th) { > > @@ -148,11 +150,52 @@ rte_red_config_init(struct rte_red_config > > *red_cfg, > > rte_red_init_done =3D 1; > > } > > > > - red_cfg->min_th =3D ((uint32_t) min_th) << (wq_log2 + > > RTE_RED_SCALING); > > - red_cfg->max_th =3D ((uint32_t) max_th) << (wq_log2 + > > RTE_RED_SCALING); > > - red_cfg->pa_const =3D (2 * (max_th - min_th) * maxp_inv) << > > RTE_RED_SCALING; > > + red_cfg->min_th =3D ((uint32_t) min_th) << (wq_log2 + > > rte_red_scaling); > > + red_cfg->max_th =3D ((uint32_t) max_th) << (wq_log2 + > > rte_red_scaling); > > + red_cfg->pa_const =3D (2 * (max_th - min_th) * maxp_inv) << > > + rte_red_scaling; > > red_cfg->maxp_inv =3D maxp_inv; > > red_cfg->wq_log2 =3D 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 =3D 0; > > + while (max_red_queue_length !=3D 0) { > > + max_red_queue_length >>=3D 1; > > + count++; > > + } > > + > > + rte_red_scaling -=3D count - RTE_RED_SCALING_DEFAULT; > > + rte_red_max_threshold =3D max_red_queue_length - 1; > > + return 0; > > +} > > + > > +void > > +rte_red_reset_scaling(void) > > +{ > > + rte_red_init_done =3D 0; > > + rte_red_scaling =3D RTE_RED_SCALING_DEFAULT; > > + rte_red_max_threshold =3D 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 > > #include > > > > -#define RTE_RED_SCALING 10 /**< Fraction s= ize for > fixed- > > point */ > > -#define RTE_RED_S (1 << 22) /**< Packet siz= e multiplied > by > > number of leaf queues */ > > -#define RTE_RED_MAX_TH_MAX 1023 /**< Max thresh= old > limit > > in fixed point format */ > > -#define RTE_RED_WQ_LOG2_MIN 1 /**< Min invers= e > filter > > weight value */ > > -#define RTE_RED_WQ_LOG2_MAX 12 /**< Max invers= e > filter > > weight value */ > > -#define RTE_RED_MAXP_INV_MIN 1 /**< Min invers= e > mark > > probability value */ > > -#define RTE_RED_MAXP_INV_MAX 255 /**< Max invers= e > 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_B= IT) > > #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-test= s > > + * > > + * @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 =3D (n >> 6) & 0xf; > > n >>=3D 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 >=3D RTE_RED_2POW16) { > > red->avg =3D 0; > > } else { > > - red->avg =3D (red->avg >> RTE_RED_SCALING) * > > __rte_red_calc_qempty_factor(red_cfg->wq_log2, (uint16_t) m); > > + red->avg =3D (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 +=3D (q << RTE_RED_SCALING) - (red->avg >> red_cfg- > > >wq_log2); > > + red->avg +=3D (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 structu= re > 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 Qu= eues */ > > @@ -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_c= fg, > > @@ -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 =3D avg << (RTE_RED_SCALING + red_cfg->wq_log2); > > + red->avg =3D 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 =3D 0; > > + int ret; > > > > tcfg->tvar->clk_freq =3D rte_get_timer_hz(); > > init_port_ts( tcfg->tvar->clk_freq ); > > > > + rte_red_reset_scaling(); > > + ret =3D 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 =3D 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 =3D { > > .min_th =3D 32, > > .max_th =3D 128, > > .maxp_inv =3D ft_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_queue ft_tqueue =3D { > > @@ -554,6 +569,7 @@ static struct test_rte_red_config ft2_tconfig =3D = { > > .min_th =3D 32, > > .max_th =3D 128, > > .maxp_inv =3D ft2_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_config func_test2_config =3D { > > @@ -576,6 +592,41 @@ static struct test_config func_test2_config =3D { > > .tlevel =3D ft2_tlevel, > > }; > > > > +/** > > + * Test F2: functional test 2 - with long queues and smaller red-scali= ng > factor > > + */ > > +static uint32_t ft2_tlevel_scaling[] =3D {8190}; > > + > > +static struct test_rte_red_config ft2_tconfig_scaling =3D { > > + .rconfig =3D ft2_rconfig, > > + .num_cfg =3D RTE_DIM(ft2_rconfig), > > + .wq_log2 =3D ft2_wq_log2, > > + .min_th =3D 32, > > + .max_th =3D 8191, > > + .maxp_inv =3D ft2_maxp_inv, > > + .max_queue_len =3D 8192, > > +}; > > + > > +static struct test_config func_test2_config_scaling =3D { > > + .ifname =3D "functional test 2 interface", > > + .msg =3D "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 =3D "RED config " > > + "avg queue size " > > + "min threshold " > > + "max threshold " > > + "drop prob % " > > + "drop rate % " > > + "diff % " > > + "tolerance % " > > + "\n", > > + .tconfig =3D &ft2_tconfig_scaling, > > + .tqueue =3D &ft_tqueue, > > + .tvar =3D &ft_tvar, > > + .tlevel =3D ft2_tlevel_scaling, > > +}; > > + > > static enum test_result func_test2(struct test_config *tcfg) > > { > > enum test_result result =3D PASS; > > @@ -662,6 +713,7 @@ static struct test_rte_red_config ft3_tconfig =3D = { > > .min_th =3D 32, > > .max_th =3D 1023, > > .maxp_inv =3D ft_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_config func_test3_config =3D { > > @@ -683,6 +735,40 @@ static struct test_config func_test3_config =3D { > > .tlevel =3D ft3_tlevel, > > }; > > > > +/** > > + * Test F3: functional test 3 - with large queues and smaller red scal= ing > factor > > + */ > > +static uint32_t ft3_tlevel_scaling[] =3D {8190}; > > + > > +static struct test_rte_red_config ft3_tconfig_scaling =3D { > > + .rconfig =3D ft_wrconfig, > > + .num_cfg =3D RTE_DIM(ft_wrconfig), > > + .wq_log2 =3D ft_wq_log2, > > + .min_th =3D 32, > > + .max_th =3D 8191, > > + .maxp_inv =3D ft_maxp_inv, > > + .max_queue_len =3D 8192, > > +}; > > + > > +static struct test_config func_test3_config_scaling =3D { > > + .ifname =3D "functional test 3 interface", > > + .msg =3D "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 =3D "q avg before " > > + "q avg after " > > + "expected " > > + "difference % " > > + "tolerance % " > > + "result " > > + "\n", > > + .tconfig =3D &ft3_tconfig_scaling, > > + .tqueue =3D &ft_tqueue, > > + .tvar =3D &ft_tvar, > > + .tlevel =3D ft3_tlevel_scaling, > > +}; > > + > > static enum test_result func_test3(struct test_config *tcfg) > > { > > enum test_result result =3D PASS; > > @@ -776,6 +862,7 @@ static struct test_rte_red_config ft4_tconfig =3D = { > > .max_th =3D 1023, > > .wq_log2 =3D ft4_wq_log2, > > .maxp_inv =3D ft_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_queue ft4_tqueue =3D { > > @@ -810,6 +897,42 @@ static struct test_config func_test4_config =3D { > > .tlevel =3D ft4_tlevel, > > }; > > > > +/** > > + * Test F4: functional test 4 > > + */ > > +static uint32_t ft4_tlevel_scaling[] =3D {8190}; > > + > > +static struct test_rte_red_config ft4_tconfig_scaling =3D { > > + .rconfig =3D ft_wrconfig, > > + .num_cfg =3D RTE_DIM(ft_wrconfig), > > + .min_th =3D 32, > > + .max_th =3D 8191, > > + .wq_log2 =3D ft4_wq_log2, > > + .maxp_inv =3D ft_maxp_inv, > > + .max_queue_len =3D 8192, > > +}; > > + > > +static struct test_config func_test4_config_scaling =3D { > > + .ifname =3D "functional test 4 interface", > > + .msg =3D "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 =3D "q avg before " > > + "q avg after " > > + "expected " > > + "difference % " > > + "tolerance % " > > + "result " > > + "\n", > > + .tconfig =3D &ft4_tconfig_scaling, > > + .tqueue =3D &ft4_tqueue, > > + .tvar =3D &ft_tvar, > > + .tlevel =3D ft4_tlevel_scaling, > > +}; > > + > > static enum test_result func_test4(struct test_config *tcfg) > > { > > enum test_result result =3D PASS; > > @@ -924,6 +1047,7 @@ static struct test_rte_red_config ft5_tconfig =3D = { > > .max_th =3D 128, > > .wq_log2 =3D ft5_wq_log2, > > .maxp_inv =3D ft5_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_queue ft5_tqueue =3D { > > @@ -970,6 +1094,45 @@ static struct test_config func_test5_config =3D { > > .tlevel =3D ft5_tlevel, > > }; > > > > + > > +/** > > + * Test F5: functional test 5 > > + */ > > +static uint32_t ft5_tlevel_scaling[] =3D {8190}; > > + > > +static struct test_rte_red_config ft5_tconfig_scaling =3D { > > + .rconfig =3D ft5_config, > > + .num_cfg =3D RTE_DIM(ft5_config), > > + .min_th =3D 32, > > + .max_th =3D 8191, > > + .wq_log2 =3D ft5_wq_log2, > > + .maxp_inv =3D ft5_maxp_inv, > > + .max_queue_len =3D 8192, > > +}; > > + > > +static struct test_config func_test5_config_scaling =3D { > > + .ifname =3D "functional test 5 interface", > > + .msg =3D "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 =3D "queue " > > + "config " > > + "avg queue size " > > + "min threshold " > > + "max threshold " > > + "drop prob % " > > + "drop rate % " > > + "diff % " > > + "tolerance % " > > + "\n", > > + .tconfig =3D &ft5_tconfig_scaling, > > + .tqueue =3D &ft5_tqueue, > > + .tvar =3D &ft5_tvar, > > + .tlevel =3D ft5_tlevel_scaling, > > +}; > > + > > static enum test_result func_test5(struct test_config *tcfg) > > { > > enum test_result result =3D PASS; > > @@ -1062,6 +1225,7 @@ static struct test_rte_red_config ft6_tconfig =3D= { > > .max_th =3D 1023, > > .wq_log2 =3D ft6_wq_log2, > > .maxp_inv =3D ft6_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_queue ft6_tqueue =3D { > > @@ -1078,7 +1242,7 @@ static struct test_queue ft6_tqueue =3D { > > static struct test_config func_test6_config =3D { > > .ifname =3D "functional test 6 interface", > > .msg =3D "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 =3D = { > > .tlevel =3D ft6_tlevel, > > }; > > > > +/** > > + * Test F6: functional test 6 > > + */ > > +static uint32_t ft6_tlevel_scaling[] =3D {8190}; > > + > > +static struct test_rte_red_config ft6_tconfig_scaling =3D { > > + .rconfig =3D ft6_config, > > + .num_cfg =3D RTE_DIM(ft6_config), > > + .min_th =3D 32, > > + .max_th =3D 8191, > > + .wq_log2 =3D ft6_wq_log2, > > + .maxp_inv =3D ft6_maxp_inv, > > + .max_queue_len =3D 8192, > > +}; > > + > > +static struct test_config func_test6_config_scaling =3D { > > + .ifname =3D "functional test 6 interface", > > + .msg =3D "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 =3D "queue " > > + "config " > > + "q avg before " > > + "q avg after " > > + "expected " > > + "difference % " > > + "tolerance % " > > + "result " > > + "\n", > > + .tconfig =3D &ft6_tconfig_scaling, > > + .tqueue =3D &ft6_tqueue, > > + .tvar =3D &ft_tvar, > > + .tlevel =3D ft6_tlevel_scaling, > > +}; > > + > > static enum test_result func_test6(struct test_config *tcfg) > > { > > enum test_result result =3D PASS; > > @@ -1195,6 +1397,7 @@ static struct test_rte_red_config pt_tconfig =3D = { > > .min_th =3D 32, > > .max_th =3D 128, > > .maxp_inv =3D pt_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_queue pt_tqueue =3D { > > @@ -1557,6 +1760,7 @@ static struct test_rte_red_config ovfl_tconfig = =3D > { > > .min_th =3D 32, > > .max_th =3D 1023, > > .maxp_inv =3D ovfl_maxp_inv, > > + .max_queue_len =3D RTE_RED_DEFAULT_QUEUE_LENGTH, > > }; > > > > static struct test_queue ovfl_tqueue =3D { > > @@ -1598,7 +1802,7 @@ static struct test_config ovfl_test1_config =3D { > > .ifname =3D "queue avergage overflow test interface", > > .msg =3D "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 =3D "avg queue size " > > "wq_log2 " > > "fraction bits " > > @@ -1615,6 +1819,39 @@ static struct test_config ovfl_test1_config =3D = { > > .tlevel =3D ovfl_tlevel, > > }; > > > > +static uint32_t ovfl_tlevel_scaling[] =3D {8191}; > > + > > +static struct test_rte_red_config ovfl_tconfig_scaling =3D { > > + .rconfig =3D ovfl_wrconfig, > > + .num_cfg =3D RTE_DIM(ovfl_wrconfig), > > + .wq_log2 =3D ovfl_wq_log2, > > + .min_th =3D 32, > > + .max_th =3D 8191, > > + .maxp_inv =3D ovfl_maxp_inv, > > + .max_queue_len =3D 8192, > > +}; > > + > > +static struct test_config ovfl_test1_config_scaling =3D { > > + .ifname =3D "queue average overflow test interface", > > + .msg =3D "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 =3D "avg queue size " > > + "wq_log2 " > > + "fraction bits " > > + "max queue avg " > > + "num bits " > > + "enqueued " > > + "dropped " > > + "drop prob % " > > + "drop rate % " > > + "\n", > > + .tconfig =3D &ovfl_tconfig_scaling, > > + .tqueue =3D &ovfl_tqueue, > > + .tvar =3D &ovfl_tvar, > > + .tlevel =3D ovfl_tlevel_scaling, > > +}; > > + > > static enum test_result ovfl_test1(struct test_config *tcfg) > > { > > enum test_result result =3D 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[] =3D { > > { &perf2_test6_config, perf2_test }, > > }; > > > > +struct tests scale_tests[] =3D { > > + { &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 =3D 0; > > + uint32_t num_pass =3D 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 =3D 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