@@ -158,7 +158,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_power.so.1
librte_reorder.so.1
librte_ring.so.1
- librte_sched.so.1
+ librte_sched.so.2
librte_security.so.1
librte_table.so.3
librte_timer.so.1
@@ -48,7 +48,7 @@ LDLIBS += -lrte_timer
EXPORT_MAP := rte_sched_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
@@ -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 */
+uint32_t rte_red_scaling = RTE_RED_SCALING;
+uint32_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,46 @@ 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)
+{
+ 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;
+
+ rte_red_scaling = RTE_RED_SCALING - (rte_bsf32(max_red_queue_length) -
+ RTE_RED_SCALING);
+ 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;
+ rte_red_max_threshold = RTE_RED_DEFAULT_QUEUE_LENGTH - 1;
+}
+
@@ -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 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 uint32_t rte_red_scaling;
+extern uint32_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, this
+ * function can only be called once and must be called before any
+ * RED queues are initialised.
+ *
+ * @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 all RED global variables - only for use by RED unit-tests
+ */
+void
+__rte_red_reset_scaling(void);
+
+/**
* @brief Generate random number for RED
*
* Implementation 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) {
@@ -29,3 +29,10 @@ DPDK_2.1 {
rte_sched_port_pkt_read_color;
} DPDK_2.0;
+
+DPDK_18.02 {
+ global;
+
+ rte_red_set_scaling;
+ __rte_red_reset_scaling;
+} DPDK_2.1;
@@ -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);