1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
19 #ifdef __INTEL_COMPILER
20 #pragma warning(disable:2259) /* conversion may lose significant bits */
21 #pragma warning(disable:181) /* Arg incompatible with format string */
24 #define TEST_HZ_PER_KHZ 1000
25 #define TEST_NSEC_MARGIN 500 /**< nanosecond margin when calculating clk freq */
27 #define MAX_QEMPTY_TIME_MSEC 50000
28 #define MSEC_PER_SEC 1000 /**< Milli-seconds per second */
29 #define USEC_PER_MSEC 1000 /**< Micro-seconds per milli-second */
30 #define USEC_PER_SEC 1000000 /**< Micro-seconds per second */
31 #define NSEC_PER_SEC (USEC_PER_SEC * 1000) /**< Nano-seconds per second */
33 /**< structures for testing rte_red performance and function */
34 struct test_rte_red_config { /**< Test structure for RTE_RED config */
35 struct rte_red_config *rconfig; /**< RTE_RED configuration parameters */
36 uint8_t num_cfg; /**< Number of RTE_RED configs to test */
37 uint8_t *wq_log2; /**< Test wq_log2 value to use */
38 uint32_t min_th; /**< Queue minimum threshold */
39 uint32_t max_th; /**< Queue maximum threshold */
40 uint8_t *maxp_inv; /**< Inverse mark probability */
43 struct test_queue { /**< Test structure for RTE_RED Queues */
44 struct rte_red *rdata; /**< RTE_RED runtime data */
45 uint32_t num_queues; /**< Number of RTE_RED queues to test */
46 uint32_t *qconfig; /**< Configuration of RTE_RED queues for test */
47 uint32_t *q; /**< Queue size */
48 uint32_t q_ramp_up; /**< Num of enqueues to ramp up the queue */
49 uint32_t avg_ramp_up; /**< Average num of enqueues to ramp up the queue */
50 uint32_t avg_tolerance; /**< Tolerance in queue average */
51 double drop_tolerance; /**< Drop tolerance of packets not enqueued */
54 struct test_var { /**< Test variables used for testing RTE_RED */
55 uint32_t wait_usec; /**< Micro second wait interval */
56 uint32_t num_iterations; /**< Number of test iterations */
57 uint32_t num_ops; /**< Number of test operations */
58 uint64_t clk_freq; /**< CPU clock frequency */
59 uint32_t sleep_sec; /**< Seconds to sleep */
60 uint32_t *dropped; /**< Test operations dropped */
61 uint32_t *enqueued; /**< Test operations enqueued */
64 struct test_config { /**< Master test structure for RTE_RED */
65 const char *ifname; /**< Interface name */
66 const char *msg; /**< Test message for display */
67 const char *htxt; /**< Header txt display for result output */
68 struct test_rte_red_config *tconfig; /**< Test structure for RTE_RED config */
69 struct test_queue *tqueue; /**< Test structure for RTE_RED Queues */
70 struct test_var *tvar; /**< Test variables used for testing RTE_RED */
71 uint32_t *tlevel; /**< Queue levels */
79 /**< Test structure to define tests to run */
81 struct test_config *testcfg;
82 enum test_result (*testfn)(struct test_config *);
87 uint64_t clk_min; /**< min clocks */
88 uint64_t clk_max; /**< max clocks */
89 uint64_t clk_avgc; /**< count to calc average */
90 double clk_avg; /**< cumulative sum to calc average */
94 static const uint64_t port_speed_bytes = (10ULL*1000ULL*1000ULL*1000ULL)/8ULL;
95 static double inv_cycles_per_byte = 0;
96 static double pkt_time_usec = 0;
98 static void init_port_ts(uint64_t cpu_clock)
100 double cycles_per_byte = (double)(cpu_clock) / (double)(port_speed_bytes);
101 inv_cycles_per_byte = 1.0 / cycles_per_byte;
102 pkt_time_usec = 1000000.0 / ((double)port_speed_bytes / (double)RTE_RED_S);
105 static uint64_t get_port_ts(void)
107 return (uint64_t)((double)rte_rdtsc() * inv_cycles_per_byte);
110 static void rdtsc_prof_init(struct rdtsc_prof *p, const char *name)
112 p->clk_min = (uint64_t)(-1LL);
119 static inline void rdtsc_prof_start(struct rdtsc_prof *p)
121 p->clk_start = rte_rdtsc_precise();
124 static inline void rdtsc_prof_end(struct rdtsc_prof *p)
126 uint64_t clk_start = rte_rdtsc() - p->clk_start;
129 p->clk_avg += (double) clk_start;
131 if (clk_start > p->clk_max)
132 p->clk_max = clk_start;
133 if (clk_start < p->clk_min)
134 p->clk_min = clk_start;
137 static void rdtsc_prof_print(struct rdtsc_prof *p)
140 printf("RDTSC stats for %s: n=%" PRIu64 ", min=%" PRIu64 ", max=%" PRIu64 ", avg=%.1f\n",
145 (p->clk_avg / ((double) p->clk_avgc)));
149 static uint32_t rte_red_get_avg_int(const struct rte_red_config *red_cfg,
153 * scale by 1/n and convert from fixed-point to integer
155 return red->avg >> (RTE_RED_SCALING + red_cfg->wq_log2);
158 static double rte_red_get_avg_float(const struct rte_red_config *red_cfg,
162 * scale by 1/n and convert from fixed-point to floating-point
164 return ldexp((double)red->avg, -(RTE_RED_SCALING + red_cfg->wq_log2));
167 static void rte_red_set_avg_int(const struct rte_red_config *red_cfg,
172 * scale by n and convert from integer to fixed-point
174 red->avg = avg << (RTE_RED_SCALING + red_cfg->wq_log2);
177 static double calc_exp_avg_on_empty(double avg, uint32_t n, uint32_t time_diff)
179 return avg * pow((1.0 - 1.0 / (double)n), (double)time_diff / pkt_time_usec);
182 static double calc_drop_rate(uint32_t enqueued, uint32_t dropped)
184 return (double)dropped / ((double)enqueued + (double)dropped);
188 * calculate the drop probability
190 static double calc_drop_prob(uint32_t min_th, uint32_t max_th,
191 uint32_t maxp_inv, uint32_t avg)
193 double drop_prob = 0.0;
197 } else if (avg < max_th) {
198 drop_prob = (1.0 / (double)maxp_inv)
199 * ((double)(avg - min_th)
200 / (double)(max_th - min_th));
208 * check if drop rate matches drop probability within tolerance
210 static int check_drop_rate(double *diff, double drop_rate, double drop_prob, double tolerance)
212 double abs_diff = 0.0;
215 abs_diff = fabs(drop_rate - drop_prob);
216 if ((int)abs_diff == 0) {
219 *diff = (abs_diff / drop_prob) * 100.0;
220 if (*diff > tolerance) {
228 * check if average queue size is within tolerance
230 static int check_avg(double *diff, double avg, double exp_avg, double tolerance)
232 double abs_diff = 0.0;
235 abs_diff = fabs(avg - exp_avg);
236 if ((int)abs_diff == 0) {
239 *diff = (abs_diff / exp_avg) * 100.0;
240 if (*diff > tolerance) {
248 * initialize the test rte_red config
250 static enum test_result
251 test_rte_red_init(struct test_config *tcfg)
255 tcfg->tvar->clk_freq = rte_get_timer_hz();
256 init_port_ts( tcfg->tvar->clk_freq );
258 for (i = 0; i < tcfg->tconfig->num_cfg; i++) {
259 if (rte_red_config_init(&tcfg->tconfig->rconfig[i],
260 (uint16_t)tcfg->tconfig->wq_log2[i],
261 (uint16_t)tcfg->tconfig->min_th,
262 (uint16_t)tcfg->tconfig->max_th,
263 (uint16_t)tcfg->tconfig->maxp_inv[i]) != 0) {
268 *tcfg->tqueue->q = 0;
269 *tcfg->tvar->dropped = 0;
270 *tcfg->tvar->enqueued = 0;
275 * enqueue until actual queue size reaches target level
278 increase_actual_qsize(struct rte_red_config *red_cfg,
286 for (i = 0; i < attempts; i++) {
292 ret = rte_red_enqueue(red_cfg, red, *q, get_port_ts() );
299 * check if target actual queue size has been reached
310 * enqueue until average queue size reaches target level
313 increase_average_qsize(struct rte_red_config *red_cfg,
322 for (i = 0; i < num_ops; i++) {
326 rte_red_enqueue(red_cfg, red, *q, get_port_ts());
329 * check if target average queue size has been reached
331 avg = rte_red_get_avg_int(red_cfg, red);
341 * setup default values for the functional test structures
343 static struct rte_red_config ft_wrconfig[1];
344 static struct rte_red ft_rtdata[1];
345 static uint8_t ft_wq_log2[] = {9};
346 static uint8_t ft_maxp_inv[] = {10};
347 static uint32_t ft_qconfig[] = {0, 0, 1, 1};
348 static uint32_t ft_q[] ={0};
349 static uint32_t ft_dropped[] ={0};
350 static uint32_t ft_enqueued[] ={0};
352 static struct test_rte_red_config ft_tconfig = {
353 .rconfig = ft_wrconfig,
354 .num_cfg = RTE_DIM(ft_wrconfig),
355 .wq_log2 = ft_wq_log2,
358 .maxp_inv = ft_maxp_inv,
361 static struct test_queue ft_tqueue = {
363 .num_queues = RTE_DIM(ft_rtdata),
364 .qconfig = ft_qconfig,
366 .q_ramp_up = 1000000,
367 .avg_ramp_up = 1000000,
368 .avg_tolerance = 5, /* 5 percent */
369 .drop_tolerance = 50, /* 50 percent */
372 static struct test_var ft_tvar = {
377 .dropped = ft_dropped,
378 .enqueued = ft_enqueued,
379 .sleep_sec = (MAX_QEMPTY_TIME_MSEC / MSEC_PER_SEC) + 2,
383 * functional test enqueue/dequeue packets
385 static void enqueue_dequeue_func(struct rte_red_config *red_cfg,
394 for (i = 0; i < num_ops; i++) {
400 ret = rte_red_enqueue(red_cfg, red, *q, get_port_ts());
409 * Test F1: functional test 1
411 static uint32_t ft1_tlevels[] = {6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126, 132, 138, 144};
413 static struct test_config func_test1_config = {
414 .ifname = "functional test 1 interface",
415 .msg = "functional test 1 : use one rte_red configuration,\n"
416 " increase average queue size to various levels,\n"
417 " compare drop rate to drop probability\n\n",
427 .tconfig = &ft_tconfig,
428 .tqueue = &ft_tqueue,
430 .tlevel = ft1_tlevels,
433 static enum test_result func_test1(struct test_config *tcfg)
435 enum test_result result = PASS;
438 printf("%s", tcfg->msg);
440 if (test_rte_red_init(tcfg) != PASS) {
445 printf("%s", tcfg->htxt);
447 for (i = 0; i < RTE_DIM(ft1_tlevels); i++) {
448 const char *label = NULL;
450 double drop_rate = 0.0;
451 double drop_prob = 0.0;
455 * reset rte_red run-time data
457 rte_red_rt_data_init(tcfg->tqueue->rdata);
458 *tcfg->tvar->enqueued = 0;
459 *tcfg->tvar->dropped = 0;
461 if (increase_actual_qsize(tcfg->tconfig->rconfig,
465 tcfg->tqueue->q_ramp_up) != 0) {
470 if (increase_average_qsize(tcfg->tconfig->rconfig,
474 tcfg->tqueue->avg_ramp_up) != 0) {
479 enqueue_dequeue_func(tcfg->tconfig->rconfig,
483 tcfg->tvar->enqueued,
484 tcfg->tvar->dropped);
486 avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
487 if (avg != tcfg->tlevel[i]) {
488 fprintf(stderr, "Fail: avg != level\n");
492 drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped);
493 drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th,
494 *tcfg->tconfig->maxp_inv, tcfg->tlevel[i]);
495 if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance))
498 if (tcfg->tlevel[i] == tcfg->tconfig->min_th)
499 label = "min thresh: ";
500 else if (tcfg->tlevel[i] == tcfg->tconfig->max_th)
501 label = "max thresh: ";
504 printf("%s%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n",
505 label, avg, *tcfg->tvar->enqueued, *tcfg->tvar->dropped,
506 drop_prob * 100.0, drop_rate * 100.0, diff,
507 (double)tcfg->tqueue->drop_tolerance);
514 * Test F2: functional test 2
516 static uint32_t ft2_tlevel[] = {127};
517 static uint8_t ft2_wq_log2[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
518 static uint8_t ft2_maxp_inv[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
519 static struct rte_red_config ft2_rconfig[10];
521 static struct test_rte_red_config ft2_tconfig = {
522 .rconfig = ft2_rconfig,
523 .num_cfg = RTE_DIM(ft2_rconfig),
524 .wq_log2 = ft2_wq_log2,
527 .maxp_inv = ft2_maxp_inv,
530 static struct test_config func_test2_config = {
531 .ifname = "functional test 2 interface",
532 .msg = "functional test 2 : use several RED configurations,\n"
533 " increase average queue size to just below maximum threshold,\n"
534 " compare drop rate to drop probability\n\n",
535 .htxt = "RED config "
544 .tconfig = &ft2_tconfig,
545 .tqueue = &ft_tqueue,
547 .tlevel = ft2_tlevel,
550 static enum test_result func_test2(struct test_config *tcfg)
552 enum test_result result = PASS;
553 double prev_drop_rate = 1.0;
556 printf("%s", tcfg->msg);
558 if (test_rte_red_init(tcfg) != PASS) {
562 rte_red_rt_data_init(tcfg->tqueue->rdata);
564 if (increase_actual_qsize(tcfg->tconfig->rconfig,
568 tcfg->tqueue->q_ramp_up) != 0) {
573 if (increase_average_qsize(tcfg->tconfig->rconfig,
577 tcfg->tqueue->avg_ramp_up) != 0) {
581 printf("%s", tcfg->htxt);
583 for (i = 0; i < tcfg->tconfig->num_cfg; i++) {
585 double drop_rate = 0.0;
586 double drop_prob = 0.0;
589 *tcfg->tvar->dropped = 0;
590 *tcfg->tvar->enqueued = 0;
592 enqueue_dequeue_func(&tcfg->tconfig->rconfig[i],
596 tcfg->tvar->enqueued,
597 tcfg->tvar->dropped);
599 avg = rte_red_get_avg_int(&tcfg->tconfig->rconfig[i], tcfg->tqueue->rdata);
600 if (avg != *tcfg->tlevel)
603 drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped);
604 drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th,
605 tcfg->tconfig->maxp_inv[i], *tcfg->tlevel);
606 if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance))
609 * drop rate should decrease as maxp_inv increases
611 if (drop_rate > prev_drop_rate)
613 prev_drop_rate = drop_rate;
615 printf("%-15u%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n",
616 i, avg, tcfg->tconfig->min_th, tcfg->tconfig->max_th,
617 drop_prob * 100.0, drop_rate * 100.0, diff,
618 (double)tcfg->tqueue->drop_tolerance);
625 * Test F3: functional test 3
627 static uint32_t ft3_tlevel[] = {1022};
629 static struct test_rte_red_config ft3_tconfig = {
630 .rconfig = ft_wrconfig,
631 .num_cfg = RTE_DIM(ft_wrconfig),
632 .wq_log2 = ft_wq_log2,
635 .maxp_inv = ft_maxp_inv,
638 static struct test_config func_test3_config = {
639 .ifname = "functional test 3 interface",
640 .msg = "functional test 3 : use one RED configuration,\n"
641 " increase average queue size to target level,\n"
642 " dequeue all packets until queue is empty,\n"
643 " confirm that average queue size is computed correctly while queue is empty\n\n",
644 .htxt = "q avg before "
651 .tconfig = &ft3_tconfig,
652 .tqueue = &ft_tqueue,
654 .tlevel = ft3_tlevel,
657 static enum test_result func_test3(struct test_config *tcfg)
659 enum test_result result = PASS;
662 printf("%s", tcfg->msg);
664 if (test_rte_red_init(tcfg) != PASS) {
669 rte_red_rt_data_init(tcfg->tqueue->rdata);
671 if (increase_actual_qsize(tcfg->tconfig->rconfig,
675 tcfg->tqueue->q_ramp_up) != 0) {
680 if (increase_average_qsize(tcfg->tconfig->rconfig,
684 tcfg->tqueue->avg_ramp_up) != 0) {
689 printf("%s", tcfg->htxt);
691 for (i = 0; i < tcfg->tvar->num_iterations; i++) {
692 double avg_before = 0;
693 double avg_after = 0;
697 avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
702 *tcfg->tqueue->q = 0;
703 rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts());
705 rte_delay_us(tcfg->tvar->wait_usec);
708 * enqueue one packet to recalculate average queue size
710 if (rte_red_enqueue(tcfg->tconfig->rconfig,
713 get_port_ts()) == 0) {
714 (*tcfg->tqueue->q)++;
716 printf("%s:%d: packet enqueued on empty queue was dropped\n", __func__, __LINE__);
720 exp_avg = calc_exp_avg_on_empty(avg_before,
721 (1 << *tcfg->tconfig->wq_log2),
722 tcfg->tvar->wait_usec);
723 avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig,
724 tcfg->tqueue->rdata);
725 if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance))
728 printf("%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n",
729 avg_before, avg_after, exp_avg, diff,
730 (double)tcfg->tqueue->avg_tolerance,
731 diff <= (double)tcfg->tqueue->avg_tolerance ? "pass" : "fail");
738 * Test F4: functional test 4
740 static uint32_t ft4_tlevel[] = {1022};
741 static uint8_t ft4_wq_log2[] = {11};
743 static struct test_rte_red_config ft4_tconfig = {
744 .rconfig = ft_wrconfig,
745 .num_cfg = RTE_DIM(ft_wrconfig),
748 .wq_log2 = ft4_wq_log2,
749 .maxp_inv = ft_maxp_inv,
752 static struct test_queue ft4_tqueue = {
754 .num_queues = RTE_DIM(ft_rtdata),
755 .qconfig = ft_qconfig,
757 .q_ramp_up = 1000000,
758 .avg_ramp_up = 1000000,
759 .avg_tolerance = 0, /* 0 percent */
760 .drop_tolerance = 50, /* 50 percent */
763 static struct test_config func_test4_config = {
764 .ifname = "functional test 4 interface",
765 .msg = "functional test 4 : use one RED configuration,\n"
766 " increase average queue size to target level,\n"
767 " dequeue all packets until queue is empty,\n"
768 " confirm that average queue size is computed correctly while\n"
769 " queue is empty for more than 50 sec,\n"
770 " (this test takes 52 sec to run)\n\n",
771 .htxt = "q avg before "
778 .tconfig = &ft4_tconfig,
779 .tqueue = &ft4_tqueue,
781 .tlevel = ft4_tlevel,
784 static enum test_result func_test4(struct test_config *tcfg)
786 enum test_result result = PASS;
787 uint64_t time_diff = 0;
789 double avg_before = 0.0;
790 double avg_after = 0.0;
791 double exp_avg = 0.0;
794 printf("%s", tcfg->msg);
796 if (test_rte_red_init(tcfg) != PASS) {
801 rte_red_rt_data_init(tcfg->tqueue->rdata);
803 if (increase_actual_qsize(tcfg->tconfig->rconfig,
807 tcfg->tqueue->q_ramp_up) != 0) {
812 if (increase_average_qsize(tcfg->tconfig->rconfig,
816 tcfg->tqueue->avg_ramp_up) != 0) {
821 printf("%s", tcfg->htxt);
823 avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
828 *tcfg->tqueue->q = 0;
829 rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts());
832 * record empty time locally
836 sleep(tcfg->tvar->sleep_sec);
839 * enqueue one packet to recalculate average queue size
841 if (rte_red_enqueue(tcfg->tconfig->rconfig,
844 get_port_ts()) != 0) {
848 (*tcfg->tqueue->q)++;
851 * calculate how long queue has been empty
853 time_diff = ((rte_rdtsc() - start) / tcfg->tvar->clk_freq)
855 if (time_diff < MAX_QEMPTY_TIME_MSEC) {
857 * this could happen if sleep was interrupted for some reason
864 * confirm that average queue size is now at expected level
867 avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
868 if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance))
871 printf("%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n",
872 avg_before, avg_after, exp_avg,
873 diff, (double)tcfg->tqueue->avg_tolerance,
874 diff <= (double)tcfg->tqueue->avg_tolerance ? "pass" : "fail");
880 * Test F5: functional test 5
882 static uint32_t ft5_tlevel[] = {127};
883 static uint8_t ft5_wq_log2[] = {9, 8};
884 static uint8_t ft5_maxp_inv[] = {10, 20};
885 static struct rte_red_config ft5_config[2];
886 static struct rte_red ft5_data[4];
887 static uint32_t ft5_q[4];
888 static uint32_t ft5_dropped[] = {0, 0, 0, 0};
889 static uint32_t ft5_enqueued[] = {0, 0, 0, 0};
891 static struct test_rte_red_config ft5_tconfig = {
892 .rconfig = ft5_config,
893 .num_cfg = RTE_DIM(ft5_config),
896 .wq_log2 = ft5_wq_log2,
897 .maxp_inv = ft5_maxp_inv,
900 static struct test_queue ft5_tqueue = {
902 .num_queues = RTE_DIM(ft5_data),
903 .qconfig = ft_qconfig,
905 .q_ramp_up = 1000000,
906 .avg_ramp_up = 1000000,
907 .avg_tolerance = 5, /* 10 percent */
908 .drop_tolerance = 50, /* 50 percent */
911 struct test_var ft5_tvar = {
913 .num_iterations = 15,
916 .dropped = ft5_dropped,
917 .enqueued = ft5_enqueued,
921 static struct test_config func_test5_config = {
922 .ifname = "functional test 5 interface",
923 .msg = "functional test 5 : use several queues (each with its own run-time data),\n"
924 " use several RED configurations (such that each configuration is shared by multiple queues),\n"
925 " increase average queue size to just below maximum threshold,\n"
926 " compare drop rate to drop probability,\n"
927 " (this is a larger scale version of functional test 2)\n\n",
938 .tconfig = &ft5_tconfig,
939 .tqueue = &ft5_tqueue,
941 .tlevel = ft5_tlevel,
944 static enum test_result func_test5(struct test_config *tcfg)
946 enum test_result result = PASS;
949 printf("%s", tcfg->msg);
951 if (test_rte_red_init(tcfg) != PASS) {
956 printf("%s", tcfg->htxt);
958 for (j = 0; j < tcfg->tqueue->num_queues; j++) {
959 rte_red_rt_data_init(&tcfg->tqueue->rdata[j]);
960 tcfg->tqueue->q[j] = 0;
962 if (increase_actual_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
963 &tcfg->tqueue->rdata[j],
966 tcfg->tqueue->q_ramp_up) != 0) {
971 if (increase_average_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
972 &tcfg->tqueue->rdata[j],
975 tcfg->tqueue->avg_ramp_up) != 0) {
981 for (j = 0; j < tcfg->tqueue->num_queues; j++) {
983 double drop_rate = 0.0;
984 double drop_prob = 0.0;
987 tcfg->tvar->dropped[j] = 0;
988 tcfg->tvar->enqueued[j] = 0;
990 enqueue_dequeue_func(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
991 &tcfg->tqueue->rdata[j],
994 &tcfg->tvar->enqueued[j],
995 &tcfg->tvar->dropped[j]);
997 avg = rte_red_get_avg_int(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
998 &tcfg->tqueue->rdata[j]);
999 if (avg != *tcfg->tlevel)
1002 drop_rate = calc_drop_rate(tcfg->tvar->enqueued[j],tcfg->tvar->dropped[j]);
1003 drop_prob = calc_drop_prob(tcfg->tconfig->min_th, tcfg->tconfig->max_th,
1004 tcfg->tconfig->maxp_inv[tcfg->tqueue->qconfig[j]],
1006 if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance))
1009 printf("%-15u%-15u%-15u%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf\n",
1010 j, tcfg->tqueue->qconfig[j], avg,
1011 tcfg->tconfig->min_th, tcfg->tconfig->max_th,
1012 drop_prob * 100.0, drop_rate * 100.0,
1013 diff, (double)tcfg->tqueue->drop_tolerance);
1020 * Test F6: functional test 6
1022 static uint32_t ft6_tlevel[] = {1022};
1023 static uint8_t ft6_wq_log2[] = {9, 8};
1024 static uint8_t ft6_maxp_inv[] = {10, 20};
1025 static struct rte_red_config ft6_config[2];
1026 static struct rte_red ft6_data[4];
1027 static uint32_t ft6_q[4];
1029 static struct test_rte_red_config ft6_tconfig = {
1030 .rconfig = ft6_config,
1031 .num_cfg = RTE_DIM(ft6_config),
1034 .wq_log2 = ft6_wq_log2,
1035 .maxp_inv = ft6_maxp_inv,
1038 static struct test_queue ft6_tqueue = {
1040 .num_queues = RTE_DIM(ft6_data),
1041 .qconfig = ft_qconfig,
1043 .q_ramp_up = 1000000,
1044 .avg_ramp_up = 1000000,
1045 .avg_tolerance = 5, /* 10 percent */
1046 .drop_tolerance = 50, /* 50 percent */
1049 static struct test_config func_test6_config = {
1050 .ifname = "functional test 6 interface",
1051 .msg = "functional test 6 : use several queues (each with its own run-time data),\n"
1052 " use several RED configurations (such that each configuration is sharte_red by multiple queues),\n"
1053 " increase average queue size to target level,\n"
1054 " dequeue all packets until queue is empty,\n"
1055 " confirm that average queue size is computed correctly while queue is empty\n"
1056 " (this is a larger scale version of functional test 3)\n\n",
1065 .tconfig = &ft6_tconfig,
1066 .tqueue = &ft6_tqueue,
1068 .tlevel = ft6_tlevel,
1071 static enum test_result func_test6(struct test_config *tcfg)
1073 enum test_result result = PASS;
1076 printf("%s", tcfg->msg);
1077 if (test_rte_red_init(tcfg) != PASS) {
1081 printf("%s", tcfg->htxt);
1083 for (j = 0; j < tcfg->tqueue->num_queues; j++) {
1084 rte_red_rt_data_init(&tcfg->tqueue->rdata[j]);
1085 tcfg->tqueue->q[j] = 0;
1087 if (increase_actual_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
1088 &tcfg->tqueue->rdata[j],
1089 &tcfg->tqueue->q[j],
1091 tcfg->tqueue->q_ramp_up) != 0) {
1095 if (increase_average_qsize(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
1096 &tcfg->tqueue->rdata[j],
1097 &tcfg->tqueue->q[j],
1099 tcfg->tqueue->avg_ramp_up) != 0) {
1104 for (j = 0; j < tcfg->tqueue->num_queues; j++) {
1105 double avg_before = 0;
1106 double avg_after = 0;
1110 avg_before = rte_red_get_avg_float(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
1111 &tcfg->tqueue->rdata[j]);
1116 tcfg->tqueue->q[j] = 0;
1117 rte_red_mark_queue_empty(&tcfg->tqueue->rdata[j], get_port_ts());
1118 rte_delay_us(tcfg->tvar->wait_usec);
1121 * enqueue one packet to recalculate average queue size
1123 if (rte_red_enqueue(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
1124 &tcfg->tqueue->rdata[j],
1126 get_port_ts()) == 0) {
1127 tcfg->tqueue->q[j]++;
1129 printf("%s:%d: packet enqueued on empty queue was dropped\n", __func__, __LINE__);
1133 exp_avg = calc_exp_avg_on_empty(avg_before,
1134 (1 << tcfg->tconfig->wq_log2[tcfg->tqueue->qconfig[j]]),
1135 tcfg->tvar->wait_usec);
1136 avg_after = rte_red_get_avg_float(&tcfg->tconfig->rconfig[tcfg->tqueue->qconfig[j]],
1137 &tcfg->tqueue->rdata[j]);
1138 if (!check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance))
1141 printf("%-15u%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n",
1142 j, tcfg->tqueue->qconfig[j], avg_before, avg_after,
1143 exp_avg, diff, (double)tcfg->tqueue->avg_tolerance,
1144 diff <= tcfg->tqueue->avg_tolerance ? "pass" : "fail");
1151 * setup default values for the performance test structures
1153 static struct rte_red_config pt_wrconfig[1];
1154 static struct rte_red pt_rtdata[1];
1155 static uint8_t pt_wq_log2[] = {9};
1156 static uint8_t pt_maxp_inv[] = {10};
1157 static uint32_t pt_qconfig[] = {0};
1158 static uint32_t pt_q[] = {0};
1159 static uint32_t pt_dropped[] = {0};
1160 static uint32_t pt_enqueued[] = {0};
1162 static struct test_rte_red_config pt_tconfig = {
1163 .rconfig = pt_wrconfig,
1164 .num_cfg = RTE_DIM(pt_wrconfig),
1165 .wq_log2 = pt_wq_log2,
1168 .maxp_inv = pt_maxp_inv,
1171 static struct test_queue pt_tqueue = {
1173 .num_queues = RTE_DIM(pt_rtdata),
1174 .qconfig = pt_qconfig,
1176 .q_ramp_up = 1000000,
1177 .avg_ramp_up = 1000000,
1178 .avg_tolerance = 5, /* 10 percent */
1179 .drop_tolerance = 50, /* 50 percent */
1183 * enqueue/dequeue packets
1185 static void enqueue_dequeue_perf(struct rte_red_config *red_cfg,
1186 struct rte_red *red,
1191 struct rdtsc_prof *prof)
1195 for (i = 0; i < num_ops; i++) {
1202 rdtsc_prof_start(prof);
1203 ret = rte_red_enqueue(red_cfg, red, *q, ts );
1204 rdtsc_prof_end(prof);
1213 * Setup test structures for tests P1, P2, P3
1214 * performance tests 1, 2 and 3
1216 static uint32_t pt1_tlevel[] = {16};
1217 static uint32_t pt2_tlevel[] = {80};
1218 static uint32_t pt3_tlevel[] = {144};
1220 static struct test_var perf1_tvar = {
1222 .num_iterations = 15,
1223 .num_ops = 50000000,
1225 .dropped = pt_dropped,
1226 .enqueued = pt_enqueued,
1230 static struct test_config perf1_test1_config = {
1231 .ifname = "performance test 1 interface",
1232 .msg = "performance test 1 : use one RED configuration,\n"
1233 " set actual and average queue sizes to level below min threshold,\n"
1234 " measure enqueue performance\n\n",
1235 .tconfig = &pt_tconfig,
1236 .tqueue = &pt_tqueue,
1237 .tvar = &perf1_tvar,
1238 .tlevel = pt1_tlevel,
1241 static struct test_config perf1_test2_config = {
1242 .ifname = "performance test 2 interface",
1243 .msg = "performance test 2 : use one RED configuration,\n"
1244 " set actual and average queue sizes to level in between min and max thresholds,\n"
1245 " measure enqueue performance\n\n",
1246 .tconfig = &pt_tconfig,
1247 .tqueue = &pt_tqueue,
1248 .tvar = &perf1_tvar,
1249 .tlevel = pt2_tlevel,
1252 static struct test_config perf1_test3_config = {
1253 .ifname = "performance test 3 interface",
1254 .msg = "performance test 3 : use one RED configuration,\n"
1255 " set actual and average queue sizes to level above max threshold,\n"
1256 " measure enqueue performance\n\n",
1257 .tconfig = &pt_tconfig,
1258 .tqueue = &pt_tqueue,
1259 .tvar = &perf1_tvar,
1260 .tlevel = pt3_tlevel,
1264 * Performance test function to measure enqueue performance.
1265 * This runs performance tests 1, 2 and 3
1267 static enum test_result perf1_test(struct test_config *tcfg)
1269 enum test_result result = PASS;
1270 struct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL};
1273 printf("%s", tcfg->msg);
1275 rdtsc_prof_init(&prof, "enqueue");
1277 if (test_rte_red_init(tcfg) != PASS) {
1283 * set average queue size to target level
1285 *tcfg->tqueue->q = *tcfg->tlevel;
1288 * initialize the rte_red run time data structure
1290 rte_red_rt_data_init(tcfg->tqueue->rdata);
1293 * set the queue average
1295 rte_red_set_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, *tcfg->tlevel);
1296 if (rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata)
1302 enqueue_dequeue_perf(tcfg->tconfig->rconfig,
1303 tcfg->tqueue->rdata,
1305 tcfg->tvar->num_ops,
1306 tcfg->tvar->enqueued,
1307 tcfg->tvar->dropped,
1310 total = *tcfg->tvar->enqueued + *tcfg->tvar->dropped;
1312 printf("\ntotal: %u, enqueued: %u (%.2lf%%), dropped: %u (%.2lf%%)\n", total,
1313 *tcfg->tvar->enqueued, ((double)(*tcfg->tvar->enqueued) / (double)total) * 100.0,
1314 *tcfg->tvar->dropped, ((double)(*tcfg->tvar->dropped) / (double)total) * 100.0);
1316 rdtsc_prof_print(&prof);
1322 * Setup test structures for tests P4, P5, P6
1323 * performance tests 4, 5 and 6
1325 static uint32_t pt4_tlevel[] = {16};
1326 static uint32_t pt5_tlevel[] = {80};
1327 static uint32_t pt6_tlevel[] = {144};
1329 static struct test_var perf2_tvar = {
1331 .num_iterations = 10000,
1333 .dropped = pt_dropped,
1334 .enqueued = pt_enqueued,
1338 static struct test_config perf2_test4_config = {
1339 .ifname = "performance test 4 interface",
1340 .msg = "performance test 4 : use one RED configuration,\n"
1341 " set actual and average queue sizes to level below min threshold,\n"
1342 " dequeue all packets until queue is empty,\n"
1343 " measure enqueue performance when queue is empty\n\n",
1344 .htxt = "iteration "
1351 .tconfig = &pt_tconfig,
1352 .tqueue = &pt_tqueue,
1353 .tvar = &perf2_tvar,
1354 .tlevel = pt4_tlevel,
1357 static struct test_config perf2_test5_config = {
1358 .ifname = "performance test 5 interface",
1359 .msg = "performance test 5 : use one RED configuration,\n"
1360 " set actual and average queue sizes to level in between min and max thresholds,\n"
1361 " dequeue all packets until queue is empty,\n"
1362 " measure enqueue performance when queue is empty\n\n",
1363 .htxt = "iteration "
1370 .tconfig = &pt_tconfig,
1371 .tqueue = &pt_tqueue,
1372 .tvar = &perf2_tvar,
1373 .tlevel = pt5_tlevel,
1376 static struct test_config perf2_test6_config = {
1377 .ifname = "performance test 6 interface",
1378 .msg = "performance test 6 : use one RED configuration,\n"
1379 " set actual and average queue sizes to level above max threshold,\n"
1380 " dequeue all packets until queue is empty,\n"
1381 " measure enqueue performance when queue is empty\n\n",
1382 .htxt = "iteration "
1389 .tconfig = &pt_tconfig,
1390 .tqueue = &pt_tqueue,
1391 .tvar = &perf2_tvar,
1392 .tlevel = pt6_tlevel,
1396 * Performance test function to measure enqueue performance when the
1397 * queue is empty. This runs performance tests 4, 5 and 6
1399 static enum test_result perf2_test(struct test_config *tcfg)
1401 enum test_result result = PASS;
1402 struct rdtsc_prof prof = {0, 0, 0, 0, 0.0, NULL};
1406 printf("%s", tcfg->msg);
1408 rdtsc_prof_init(&prof, "enqueue");
1410 if (test_rte_red_init(tcfg) != PASS) {
1415 printf("%s", tcfg->htxt);
1417 for (i = 0; i < tcfg->tvar->num_iterations; i++) {
1420 double avg_before = 0;
1424 * set average queue size to target level
1426 *tcfg->tqueue->q = *tcfg->tlevel;
1427 count = (*tcfg->tqueue->rdata).count;
1430 * initialize the rte_red run time data structure
1432 rte_red_rt_data_init(tcfg->tqueue->rdata);
1433 (*tcfg->tqueue->rdata).count = count;
1436 * set the queue average
1438 rte_red_set_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata, *tcfg->tlevel);
1439 avg_before = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
1440 if ((avg_before < *tcfg->tlevel) || (avg_before > *tcfg->tlevel)) {
1448 *tcfg->tqueue->q = 0;
1449 rte_red_mark_queue_empty(tcfg->tqueue->rdata, get_port_ts());
1452 * wait for specified period of time
1454 rte_delay_us(tcfg->tvar->wait_usec);
1457 * measure performance of enqueue operation while queue is empty
1460 rdtsc_prof_start(&prof);
1461 ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata,
1462 *tcfg->tqueue->q, ts );
1463 rdtsc_prof_end(&prof);
1466 * gather enqueued/dropped statistics
1469 (*tcfg->tvar->enqueued)++;
1471 (*tcfg->tvar->dropped)++;
1474 * on first and last iteration, confirm that
1475 * average queue size was computed correctly
1477 if ((i == 0) || (i == tcfg->tvar->num_iterations - 1)) {
1478 double avg_after = 0;
1483 avg_after = rte_red_get_avg_float(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
1484 exp_avg = calc_exp_avg_on_empty(avg_before,
1485 (1 << *tcfg->tconfig->wq_log2),
1486 tcfg->tvar->wait_usec);
1487 if (check_avg(&diff, avg_after, exp_avg, (double)tcfg->tqueue->avg_tolerance))
1489 printf("%-15u%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15.4lf%-15s\n",
1490 i, avg_before, avg_after, exp_avg, diff,
1491 (double)tcfg->tqueue->avg_tolerance, ok ? "pass" : "fail");
1498 total = *tcfg->tvar->enqueued + *tcfg->tvar->dropped;
1499 printf("\ntotal: %u, enqueued: %u (%.2lf%%), dropped: %u (%.2lf%%)\n", total,
1500 *tcfg->tvar->enqueued, ((double)(*tcfg->tvar->enqueued) / (double)total) * 100.0,
1501 *tcfg->tvar->dropped, ((double)(*tcfg->tvar->dropped) / (double)total) * 100.0);
1503 rdtsc_prof_print(&prof);
1509 * setup default values for overflow test structures
1511 static uint32_t avg_max = 0;
1512 static uint32_t avg_max_bits = 0;
1514 static struct rte_red_config ovfl_wrconfig[1];
1515 static struct rte_red ovfl_rtdata[1];
1516 static uint8_t ovfl_maxp_inv[] = {10};
1517 static uint32_t ovfl_qconfig[] = {0, 0, 1, 1};
1518 static uint32_t ovfl_q[] ={0};
1519 static uint32_t ovfl_dropped[] ={0};
1520 static uint32_t ovfl_enqueued[] ={0};
1521 static uint32_t ovfl_tlevel[] = {1023};
1522 static uint8_t ovfl_wq_log2[] = {12};
1524 static struct test_rte_red_config ovfl_tconfig = {
1525 .rconfig = ovfl_wrconfig,
1526 .num_cfg = RTE_DIM(ovfl_wrconfig),
1527 .wq_log2 = ovfl_wq_log2,
1530 .maxp_inv = ovfl_maxp_inv,
1533 static struct test_queue ovfl_tqueue = {
1534 .rdata = ovfl_rtdata,
1535 .num_queues = RTE_DIM(ovfl_rtdata),
1536 .qconfig = ovfl_qconfig,
1538 .q_ramp_up = 1000000,
1539 .avg_ramp_up = 1000000,
1540 .avg_tolerance = 5, /* 10 percent */
1541 .drop_tolerance = 50, /* 50 percent */
1544 static struct test_var ovfl_tvar = {
1546 .num_iterations = 1,
1549 .dropped = ovfl_dropped,
1550 .enqueued = ovfl_enqueued,
1554 static void ovfl_check_avg(uint32_t avg)
1556 if (avg > avg_max) {
1560 avg_log = log(((double)avg_max));
1561 avg_log = avg_log / log(2.0);
1562 bits = (uint32_t)ceil(avg_log);
1563 if (bits > avg_max_bits)
1564 avg_max_bits = bits;
1568 static struct test_config ovfl_test1_config = {
1569 .ifname = "queue avergage overflow test interface",
1570 .msg = "overflow test 1 : use one RED configuration,\n"
1571 " increase average queue size to target level,\n"
1572 " check maximum number of bits requirte_red to represent avg_s\n\n",
1573 .htxt = "avg queue size "
1583 .tconfig = &ovfl_tconfig,
1584 .tqueue = &ovfl_tqueue,
1586 .tlevel = ovfl_tlevel,
1589 static enum test_result ovfl_test1(struct test_config *tcfg)
1591 enum test_result result = PASS;
1594 double drop_rate = 0.0;
1595 double drop_prob = 0.0;
1599 printf("%s", tcfg->msg);
1601 if (test_rte_red_init(tcfg) != PASS) {
1608 * reset rte_red run-time data
1610 rte_red_rt_data_init(tcfg->tqueue->rdata);
1613 * increase actual queue size
1615 for (i = 0; i < tcfg->tqueue->q_ramp_up; i++) {
1616 ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata,
1617 *tcfg->tqueue->q, get_port_ts());
1620 if (++(*tcfg->tqueue->q) >= *tcfg->tlevel)
1628 for (i = 0; i < tcfg->tqueue->avg_ramp_up; i++) {
1629 ret = rte_red_enqueue(tcfg->tconfig->rconfig, tcfg->tqueue->rdata,
1630 *tcfg->tqueue->q, get_port_ts());
1631 ovfl_check_avg((*tcfg->tqueue->rdata).avg);
1632 avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
1633 if (avg == *tcfg->tlevel) {
1635 (*tcfg->tvar->enqueued)++;
1637 (*tcfg->tvar->dropped)++;
1642 * check if target average queue size has been reached
1644 avg = rte_red_get_avg_int(tcfg->tconfig->rconfig, tcfg->tqueue->rdata);
1645 if (avg != *tcfg->tlevel) {
1651 * check drop rate against drop probability
1653 drop_rate = calc_drop_rate(*tcfg->tvar->enqueued, *tcfg->tvar->dropped);
1654 drop_prob = calc_drop_prob(tcfg->tconfig->min_th,
1655 tcfg->tconfig->max_th,
1656 *tcfg->tconfig->maxp_inv,
1658 if (!check_drop_rate(&diff, drop_rate, drop_prob, (double)tcfg->tqueue->drop_tolerance))
1661 printf("%s", tcfg->htxt);
1663 printf("%-16u%-9u%-15u0x%08x %-10u%-10u%-10u%-13.2lf%-13.2lf\n",
1664 avg, *tcfg->tconfig->wq_log2, RTE_RED_SCALING,
1665 avg_max, avg_max_bits,
1666 *tcfg->tvar->enqueued, *tcfg->tvar->dropped,
1667 drop_prob * 100.0, drop_rate * 100.0);
1673 * define the functional and performance tests to be executed
1675 struct tests func_tests[] = {
1676 { &func_test1_config, func_test1 },
1677 { &func_test2_config, func_test2 },
1678 { &func_test3_config, func_test3 },
1679 { &func_test4_config, func_test4 },
1680 { &func_test5_config, func_test5 },
1681 { &func_test6_config, func_test6 },
1682 { &ovfl_test1_config, ovfl_test1 },
1685 struct tests func_tests_quick[] = {
1686 { &func_test1_config, func_test1 },
1687 { &func_test2_config, func_test2 },
1688 { &func_test3_config, func_test3 },
1689 /* no test 4 as it takes a lot of time */
1690 { &func_test5_config, func_test5 },
1691 { &func_test6_config, func_test6 },
1692 { &ovfl_test1_config, ovfl_test1 },
1695 struct tests perf_tests[] = {
1696 { &perf1_test1_config, perf1_test },
1697 { &perf1_test2_config, perf1_test },
1698 { &perf1_test3_config, perf1_test },
1699 { &perf2_test4_config, perf2_test },
1700 { &perf2_test5_config, perf2_test },
1701 { &perf2_test6_config, perf2_test },
1705 * function to execute the required_red tests
1707 static void run_tests(struct tests *test_type, uint32_t test_count, uint32_t *num_tests, uint32_t *num_pass)
1709 enum test_result result = PASS;
1712 for (i = 0; i < test_count; i++) {
1713 printf("\n--------------------------------------------------------------------------------\n");
1714 result = test_type[i].testfn(test_type[i].testcfg);
1716 if (result == PASS) {
1718 printf("-------------------------------------<pass>-------------------------------------\n");
1720 printf("-------------------------------------<fail>-------------------------------------\n");
1727 * check if functions accept invalid parameters
1729 * First, all functions will be called without initialized RED
1730 * Then, all of them will be called with NULL/invalid parameters
1732 * Some functions are not tested as they are performance-critical and thus
1733 * don't do any parameter checking.
1736 test_invalid_parameters(void)
1738 struct rte_red_config config;
1740 if (rte_red_rt_data_init(NULL) == 0) {
1741 printf("rte_red_rt_data_init should have failed!\n");
1745 if (rte_red_config_init(NULL, 0, 0, 0, 0) == 0) {
1746 printf("rte_red_config_init should have failed!\n");
1750 if (rte_red_rt_data_init(NULL) == 0) {
1751 printf("rte_red_rt_data_init should have failed!\n");
1756 if (rte_red_config_init(NULL, 0, 0, 0, 0) == 0) {
1757 printf("%i: rte_red_config_init should have failed!\n", __LINE__);
1760 /* min_treshold == max_treshold */
1761 if (rte_red_config_init(&config, 0, 1, 1, 0) == 0) {
1762 printf("%i: rte_red_config_init should have failed!\n", __LINE__);
1765 /* min_treshold > max_treshold */
1766 if (rte_red_config_init(&config, 0, 2, 1, 0) == 0) {
1767 printf("%i: rte_red_config_init should have failed!\n", __LINE__);
1770 /* wq_log2 > RTE_RED_WQ_LOG2_MAX */
1771 if (rte_red_config_init(&config,
1772 RTE_RED_WQ_LOG2_MAX + 1, 1, 2, 0) == 0) {
1773 printf("%i: rte_red_config_init should have failed!\n", __LINE__);
1776 /* wq_log2 < RTE_RED_WQ_LOG2_MIN */
1777 if (rte_red_config_init(&config,
1778 RTE_RED_WQ_LOG2_MIN - 1, 1, 2, 0) == 0) {
1779 printf("%i: rte_red_config_init should have failed!\n", __LINE__);
1782 /* maxp_inv > RTE_RED_MAXP_INV_MAX */
1783 if (rte_red_config_init(&config,
1784 RTE_RED_WQ_LOG2_MIN, 1, 2, RTE_RED_MAXP_INV_MAX + 1) == 0) {
1785 printf("%i: rte_red_config_init should have failed!\n", __LINE__);
1788 /* maxp_inv < RTE_RED_MAXP_INV_MIN */
1789 if (rte_red_config_init(&config,
1790 RTE_RED_WQ_LOG2_MIN, 1, 2, RTE_RED_MAXP_INV_MIN - 1) == 0) {
1791 printf("%i: rte_red_config_init should have failed!\n", __LINE__);
1799 show_stats(const uint32_t num_tests, const uint32_t num_pass)
1801 if (num_pass == num_tests)
1802 printf("[total: %u, pass: %u]\n", num_tests, num_pass);
1804 printf("[total: %u, pass: %u, fail: %u]\n", num_tests, num_pass,
1805 num_tests - num_pass);
1809 tell_the_result(const uint32_t num_tests, const uint32_t num_pass)
1811 return (num_pass == num_tests) ? 0 : 1;
1817 uint32_t num_tests = 0;
1818 uint32_t num_pass = 0;
1820 if (test_invalid_parameters() < 0)
1822 run_tests(func_tests_quick, RTE_DIM(func_tests_quick),
1823 &num_tests, &num_pass);
1824 show_stats(num_tests, num_pass);
1825 return tell_the_result(num_tests, num_pass);
1831 uint32_t num_tests = 0;
1832 uint32_t num_pass = 0;
1834 run_tests(perf_tests, RTE_DIM(perf_tests), &num_tests, &num_pass);
1835 show_stats(num_tests, num_pass);
1836 return tell_the_result(num_tests, num_pass);
1842 uint32_t num_tests = 0;
1843 uint32_t num_pass = 0;
1845 if (test_invalid_parameters() < 0)
1848 run_tests(func_tests, RTE_DIM(func_tests), &num_tests, &num_pass);
1849 run_tests(perf_tests, RTE_DIM(perf_tests), &num_tests, &num_pass);
1850 show_stats(num_tests, num_pass);
1851 return tell_the_result(num_tests, num_pass);
1854 REGISTER_TEST_COMMAND(red_autotest, test_red);
1855 REGISTER_TEST_COMMAND(red_perf, test_red_perf);
1856 REGISTER_TEST_COMMAND(red_all, test_red_all);