1
2
3
4
5#include <stdio.h>
6#include <string.h>
7#include <stdint.h>
8#include <errno.h>
9#include <unistd.h>
10#include <sys/queue.h>
11
12#include <rte_memory.h>
13#include <rte_launch.h>
14#include <rte_eal.h>
15#include <rte_per_lcore.h>
16#include <rte_lcore.h>
17#include <rte_debug.h>
18#include <rte_ethdev.h>
19#include <rte_cycles.h>
20#include <rte_eventdev.h>
21#include <rte_pause.h>
22#include <rte_service.h>
23#include <rte_service_component.h>
24#include <rte_bus_vdev.h>
25
26#include "sw_evdev.h"
27
28#define MAX_PORTS 16
29#define MAX_QIDS 16
30#define NUM_PACKETS (1<<18)
31#define DEQUEUE_DEPTH 128
32
33static int evdev;
34
35struct test {
36 struct rte_mempool *mbuf_pool;
37 uint8_t port[MAX_PORTS];
38 uint8_t qid[MAX_QIDS];
39 int nb_qids;
40 uint32_t service_id;
41};
42
43typedef uint8_t counter_dynfield_t;
44static int counter_dynfield_offset = -1;
45
46static inline counter_dynfield_t *
47counter_field(struct rte_mbuf *mbuf)
48{
49 return RTE_MBUF_DYNFIELD(mbuf, \
50 counter_dynfield_offset, counter_dynfield_t *);
51}
52
53static struct rte_event release_ev;
54
55static inline struct rte_mbuf *
56rte_gen_arp(int portid, struct rte_mempool *mp)
57{
58
59
60
61
62 static const uint8_t arp_request[] = {
63 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xa8,
64 0x6b, 0xfd, 0x02, 0x29, 0x08, 0x06, 0x00, 0x01,
65 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xec, 0xa8,
66 0x6b, 0xfd, 0x02, 0x29, 0x0a, 0x00, 0x00, 0x01,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
68 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00
71 };
72 struct rte_mbuf *m;
73 int pkt_len = sizeof(arp_request) - 1;
74
75 m = rte_pktmbuf_alloc(mp);
76 if (!m)
77 return 0;
78
79 memcpy((void *)((uintptr_t)m->buf_addr + m->data_off),
80 arp_request, pkt_len);
81 rte_pktmbuf_pkt_len(m) = pkt_len;
82 rte_pktmbuf_data_len(m) = pkt_len;
83
84 RTE_SET_USED(portid);
85
86 return m;
87}
88
89static void
90xstats_print(void)
91{
92 const uint32_t XSTATS_MAX = 1024;
93 uint32_t i;
94 uint32_t ids[XSTATS_MAX];
95 uint64_t values[XSTATS_MAX];
96 struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
97
98 for (i = 0; i < XSTATS_MAX; i++)
99 ids[i] = i;
100
101
102 int ret = rte_event_dev_xstats_names_get(evdev,
103 RTE_EVENT_DEV_XSTATS_DEVICE, 0,
104 xstats_names, ids, XSTATS_MAX);
105 if (ret < 0) {
106 printf("%d: xstats names get() returned error\n",
107 __LINE__);
108 return;
109 }
110 ret = rte_event_dev_xstats_get(evdev,
111 RTE_EVENT_DEV_XSTATS_DEVICE,
112 0, ids, values, ret);
113 if (ret > (signed int)XSTATS_MAX)
114 printf("%s %d: more xstats available than space\n",
115 __func__, __LINE__);
116 for (i = 0; (signed int)i < ret; i++) {
117 printf("%d : %s : %"PRIu64"\n",
118 i, xstats_names[i].name, values[i]);
119 }
120
121
122 ret = rte_event_dev_xstats_names_get(evdev,
123 RTE_EVENT_DEV_XSTATS_PORT, 0,
124 xstats_names, ids, XSTATS_MAX);
125 ret = rte_event_dev_xstats_get(evdev,
126 RTE_EVENT_DEV_XSTATS_PORT, 1,
127 ids, values, ret);
128 if (ret > (signed int)XSTATS_MAX)
129 printf("%s %d: more xstats available than space\n",
130 __func__, __LINE__);
131 for (i = 0; (signed int)i < ret; i++) {
132 printf("%d : %s : %"PRIu64"\n",
133 i, xstats_names[i].name, values[i]);
134 }
135
136
137 ret = rte_event_dev_xstats_names_get(evdev,
138 RTE_EVENT_DEV_XSTATS_QUEUE, 0,
139 xstats_names, ids, XSTATS_MAX);
140 ret = rte_event_dev_xstats_get(evdev,
141 RTE_EVENT_DEV_XSTATS_QUEUE,
142 1, ids, values, ret);
143 if (ret > (signed int)XSTATS_MAX)
144 printf("%s %d: more xstats available than space\n",
145 __func__, __LINE__);
146 for (i = 0; (signed int)i < ret; i++) {
147 printf("%d : %s : %"PRIu64"\n",
148 i, xstats_names[i].name, values[i]);
149 }
150}
151
152
153static inline int
154init(struct test *t, int nb_queues, int nb_ports)
155{
156 struct rte_event_dev_config config = {
157 .nb_event_queues = nb_queues,
158 .nb_event_ports = nb_ports,
159 .nb_event_queue_flows = 1024,
160 .nb_events_limit = 4096,
161 .nb_event_port_dequeue_depth = DEQUEUE_DEPTH,
162 .nb_event_port_enqueue_depth = 128,
163 };
164 int ret;
165
166 void *temp = t->mbuf_pool;
167
168 memset(t, 0, sizeof(*t));
169 t->mbuf_pool = temp;
170
171 ret = rte_event_dev_configure(evdev, &config);
172 if (ret < 0)
173 printf("%d: Error configuring device\n", __LINE__);
174 return ret;
175};
176
177static inline int
178create_ports(struct test *t, int num_ports)
179{
180 int i;
181 static const struct rte_event_port_conf conf = {
182 .new_event_threshold = 1024,
183 .dequeue_depth = 32,
184 .enqueue_depth = 64,
185 };
186 if (num_ports > MAX_PORTS)
187 return -1;
188
189 for (i = 0; i < num_ports; i++) {
190 if (rte_event_port_setup(evdev, i, &conf) < 0) {
191 printf("Error setting up port %d\n", i);
192 return -1;
193 }
194 t->port[i] = i;
195 }
196
197 return 0;
198}
199
200static inline int
201create_lb_qids(struct test *t, int num_qids, uint32_t flags)
202{
203 int i;
204
205
206 const struct rte_event_queue_conf conf = {
207 .schedule_type = flags,
208 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
209 .nb_atomic_flows = 1024,
210 .nb_atomic_order_sequences = 1024,
211 };
212
213 for (i = t->nb_qids; i < t->nb_qids + num_qids; i++) {
214 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
215 printf("%d: error creating qid %d\n", __LINE__, i);
216 return -1;
217 }
218 t->qid[i] = i;
219 }
220 t->nb_qids += num_qids;
221 if (t->nb_qids > MAX_QIDS)
222 return -1;
223
224 return 0;
225}
226
227static inline int
228create_atomic_qids(struct test *t, int num_qids)
229{
230 return create_lb_qids(t, num_qids, RTE_SCHED_TYPE_ATOMIC);
231}
232
233static inline int
234create_ordered_qids(struct test *t, int num_qids)
235{
236 return create_lb_qids(t, num_qids, RTE_SCHED_TYPE_ORDERED);
237}
238
239
240static inline int
241create_unordered_qids(struct test *t, int num_qids)
242{
243 return create_lb_qids(t, num_qids, RTE_SCHED_TYPE_PARALLEL);
244}
245
246static inline int
247create_directed_qids(struct test *t, int num_qids, const uint8_t ports[])
248{
249 int i;
250
251
252 static const struct rte_event_queue_conf conf = {
253 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
254 .event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK,
255 };
256
257 for (i = t->nb_qids; i < t->nb_qids + num_qids; i++) {
258 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
259 printf("%d: error creating qid %d\n", __LINE__, i);
260 return -1;
261 }
262 t->qid[i] = i;
263
264 if (rte_event_port_link(evdev, ports[i - t->nb_qids],
265 &t->qid[i], NULL, 1) != 1) {
266 printf("%d: error creating link for qid %d\n",
267 __LINE__, i);
268 return -1;
269 }
270 }
271 t->nb_qids += num_qids;
272 if (t->nb_qids > MAX_QIDS)
273 return -1;
274
275 return 0;
276}
277
278
279static inline int
280cleanup(struct test *t __rte_unused)
281{
282 rte_event_dev_stop(evdev);
283 rte_event_dev_close(evdev);
284 return 0;
285};
286
287struct test_event_dev_stats {
288 uint64_t rx_pkts;
289 uint64_t rx_dropped;
290 uint64_t tx_pkts;
291
292
293 uint64_t port_rx_pkts[MAX_PORTS];
294
295 uint64_t port_rx_dropped[MAX_PORTS];
296
297 uint64_t port_inflight[MAX_PORTS];
298
299 uint64_t port_tx_pkts[MAX_PORTS];
300
301 uint64_t qid_rx_pkts[MAX_QIDS];
302
303 uint64_t qid_rx_dropped[MAX_QIDS];
304
305 uint64_t qid_tx_pkts[MAX_QIDS];
306};
307
308static inline int
309test_event_dev_stats_get(int dev_id, struct test_event_dev_stats *stats)
310{
311 static uint32_t i;
312 static uint32_t total_ids[3];
313 static uint32_t port_rx_pkts_ids[MAX_PORTS];
314 static uint32_t port_rx_dropped_ids[MAX_PORTS];
315 static uint32_t port_inflight_ids[MAX_PORTS];
316 static uint32_t port_tx_pkts_ids[MAX_PORTS];
317 static uint32_t qid_rx_pkts_ids[MAX_QIDS];
318 static uint32_t qid_rx_dropped_ids[MAX_QIDS];
319 static uint32_t qid_tx_pkts_ids[MAX_QIDS];
320
321
322 stats->rx_pkts = rte_event_dev_xstats_by_name_get(dev_id,
323 "dev_rx", &total_ids[0]);
324 stats->rx_dropped = rte_event_dev_xstats_by_name_get(dev_id,
325 "dev_drop", &total_ids[1]);
326 stats->tx_pkts = rte_event_dev_xstats_by_name_get(dev_id,
327 "dev_tx", &total_ids[2]);
328 for (i = 0; i < MAX_PORTS; i++) {
329 char name[32];
330 snprintf(name, sizeof(name), "port_%u_rx", i);
331 stats->port_rx_pkts[i] = rte_event_dev_xstats_by_name_get(
332 dev_id, name, &port_rx_pkts_ids[i]);
333 snprintf(name, sizeof(name), "port_%u_drop", i);
334 stats->port_rx_dropped[i] = rte_event_dev_xstats_by_name_get(
335 dev_id, name, &port_rx_dropped_ids[i]);
336 snprintf(name, sizeof(name), "port_%u_inflight", i);
337 stats->port_inflight[i] = rte_event_dev_xstats_by_name_get(
338 dev_id, name, &port_inflight_ids[i]);
339 snprintf(name, sizeof(name), "port_%u_tx", i);
340 stats->port_tx_pkts[i] = rte_event_dev_xstats_by_name_get(
341 dev_id, name, &port_tx_pkts_ids[i]);
342 }
343 for (i = 0; i < MAX_QIDS; i++) {
344 char name[32];
345 snprintf(name, sizeof(name), "qid_%u_rx", i);
346 stats->qid_rx_pkts[i] = rte_event_dev_xstats_by_name_get(
347 dev_id, name, &qid_rx_pkts_ids[i]);
348 snprintf(name, sizeof(name), "qid_%u_drop", i);
349 stats->qid_rx_dropped[i] = rte_event_dev_xstats_by_name_get(
350 dev_id, name, &qid_rx_dropped_ids[i]);
351 snprintf(name, sizeof(name), "qid_%u_tx", i);
352 stats->qid_tx_pkts[i] = rte_event_dev_xstats_by_name_get(
353 dev_id, name, &qid_tx_pkts_ids[i]);
354 }
355
356 return 0;
357}
358
359
360
361
362
363
364
365
366
367
368
369
370static int
371run_prio_packet_test(struct test *t)
372{
373 int err;
374 const uint32_t MAGIC_SEQN[] = {4711, 1234};
375 const uint32_t PRIORITY[] = {
376 RTE_EVENT_DEV_PRIORITY_NORMAL,
377 RTE_EVENT_DEV_PRIORITY_HIGHEST
378 };
379 unsigned int i;
380 for (i = 0; i < RTE_DIM(MAGIC_SEQN); i++) {
381
382 struct rte_event ev;
383 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
384 if (!arp) {
385 printf("%d: gen of pkt failed\n", __LINE__);
386 return -1;
387 }
388 *rte_event_pmd_selftest_seqn(arp) = MAGIC_SEQN[i];
389
390 ev = (struct rte_event){
391 .priority = PRIORITY[i],
392 .op = RTE_EVENT_OP_NEW,
393 .queue_id = t->qid[0],
394 .mbuf = arp
395 };
396 err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
397 if (err != 1) {
398 printf("%d: error failed to enqueue\n", __LINE__);
399 return -1;
400 }
401 }
402
403 rte_service_run_iter_on_app_lcore(t->service_id, 1);
404
405 struct test_event_dev_stats stats;
406 err = test_event_dev_stats_get(evdev, &stats);
407 if (err) {
408 printf("%d: error failed to get stats\n", __LINE__);
409 return -1;
410 }
411
412 if (stats.port_rx_pkts[t->port[0]] != 2) {
413 printf("%d: error stats incorrect for directed port\n",
414 __LINE__);
415 rte_event_dev_dump(evdev, stdout);
416 return -1;
417 }
418
419 struct rte_event ev, ev2;
420 uint32_t deq_pkts;
421 deq_pkts = rte_event_dequeue_burst(evdev, t->port[0], &ev, 1, 0);
422 if (deq_pkts != 1) {
423 printf("%d: error failed to deq\n", __LINE__);
424 rte_event_dev_dump(evdev, stdout);
425 return -1;
426 }
427 if (*rte_event_pmd_selftest_seqn(ev.mbuf) != MAGIC_SEQN[1]) {
428 printf("%d: first packet out not highest priority\n",
429 __LINE__);
430 rte_event_dev_dump(evdev, stdout);
431 return -1;
432 }
433 rte_pktmbuf_free(ev.mbuf);
434
435 deq_pkts = rte_event_dequeue_burst(evdev, t->port[0], &ev2, 1, 0);
436 if (deq_pkts != 1) {
437 printf("%d: error failed to deq\n", __LINE__);
438 rte_event_dev_dump(evdev, stdout);
439 return -1;
440 }
441 if (*rte_event_pmd_selftest_seqn(ev2.mbuf) != MAGIC_SEQN[0]) {
442 printf("%d: second packet out not lower priority\n",
443 __LINE__);
444 rte_event_dev_dump(evdev, stdout);
445 return -1;
446 }
447 rte_pktmbuf_free(ev2.mbuf);
448
449 cleanup(t);
450 return 0;
451}
452
453static int
454test_single_directed_packet(struct test *t)
455{
456 const int rx_enq = 0;
457 const int wrk_enq = 2;
458 int err;
459
460
461 if (init(t, 3, 3) < 0 ||
462 create_ports(t, 3) < 0 ||
463 create_directed_qids(t, 3, t->port) < 0)
464 return -1;
465
466 if (rte_event_dev_start(evdev) < 0) {
467 printf("%d: Error with start call\n", __LINE__);
468 return -1;
469 }
470
471
472 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
473 struct rte_event ev = {
474 .op = RTE_EVENT_OP_NEW,
475 .queue_id = wrk_enq,
476 .mbuf = arp,
477 };
478
479 if (!arp) {
480 printf("%d: gen of pkt failed\n", __LINE__);
481 return -1;
482 }
483
484 const uint32_t MAGIC_SEQN = 4711;
485 *rte_event_pmd_selftest_seqn(arp) = MAGIC_SEQN;
486
487
488 err = rte_event_enqueue_burst(evdev, rx_enq, &ev, 1);
489 if (err != 1) {
490 printf("%d: error failed to enqueue\n", __LINE__);
491 return -1;
492 }
493
494
495 rte_service_run_iter_on_app_lcore(t->service_id, 1);
496
497 struct test_event_dev_stats stats;
498 err = test_event_dev_stats_get(evdev, &stats);
499 if (err) {
500 printf("%d: error failed to get stats\n", __LINE__);
501 return -1;
502 }
503
504 if (stats.port_rx_pkts[rx_enq] != 1) {
505 printf("%d: error stats incorrect for directed port\n",
506 __LINE__);
507 return -1;
508 }
509
510 uint32_t deq_pkts;
511 deq_pkts = rte_event_dequeue_burst(evdev, wrk_enq, &ev, 1, 0);
512 if (deq_pkts != 1) {
513 printf("%d: error failed to deq\n", __LINE__);
514 return -1;
515 }
516
517 err = test_event_dev_stats_get(evdev, &stats);
518 if (stats.port_rx_pkts[wrk_enq] != 0 &&
519 stats.port_rx_pkts[wrk_enq] != 1) {
520 printf("%d: error directed stats post-dequeue\n", __LINE__);
521 return -1;
522 }
523
524 if (*rte_event_pmd_selftest_seqn(ev.mbuf) != MAGIC_SEQN) {
525 printf("%d: error magic sequence number not dequeued\n",
526 __LINE__);
527 return -1;
528 }
529
530 rte_pktmbuf_free(ev.mbuf);
531 cleanup(t);
532 return 0;
533}
534
535static int
536test_directed_forward_credits(struct test *t)
537{
538 uint32_t i;
539 int32_t err;
540
541 if (init(t, 1, 1) < 0 ||
542 create_ports(t, 1) < 0 ||
543 create_directed_qids(t, 1, t->port) < 0)
544 return -1;
545
546 if (rte_event_dev_start(evdev) < 0) {
547 printf("%d: Error with start call\n", __LINE__);
548 return -1;
549 }
550
551 struct rte_event ev = {
552 .op = RTE_EVENT_OP_NEW,
553 .queue_id = 0,
554 };
555
556 for (i = 0; i < 1000; i++) {
557 err = rte_event_enqueue_burst(evdev, 0, &ev, 1);
558 if (err != 1) {
559 printf("%d: error failed to enqueue\n", __LINE__);
560 return -1;
561 }
562 rte_service_run_iter_on_app_lcore(t->service_id, 1);
563
564 uint32_t deq_pkts;
565 deq_pkts = rte_event_dequeue_burst(evdev, 0, &ev, 1, 0);
566 if (deq_pkts != 1) {
567 printf("%d: error failed to deq\n", __LINE__);
568 return -1;
569 }
570
571
572 ev.op = RTE_EVENT_OP_FORWARD;
573 }
574
575 cleanup(t);
576 return 0;
577}
578
579
580static int
581test_priority_directed(struct test *t)
582{
583 if (init(t, 1, 1) < 0 ||
584 create_ports(t, 1) < 0 ||
585 create_directed_qids(t, 1, t->port) < 0) {
586 printf("%d: Error initializing device\n", __LINE__);
587 return -1;
588 }
589
590 if (rte_event_dev_start(evdev) < 0) {
591 printf("%d: Error with start call\n", __LINE__);
592 return -1;
593 }
594
595 return run_prio_packet_test(t);
596}
597
598static int
599test_priority_atomic(struct test *t)
600{
601 if (init(t, 1, 1) < 0 ||
602 create_ports(t, 1) < 0 ||
603 create_atomic_qids(t, 1) < 0) {
604 printf("%d: Error initializing device\n", __LINE__);
605 return -1;
606 }
607
608
609 if (rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1) != 1) {
610 printf("%d: error mapping qid to port\n", __LINE__);
611 return -1;
612 }
613 if (rte_event_dev_start(evdev) < 0) {
614 printf("%d: Error with start call\n", __LINE__);
615 return -1;
616 }
617
618 return run_prio_packet_test(t);
619}
620
621static int
622test_priority_ordered(struct test *t)
623{
624 if (init(t, 1, 1) < 0 ||
625 create_ports(t, 1) < 0 ||
626 create_ordered_qids(t, 1) < 0) {
627 printf("%d: Error initializing device\n", __LINE__);
628 return -1;
629 }
630
631
632 if (rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1) != 1) {
633 printf("%d: error mapping qid to port\n", __LINE__);
634 return -1;
635 }
636 if (rte_event_dev_start(evdev) < 0) {
637 printf("%d: Error with start call\n", __LINE__);
638 return -1;
639 }
640
641 return run_prio_packet_test(t);
642}
643
644static int
645test_priority_unordered(struct test *t)
646{
647 if (init(t, 1, 1) < 0 ||
648 create_ports(t, 1) < 0 ||
649 create_unordered_qids(t, 1) < 0) {
650 printf("%d: Error initializing device\n", __LINE__);
651 return -1;
652 }
653
654
655 if (rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1) != 1) {
656 printf("%d: error mapping qid to port\n", __LINE__);
657 return -1;
658 }
659 if (rte_event_dev_start(evdev) < 0) {
660 printf("%d: Error with start call\n", __LINE__);
661 return -1;
662 }
663
664 return run_prio_packet_test(t);
665}
666
667static int
668burst_packets(struct test *t)
669{
670
671 uint32_t i;
672 int err;
673 int ret;
674
675
676 if (init(t, 2, 2) < 0 ||
677 create_ports(t, 2) < 0 ||
678 create_atomic_qids(t, 2) < 0) {
679 printf("%d: Error initializing device\n", __LINE__);
680 return -1;
681 }
682
683
684 ret = rte_event_port_link(evdev, t->port[0], &t->qid[0], NULL, 1);
685 if (ret != 1) {
686 printf("%d: error mapping lb qid0\n", __LINE__);
687 return -1;
688 }
689 ret = rte_event_port_link(evdev, t->port[1], &t->qid[1], NULL, 1);
690 if (ret != 1) {
691 printf("%d: error mapping lb qid1\n", __LINE__);
692 return -1;
693 }
694
695 if (rte_event_dev_start(evdev) < 0) {
696 printf("%d: Error with start call\n", __LINE__);
697 return -1;
698 }
699
700
701 const uint32_t rx_port = 0;
702 const uint32_t NUM_PKTS = 2;
703
704 for (i = 0; i < NUM_PKTS; i++) {
705 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
706 if (!arp) {
707 printf("%d: error generating pkt\n", __LINE__);
708 return -1;
709 }
710
711 struct rte_event ev = {
712 .op = RTE_EVENT_OP_NEW,
713 .queue_id = i % 2,
714 .flow_id = i % 3,
715 .mbuf = arp,
716 };
717
718 err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
719 if (err != 1) {
720 printf("%d: Failed to enqueue\n", __LINE__);
721 return -1;
722 }
723 }
724 rte_service_run_iter_on_app_lcore(t->service_id, 1);
725
726
727 struct test_event_dev_stats stats;
728
729 err = test_event_dev_stats_get(evdev, &stats);
730 if (err) {
731 printf("%d: failed to get stats\n", __LINE__);
732 return -1;
733 }
734 if (stats.rx_pkts != NUM_PKTS || stats.tx_pkts != NUM_PKTS) {
735 printf("%d: Sched core didn't receive all %d pkts\n",
736 __LINE__, NUM_PKTS);
737 rte_event_dev_dump(evdev, stdout);
738 return -1;
739 }
740
741 uint32_t deq_pkts;
742 int p;
743
744 deq_pkts = 0;
745
746 do {
747 struct rte_event ev;
748 p = rte_event_dequeue_burst(evdev, t->port[0], &ev, 1, 0);
749 deq_pkts += p;
750 rte_pktmbuf_free(ev.mbuf);
751 } while (p);
752
753 if (deq_pkts != NUM_PKTS/2) {
754 printf("%d: Half of NUM_PKTS didn't arrive at port 1\n",
755 __LINE__);
756 return -1;
757 }
758
759
760 deq_pkts = 0;
761 do {
762 struct rte_event ev;
763 p = rte_event_dequeue_burst(evdev, t->port[1], &ev, 1, 0);
764 deq_pkts += p;
765 rte_pktmbuf_free(ev.mbuf);
766 } while (p);
767 if (deq_pkts != NUM_PKTS/2) {
768 printf("%d: Half of NUM_PKTS didn't arrive at port 2\n",
769 __LINE__);
770 return -1;
771 }
772
773 cleanup(t);
774 return 0;
775}
776
777static int
778abuse_inflights(struct test *t)
779{
780 const int rx_enq = 0;
781 const int wrk_enq = 2;
782 int err;
783
784
785 if (init(t, 1, 4) < 0 ||
786 create_ports(t, 4) < 0 ||
787 create_atomic_qids(t, 1) < 0) {
788 printf("%d: Error initializing device\n", __LINE__);
789 return -1;
790 }
791
792
793 err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
794 if (err != 1) {
795 printf("%d: error mapping lb qid\n", __LINE__);
796 cleanup(t);
797 return -1;
798 }
799
800 if (rte_event_dev_start(evdev) < 0) {
801 printf("%d: Error with start call\n", __LINE__);
802 return -1;
803 }
804
805
806 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &release_ev, 1);
807 if (err != 1) {
808 printf("%d: Failed to enqueue\n", __LINE__);
809 return -1;
810 }
811
812
813 rte_service_run_iter_on_app_lcore(t->service_id, 1);
814
815 struct test_event_dev_stats stats;
816
817 err = test_event_dev_stats_get(evdev, &stats);
818 if (err) {
819 printf("%d: failed to get stats\n", __LINE__);
820 return -1;
821 }
822
823 if (stats.rx_pkts != 0 ||
824 stats.tx_pkts != 0 ||
825 stats.port_inflight[wrk_enq] != 0) {
826 printf("%d: Sched core didn't handle pkt as expected\n",
827 __LINE__);
828 return -1;
829 }
830
831 cleanup(t);
832 return 0;
833}
834
835static int
836xstats_tests(struct test *t)
837{
838 const int wrk_enq = 2;
839 int err;
840
841
842 if (init(t, 1, 4) < 0 ||
843 create_ports(t, 4) < 0 ||
844 create_atomic_qids(t, 1) < 0) {
845 printf("%d: Error initializing device\n", __LINE__);
846 return -1;
847 }
848
849
850 err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
851 if (err != 1) {
852 printf("%d: error mapping lb qid\n", __LINE__);
853 cleanup(t);
854 return -1;
855 }
856
857 if (rte_event_dev_start(evdev) < 0) {
858 printf("%d: Error with start call\n", __LINE__);
859 return -1;
860 }
861
862 const uint32_t XSTATS_MAX = 1024;
863
864 uint32_t i;
865 uint32_t ids[XSTATS_MAX];
866 uint64_t values[XSTATS_MAX];
867 struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
868
869 for (i = 0; i < XSTATS_MAX; i++)
870 ids[i] = i;
871
872
873 int ret = rte_event_dev_xstats_names_get(evdev,
874 RTE_EVENT_DEV_XSTATS_DEVICE,
875 0, xstats_names, ids, XSTATS_MAX);
876 if (ret != 8) {
877 printf("%d: expected 8 stats, got return %d\n", __LINE__, ret);
878 return -1;
879 }
880 ret = rte_event_dev_xstats_get(evdev,
881 RTE_EVENT_DEV_XSTATS_DEVICE,
882 0, ids, values, ret);
883 if (ret != 8) {
884 printf("%d: expected 8 stats, got return %d\n", __LINE__, ret);
885 return -1;
886 }
887
888
889 ret = rte_event_dev_xstats_names_get(evdev,
890 RTE_EVENT_DEV_XSTATS_PORT, 0,
891 xstats_names, ids, XSTATS_MAX);
892 if (ret != 21) {
893 printf("%d: expected 21 stats, got return %d\n", __LINE__, ret);
894 return -1;
895 }
896 ret = rte_event_dev_xstats_get(evdev,
897 RTE_EVENT_DEV_XSTATS_PORT, 0,
898 ids, values, ret);
899 if (ret != 21) {
900 printf("%d: expected 21 stats, got return %d\n", __LINE__, ret);
901 return -1;
902 }
903
904
905 ret = rte_event_dev_xstats_names_get(evdev,
906 RTE_EVENT_DEV_XSTATS_QUEUE,
907 0, xstats_names, ids, XSTATS_MAX);
908 if (ret != 16) {
909 printf("%d: expected 16 stats, got return %d\n", __LINE__, ret);
910 return -1;
911 }
912
913
914 ret = rte_event_dev_xstats_get(evdev,
915 RTE_EVENT_DEV_XSTATS_QUEUE,
916 1, ids, values, ret);
917 if (ret != -EINVAL) {
918 printf("%d: expected 0 stats, got return %d\n", __LINE__, ret);
919 return -1;
920 }
921
922 ret = rte_event_dev_xstats_get(evdev,
923 RTE_EVENT_DEV_XSTATS_QUEUE,
924 0, ids, values, ret);
925 if (ret != 16) {
926 printf("%d: expected 16 stats, got return %d\n", __LINE__, ret);
927 return -1;
928 }
929
930
931 for (i = 0; i < 3; i++) {
932 struct rte_event ev;
933 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
934 if (!arp) {
935 printf("%d: gen of pkt failed\n", __LINE__);
936 return -1;
937 }
938 ev.queue_id = t->qid[i];
939 ev.op = RTE_EVENT_OP_NEW;
940 ev.mbuf = arp;
941 ev.flow_id = 7;
942 *rte_event_pmd_selftest_seqn(arp) = i;
943
944 int err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
945 if (err != 1) {
946 printf("%d: Failed to enqueue\n", __LINE__);
947 return -1;
948 }
949 }
950
951 rte_service_run_iter_on_app_lcore(t->service_id, 1);
952
953
954 int num_stats = rte_event_dev_xstats_names_get(evdev,
955 RTE_EVENT_DEV_XSTATS_DEVICE, 0,
956 xstats_names, ids, XSTATS_MAX);
957 if (num_stats < 0)
958 goto fail;
959 ret = rte_event_dev_xstats_get(evdev,
960 RTE_EVENT_DEV_XSTATS_DEVICE,
961 0, ids, values, num_stats);
962 static const uint64_t expected[] = {3, 3, 0, 1, 0, 0, 4, 1};
963 for (i = 0; (signed int)i < ret; i++) {
964 if (expected[i] != values[i]) {
965 printf(
966 "%d Error xstat %d (id %d) %s : %"PRIu64
967 ", expect %"PRIu64"\n",
968 __LINE__, i, ids[i], xstats_names[i].name,
969 values[i], expected[i]);
970 goto fail;
971 }
972 }
973
974 ret = rte_event_dev_xstats_reset(evdev, RTE_EVENT_DEV_XSTATS_DEVICE,
975 0, NULL, 0);
976
977
978 static const uint64_t expected_zero[] = {0, 0, 0, 0, 0, 0, 0, 0};
979 ret = rte_event_dev_xstats_get(evdev,
980 RTE_EVENT_DEV_XSTATS_DEVICE,
981 0, ids, values, num_stats);
982 for (i = 0; (signed int)i < ret; i++) {
983 if (expected_zero[i] != values[i]) {
984 printf(
985 "%d Error, xstat %d (id %d) %s : %"PRIu64
986 ", expect %"PRIu64"\n",
987 __LINE__, i, ids[i], xstats_names[i].name,
988 values[i], expected_zero[i]);
989 goto fail;
990 }
991 }
992
993
994 num_stats = rte_event_dev_xstats_names_get(evdev,
995 RTE_EVENT_DEV_XSTATS_PORT, 0,
996 xstats_names, ids, XSTATS_MAX);
997 if (num_stats < 0)
998 goto fail;
999 ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_PORT,
1000 0, ids, values, num_stats);
1001
1002 static const uint64_t port_expected[] = {
1003 3 ,
1004 0 ,
1005 0 ,
1006 0 ,
1007 0 ,
1008 29 ,
1009 0 ,
1010 4096 ,
1011 0 ,
1012 32 ,
1013 0 ,
1014
1015 0, 0, 0, 0, 0,
1016 0, 0, 0, 0, 0,
1017 };
1018 if (ret != RTE_DIM(port_expected)) {
1019 printf(
1020 "%s %d: wrong number of port stats (%d), expected %zu\n",
1021 __func__, __LINE__, ret, RTE_DIM(port_expected));
1022 }
1023
1024 for (i = 0; (signed int)i < ret; i++) {
1025 if (port_expected[i] != values[i]) {
1026 printf(
1027 "%s : %d: Error stat %s is %"PRIu64
1028 ", expected %"PRIu64"\n",
1029 __func__, __LINE__, xstats_names[i].name,
1030 values[i], port_expected[i]);
1031 goto fail;
1032 }
1033 }
1034
1035 ret = rte_event_dev_xstats_reset(evdev, RTE_EVENT_DEV_XSTATS_PORT,
1036 0, NULL, 0);
1037
1038
1039 static const uint64_t port_expected_zero[] = {
1040 0 ,
1041 0 ,
1042 0 ,
1043 0 ,
1044 0 ,
1045 29 ,
1046 0 ,
1047 4096 ,
1048 0 ,
1049 32 ,
1050 0 ,
1051
1052 0, 0, 0, 0, 0,
1053 0, 0, 0, 0, 0,
1054 };
1055 ret = rte_event_dev_xstats_get(evdev,
1056 RTE_EVENT_DEV_XSTATS_PORT,
1057 0, ids, values, num_stats);
1058 for (i = 0; (signed int)i < ret; i++) {
1059 if (port_expected_zero[i] != values[i]) {
1060 printf(
1061 "%d, Error, xstat %d (id %d) %s : %"PRIu64
1062 ", expect %"PRIu64"\n",
1063 __LINE__, i, ids[i], xstats_names[i].name,
1064 values[i], port_expected_zero[i]);
1065 goto fail;
1066 }
1067 }
1068
1069
1070 num_stats = rte_event_dev_xstats_names_get(evdev,
1071 RTE_EVENT_DEV_XSTATS_QUEUE, 0,
1072 xstats_names, ids, XSTATS_MAX);
1073 ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_QUEUE,
1074 0, ids, values, num_stats);
1075 if (ret < 0) {
1076 printf("xstats get returned %d\n", ret);
1077 goto fail;
1078 }
1079 if ((unsigned int)ret > XSTATS_MAX)
1080 printf("%s %d: more xstats available than space\n",
1081 __func__, __LINE__);
1082
1083 static const uint64_t queue_expected[] = {
1084 3 ,
1085 3 ,
1086 0 ,
1087 3 ,
1088 0, 0, 0, 0,
1089
1090 0, 0,
1091 0, 0,
1092 1, 3,
1093 0, 0,
1094 };
1095 for (i = 0; (signed int)i < ret; i++) {
1096 if (queue_expected[i] != values[i]) {
1097 printf(
1098 "%d, Error, xstat %d (id %d) %s : %"PRIu64
1099 ", expect %"PRIu64"\n",
1100 __LINE__, i, ids[i], xstats_names[i].name,
1101 values[i], queue_expected[i]);
1102 goto fail;
1103 }
1104 }
1105
1106
1107 ret = rte_event_dev_xstats_reset(evdev,
1108 RTE_EVENT_DEV_XSTATS_QUEUE, 0,
1109 NULL,
1110 0);
1111
1112
1113 static const uint64_t queue_expected_zero[] = {
1114 0 ,
1115 0 ,
1116 0 ,
1117 3 ,
1118 0, 0, 0, 0,
1119
1120 0, 0,
1121 0, 0,
1122 1, 0,
1123 0, 0,
1124 };
1125
1126 ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_QUEUE, 0,
1127 ids, values, num_stats);
1128 int fails = 0;
1129 for (i = 0; (signed int)i < ret; i++) {
1130 if (queue_expected_zero[i] != values[i]) {
1131 printf(
1132 "%d, Error, xstat %d (id %d) %s : %"PRIu64
1133 ", expect %"PRIu64"\n",
1134 __LINE__, i, ids[i], xstats_names[i].name,
1135 values[i], queue_expected_zero[i]);
1136 fails++;
1137 }
1138 }
1139 if (fails) {
1140 printf("%d : %d of values were not as expected above\n",
1141 __LINE__, fails);
1142 goto fail;
1143 }
1144
1145 cleanup(t);
1146 return 0;
1147
1148fail:
1149 rte_event_dev_dump(0, stdout);
1150 cleanup(t);
1151 return -1;
1152}
1153
1154
1155static int
1156xstats_id_abuse_tests(struct test *t)
1157{
1158 int err;
1159 const uint32_t XSTATS_MAX = 1024;
1160 const uint32_t link_port = 2;
1161
1162 uint32_t ids[XSTATS_MAX];
1163 struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
1164
1165
1166 if (init(t, 1, 4) < 0 ||
1167 create_ports(t, 4) < 0 ||
1168 create_atomic_qids(t, 1) < 0) {
1169 printf("%d: Error initializing device\n", __LINE__);
1170 goto fail;
1171 }
1172
1173 err = rte_event_port_link(evdev, t->port[link_port], NULL, NULL, 0);
1174 if (err != 1) {
1175 printf("%d: error mapping lb qid\n", __LINE__);
1176 goto fail;
1177 }
1178
1179 if (rte_event_dev_start(evdev) < 0) {
1180 printf("%d: Error with start call\n", __LINE__);
1181 goto fail;
1182 }
1183
1184
1185 int num_stats = rte_event_dev_xstats_names_get(evdev,
1186 RTE_EVENT_DEV_XSTATS_PORT,
1187 UINT8_MAX-1, xstats_names, ids,
1188 XSTATS_MAX);
1189 if (num_stats != 0) {
1190 printf("%d: expected %d stats, got return %d\n", __LINE__,
1191 0, num_stats);
1192 goto fail;
1193 }
1194
1195 num_stats = rte_event_dev_xstats_names_get(evdev,
1196 RTE_EVENT_DEV_XSTATS_QUEUE,
1197 UINT8_MAX-1, xstats_names, ids,
1198 XSTATS_MAX);
1199 if (num_stats != 0) {
1200 printf("%d: expected %d stats, got return %d\n", __LINE__,
1201 0, num_stats);
1202 goto fail;
1203 }
1204
1205 cleanup(t);
1206 return 0;
1207fail:
1208 cleanup(t);
1209 return -1;
1210}
1211
1212static int
1213port_reconfig_credits(struct test *t)
1214{
1215 if (init(t, 1, 1) < 0) {
1216 printf("%d: Error initializing device\n", __LINE__);
1217 return -1;
1218 }
1219
1220 uint32_t i;
1221 const uint32_t NUM_ITERS = 32;
1222 for (i = 0; i < NUM_ITERS; i++) {
1223 const struct rte_event_queue_conf conf = {
1224 .schedule_type = RTE_SCHED_TYPE_ATOMIC,
1225 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1226 .nb_atomic_flows = 1024,
1227 .nb_atomic_order_sequences = 1024,
1228 };
1229 if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1230 printf("%d: error creating qid\n", __LINE__);
1231 return -1;
1232 }
1233 t->qid[0] = 0;
1234
1235 static const struct rte_event_port_conf port_conf = {
1236 .new_event_threshold = 128,
1237 .dequeue_depth = 32,
1238 .enqueue_depth = 64,
1239 };
1240 if (rte_event_port_setup(evdev, 0, &port_conf) < 0) {
1241 printf("%d Error setting up port\n", __LINE__);
1242 return -1;
1243 }
1244
1245 int links = rte_event_port_link(evdev, 0, NULL, NULL, 0);
1246 if (links != 1) {
1247 printf("%d: error mapping lb qid\n", __LINE__);
1248 goto fail;
1249 }
1250
1251 if (rte_event_dev_start(evdev) < 0) {
1252 printf("%d: Error with start call\n", __LINE__);
1253 goto fail;
1254 }
1255
1256 const uint32_t NPKTS = 1;
1257 uint32_t j;
1258 for (j = 0; j < NPKTS; j++) {
1259 struct rte_event ev;
1260 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1261 if (!arp) {
1262 printf("%d: gen of pkt failed\n", __LINE__);
1263 goto fail;
1264 }
1265 ev.queue_id = t->qid[0];
1266 ev.op = RTE_EVENT_OP_NEW;
1267 ev.mbuf = arp;
1268 int err = rte_event_enqueue_burst(evdev, 0, &ev, 1);
1269 if (err != 1) {
1270 printf("%d: Failed to enqueue\n", __LINE__);
1271 rte_event_dev_dump(0, stdout);
1272 goto fail;
1273 }
1274 }
1275
1276 rte_service_run_iter_on_app_lcore(t->service_id, 1);
1277
1278 struct rte_event ev[NPKTS];
1279 int deq = rte_event_dequeue_burst(evdev, t->port[0], ev,
1280 NPKTS, 0);
1281 if (deq != 1)
1282 printf("%d error; no packet dequeued\n", __LINE__);
1283
1284
1285 if (i != NUM_ITERS-1)
1286 rte_event_dev_stop(evdev);
1287 }
1288
1289 cleanup(t);
1290 return 0;
1291fail:
1292 cleanup(t);
1293 return -1;
1294}
1295
1296static int
1297port_single_lb_reconfig(struct test *t)
1298{
1299 if (init(t, 2, 2) < 0) {
1300 printf("%d: Error initializing device\n", __LINE__);
1301 goto fail;
1302 }
1303
1304 static const struct rte_event_queue_conf conf_lb_atomic = {
1305 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1306 .schedule_type = RTE_SCHED_TYPE_ATOMIC,
1307 .nb_atomic_flows = 1024,
1308 .nb_atomic_order_sequences = 1024,
1309 };
1310 if (rte_event_queue_setup(evdev, 0, &conf_lb_atomic) < 0) {
1311 printf("%d: error creating qid\n", __LINE__);
1312 goto fail;
1313 }
1314
1315 static const struct rte_event_queue_conf conf_single_link = {
1316 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1317 .event_queue_cfg = RTE_EVENT_QUEUE_CFG_SINGLE_LINK,
1318 };
1319 if (rte_event_queue_setup(evdev, 1, &conf_single_link) < 0) {
1320 printf("%d: error creating qid\n", __LINE__);
1321 goto fail;
1322 }
1323
1324 struct rte_event_port_conf port_conf = {
1325 .new_event_threshold = 128,
1326 .dequeue_depth = 32,
1327 .enqueue_depth = 64,
1328 };
1329 if (rte_event_port_setup(evdev, 0, &port_conf) < 0) {
1330 printf("%d Error setting up port\n", __LINE__);
1331 goto fail;
1332 }
1333 if (rte_event_port_setup(evdev, 1, &port_conf) < 0) {
1334 printf("%d Error setting up port\n", __LINE__);
1335 goto fail;
1336 }
1337
1338
1339 uint8_t queue_id = 0;
1340 if (rte_event_port_link(evdev, 0, &queue_id, NULL, 1) != 1) {
1341 printf("%d: error creating link for qid\n", __LINE__);
1342 goto fail;
1343 }
1344
1345 int ret = rte_event_port_unlink(evdev, 0, &queue_id, 1);
1346 if (ret != 1) {
1347 printf("%d: Error unlinking lb port\n", __LINE__);
1348 goto fail;
1349 }
1350
1351 queue_id = 1;
1352 if (rte_event_port_link(evdev, 0, &queue_id, NULL, 1) != 1) {
1353 printf("%d: error creating link for qid\n", __LINE__);
1354 goto fail;
1355 }
1356
1357 queue_id = 0;
1358 int err = rte_event_port_link(evdev, 1, &queue_id, NULL, 1);
1359 if (err != 1) {
1360 printf("%d: error mapping lb qid\n", __LINE__);
1361 goto fail;
1362 }
1363
1364 if (rte_event_dev_start(evdev) < 0) {
1365 printf("%d: Error with start call\n", __LINE__);
1366 goto fail;
1367 }
1368
1369 cleanup(t);
1370 return 0;
1371fail:
1372 cleanup(t);
1373 return -1;
1374}
1375
1376static int
1377xstats_brute_force(struct test *t)
1378{
1379 uint32_t i;
1380 const uint32_t XSTATS_MAX = 1024;
1381 uint32_t ids[XSTATS_MAX];
1382 uint64_t values[XSTATS_MAX];
1383 struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
1384
1385
1386
1387 if (init(t, 1, 4) < 0 ||
1388 create_ports(t, 4) < 0 ||
1389 create_atomic_qids(t, 1) < 0) {
1390 printf("%d: Error initializing device\n", __LINE__);
1391 return -1;
1392 }
1393
1394 int err = rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1395 if (err != 1) {
1396 printf("%d: error mapping lb qid\n", __LINE__);
1397 goto fail;
1398 }
1399
1400 if (rte_event_dev_start(evdev) < 0) {
1401 printf("%d: Error with start call\n", __LINE__);
1402 goto fail;
1403 }
1404
1405 for (i = 0; i < XSTATS_MAX; i++)
1406 ids[i] = i;
1407
1408 for (i = 0; i < 3; i++) {
1409 uint32_t mode = RTE_EVENT_DEV_XSTATS_DEVICE + i;
1410 uint32_t j;
1411 for (j = 0; j < UINT8_MAX; j++) {
1412 rte_event_dev_xstats_names_get(evdev, mode,
1413 j, xstats_names, ids, XSTATS_MAX);
1414
1415 rte_event_dev_xstats_get(evdev, mode, j, ids,
1416 values, XSTATS_MAX);
1417 }
1418 }
1419
1420 cleanup(t);
1421 return 0;
1422fail:
1423 cleanup(t);
1424 return -1;
1425}
1426
1427static int
1428xstats_id_reset_tests(struct test *t)
1429{
1430 const int wrk_enq = 2;
1431 int err;
1432
1433
1434 if (init(t, 1, 4) < 0 ||
1435 create_ports(t, 4) < 0 ||
1436 create_atomic_qids(t, 1) < 0) {
1437 printf("%d: Error initializing device\n", __LINE__);
1438 return -1;
1439 }
1440
1441
1442 err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
1443 if (err != 1) {
1444 printf("%d: error mapping lb qid\n", __LINE__);
1445 goto fail;
1446 }
1447
1448 if (rte_event_dev_start(evdev) < 0) {
1449 printf("%d: Error with start call\n", __LINE__);
1450 goto fail;
1451 }
1452
1453#define XSTATS_MAX 1024
1454 int ret;
1455 uint32_t i;
1456 uint32_t ids[XSTATS_MAX];
1457 uint64_t values[XSTATS_MAX];
1458 struct rte_event_dev_xstats_name xstats_names[XSTATS_MAX];
1459
1460 for (i = 0; i < XSTATS_MAX; i++)
1461 ids[i] = i;
1462
1463#define NUM_DEV_STATS 8
1464
1465 int num_stats = rte_event_dev_xstats_names_get(evdev,
1466 RTE_EVENT_DEV_XSTATS_DEVICE,
1467 0, xstats_names, ids, XSTATS_MAX);
1468 if (num_stats != NUM_DEV_STATS) {
1469 printf("%d: expected %d stats, got return %d\n", __LINE__,
1470 NUM_DEV_STATS, num_stats);
1471 goto fail;
1472 }
1473 ret = rte_event_dev_xstats_get(evdev,
1474 RTE_EVENT_DEV_XSTATS_DEVICE,
1475 0, ids, values, num_stats);
1476 if (ret != NUM_DEV_STATS) {
1477 printf("%d: expected %d stats, got return %d\n", __LINE__,
1478 NUM_DEV_STATS, ret);
1479 goto fail;
1480 }
1481
1482#define NPKTS 7
1483 for (i = 0; i < NPKTS; i++) {
1484 struct rte_event ev;
1485 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1486 if (!arp) {
1487 printf("%d: gen of pkt failed\n", __LINE__);
1488 goto fail;
1489 }
1490 ev.queue_id = t->qid[i];
1491 ev.op = RTE_EVENT_OP_NEW;
1492 ev.mbuf = arp;
1493 *rte_event_pmd_selftest_seqn(arp) = i;
1494
1495 int err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
1496 if (err != 1) {
1497 printf("%d: Failed to enqueue\n", __LINE__);
1498 goto fail;
1499 }
1500 }
1501
1502 rte_service_run_iter_on_app_lcore(t->service_id, 1);
1503
1504 static const char * const dev_names[] = {
1505 "dev_rx", "dev_tx", "dev_drop", "dev_sched_calls",
1506 "dev_sched_no_iq_enq", "dev_sched_no_cq_enq",
1507 "dev_sched_last_iter_bitmask",
1508 "dev_sched_progress_last_iter"
1509 };
1510 uint64_t dev_expected[] = {NPKTS, NPKTS, 0, 1, 0, 0, 4, 1};
1511 for (i = 0; (int)i < ret; i++) {
1512 unsigned int id;
1513 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1514 dev_names[i],
1515 &id);
1516 if (id != i) {
1517 printf("%d: %s id incorrect, expected %d got %d\n",
1518 __LINE__, dev_names[i], i, id);
1519 goto fail;
1520 }
1521 if (val != dev_expected[i]) {
1522 printf("%d: %s value incorrect, expected %"
1523 PRIu64" got %"PRIu64"\n", __LINE__,
1524 dev_names[i], dev_expected[i], val);
1525 goto fail;
1526 }
1527
1528 int reset_ret = rte_event_dev_xstats_reset(evdev,
1529 RTE_EVENT_DEV_XSTATS_DEVICE, 0,
1530 &id,
1531 1);
1532 if (reset_ret) {
1533 printf("%d: failed to reset successfully\n", __LINE__);
1534 goto fail;
1535 }
1536 dev_expected[i] = 0;
1537
1538 val = rte_event_dev_xstats_by_name_get(evdev, dev_names[i], 0);
1539 if (val != dev_expected[i]) {
1540 printf("%d: %s value incorrect, expected %"PRIu64
1541 " got %"PRIu64"\n", __LINE__, dev_names[i],
1542 dev_expected[i], val);
1543 goto fail;
1544 }
1545 };
1546
1547
1548
1549
1550
1551#define PORT_OFF 50
1552
1553#define NUM_PORT_STATS 21
1554
1555#define PORT 2
1556 num_stats = rte_event_dev_xstats_names_get(evdev,
1557 RTE_EVENT_DEV_XSTATS_PORT, PORT,
1558 xstats_names, ids, XSTATS_MAX);
1559 if (num_stats != NUM_PORT_STATS) {
1560 printf("%d: expected %d stats, got return %d\n",
1561 __LINE__, NUM_PORT_STATS, num_stats);
1562 goto fail;
1563 }
1564 ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_PORT, PORT,
1565 ids, values, num_stats);
1566
1567 if (ret != NUM_PORT_STATS) {
1568 printf("%d: expected %d stats, got return %d\n",
1569 __LINE__, NUM_PORT_STATS, ret);
1570 goto fail;
1571 }
1572 static const char * const port_names[] = {
1573 "port_2_rx",
1574 "port_2_tx",
1575 "port_2_drop",
1576 "port_2_inflight",
1577 "port_2_avg_pkt_cycles",
1578 "port_2_credits",
1579 "port_2_rx_ring_used",
1580 "port_2_rx_ring_free",
1581 "port_2_cq_ring_used",
1582 "port_2_cq_ring_free",
1583 "port_2_dequeue_calls",
1584 "port_2_dequeues_returning_0",
1585 "port_2_dequeues_returning_1-4",
1586 "port_2_dequeues_returning_5-8",
1587 "port_2_dequeues_returning_9-12",
1588 "port_2_dequeues_returning_13-16",
1589 "port_2_dequeues_returning_17-20",
1590 "port_2_dequeues_returning_21-24",
1591 "port_2_dequeues_returning_25-28",
1592 "port_2_dequeues_returning_29-32",
1593 "port_2_dequeues_returning_33-36",
1594 };
1595 uint64_t port_expected[] = {
1596 0,
1597 NPKTS,
1598 0,
1599 NPKTS,
1600 0,
1601 0,
1602 0,
1603 4096,
1604 NPKTS,
1605 25,
1606 0,
1607 0, 0, 0, 0, 0,
1608 0, 0, 0, 0, 0,
1609 };
1610 uint64_t port_expected_zero[] = {
1611 0,
1612 0,
1613 0,
1614 NPKTS,
1615 0,
1616 0,
1617 0,
1618 4096,
1619 NPKTS,
1620 25,
1621 0,
1622 0, 0, 0, 0, 0,
1623 0, 0, 0, 0, 0,
1624 };
1625 if (RTE_DIM(port_expected) != NUM_PORT_STATS ||
1626 RTE_DIM(port_names) != NUM_PORT_STATS) {
1627 printf("%d: port array of wrong size\n", __LINE__);
1628 goto fail;
1629 }
1630
1631 int failed = 0;
1632 for (i = 0; (int)i < ret; i++) {
1633 unsigned int id;
1634 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1635 port_names[i],
1636 &id);
1637 if (id != i + PORT_OFF) {
1638 printf("%d: %s id incorrect, expected %d got %d\n",
1639 __LINE__, port_names[i], i+PORT_OFF,
1640 id);
1641 failed = 1;
1642 }
1643 if (val != port_expected[i]) {
1644 printf("%d: %s value incorrect, expected %"PRIu64
1645 " got %d\n", __LINE__, port_names[i],
1646 port_expected[i], id);
1647 failed = 1;
1648 }
1649
1650 int reset_ret = rte_event_dev_xstats_reset(evdev,
1651 RTE_EVENT_DEV_XSTATS_PORT, PORT,
1652 &id,
1653 1);
1654 if (reset_ret) {
1655 printf("%d: failed to reset successfully\n", __LINE__);
1656 failed = 1;
1657 }
1658
1659 val = rte_event_dev_xstats_by_name_get(evdev, port_names[i], 0);
1660 if (val != port_expected_zero[i]) {
1661 printf("%d: %s value incorrect, expected %"PRIu64
1662 " got %"PRIu64"\n", __LINE__, port_names[i],
1663 port_expected_zero[i], val);
1664 failed = 1;
1665 }
1666 };
1667 if (failed)
1668 goto fail;
1669
1670
1671#define NUM_Q_STATS 16
1672
1673
1674
1675#define QUEUE_OFF 92
1676 const uint32_t queue = 0;
1677 num_stats = rte_event_dev_xstats_names_get(evdev,
1678 RTE_EVENT_DEV_XSTATS_QUEUE, queue,
1679 xstats_names, ids, XSTATS_MAX);
1680 if (num_stats != NUM_Q_STATS) {
1681 printf("%d: expected %d stats, got return %d\n",
1682 __LINE__, NUM_Q_STATS, num_stats);
1683 goto fail;
1684 }
1685 ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_QUEUE,
1686 queue, ids, values, num_stats);
1687 if (ret != NUM_Q_STATS) {
1688 printf("%d: expected 21 stats, got return %d\n", __LINE__, ret);
1689 goto fail;
1690 }
1691 static const char * const queue_names[] = {
1692 "qid_0_rx",
1693 "qid_0_tx",
1694 "qid_0_drop",
1695 "qid_0_inflight",
1696 "qid_0_iq_0_used",
1697 "qid_0_iq_1_used",
1698 "qid_0_iq_2_used",
1699 "qid_0_iq_3_used",
1700 "qid_0_port_0_pinned_flows",
1701 "qid_0_port_0_packets",
1702 "qid_0_port_1_pinned_flows",
1703 "qid_0_port_1_packets",
1704 "qid_0_port_2_pinned_flows",
1705 "qid_0_port_2_packets",
1706 "qid_0_port_3_pinned_flows",
1707 "qid_0_port_3_packets",
1708 };
1709 uint64_t queue_expected[] = {
1710 7,
1711 7,
1712 0,
1713 7,
1714 0,
1715 0,
1716 0,
1717 0,
1718
1719 0, 0,
1720 0, 0,
1721 1, 7,
1722 0, 0,
1723 };
1724 uint64_t queue_expected_zero[] = {
1725 0,
1726 0,
1727 0,
1728 7,
1729 0,
1730 0,
1731 0,
1732 0,
1733
1734 0, 0,
1735 0, 0,
1736 1, 0,
1737 0, 0,
1738 };
1739 if (RTE_DIM(queue_expected) != NUM_Q_STATS ||
1740 RTE_DIM(queue_expected_zero) != NUM_Q_STATS ||
1741 RTE_DIM(queue_names) != NUM_Q_STATS) {
1742 printf("%d : queue array of wrong size\n", __LINE__);
1743 goto fail;
1744 }
1745
1746 failed = 0;
1747 for (i = 0; (int)i < ret; i++) {
1748 unsigned int id;
1749 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1750 queue_names[i],
1751 &id);
1752 if (id != i + QUEUE_OFF) {
1753 printf("%d: %s id incorrect, expected %d got %d\n",
1754 __LINE__, queue_names[i], i+QUEUE_OFF,
1755 id);
1756 failed = 1;
1757 }
1758 if (val != queue_expected[i]) {
1759 printf("%d: %d: %s value , expected %"PRIu64
1760 " got %"PRIu64"\n", i, __LINE__,
1761 queue_names[i], queue_expected[i], val);
1762 failed = 1;
1763 }
1764
1765 int reset_ret = rte_event_dev_xstats_reset(evdev,
1766 RTE_EVENT_DEV_XSTATS_QUEUE,
1767 queue, &id, 1);
1768 if (reset_ret) {
1769 printf("%d: failed to reset successfully\n", __LINE__);
1770 failed = 1;
1771 }
1772
1773 val = rte_event_dev_xstats_by_name_get(evdev, queue_names[i],
1774 0);
1775 if (val != queue_expected_zero[i]) {
1776 printf("%d: %s value incorrect, expected %"PRIu64
1777 " got %"PRIu64"\n", __LINE__, queue_names[i],
1778 queue_expected_zero[i], val);
1779 failed = 1;
1780 }
1781 };
1782
1783 if (failed)
1784 goto fail;
1785
1786 cleanup(t);
1787 return 0;
1788fail:
1789 cleanup(t);
1790 return -1;
1791}
1792
1793static int
1794ordered_reconfigure(struct test *t)
1795{
1796 if (init(t, 1, 1) < 0 ||
1797 create_ports(t, 1) < 0) {
1798 printf("%d: Error initializing device\n", __LINE__);
1799 return -1;
1800 }
1801
1802 const struct rte_event_queue_conf conf = {
1803 .schedule_type = RTE_SCHED_TYPE_ORDERED,
1804 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1805 .nb_atomic_flows = 1024,
1806 .nb_atomic_order_sequences = 1024,
1807 };
1808
1809 if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1810 printf("%d: error creating qid\n", __LINE__);
1811 goto failed;
1812 }
1813
1814 if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1815 printf("%d: error creating qid, for 2nd time\n", __LINE__);
1816 goto failed;
1817 }
1818
1819 rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1820 if (rte_event_dev_start(evdev) < 0) {
1821 printf("%d: Error with start call\n", __LINE__);
1822 return -1;
1823 }
1824
1825 cleanup(t);
1826 return 0;
1827failed:
1828 cleanup(t);
1829 return -1;
1830}
1831
1832static int
1833qid_priorities(struct test *t)
1834{
1835
1836
1837
1838
1839 unsigned int i;
1840
1841 if (init(t, 3, 1) < 0 ||
1842 create_ports(t, 1) < 0) {
1843 printf("%d: Error initializing device\n", __LINE__);
1844 return -1;
1845 }
1846
1847 for (i = 0; i < 3; i++) {
1848
1849 const struct rte_event_queue_conf conf = {
1850 .schedule_type = RTE_SCHED_TYPE_ATOMIC,
1851
1852 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL - i,
1853 .nb_atomic_flows = 1024,
1854 .nb_atomic_order_sequences = 1024,
1855 };
1856
1857 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
1858 printf("%d: error creating qid %d\n", __LINE__, i);
1859 return -1;
1860 }
1861 t->qid[i] = i;
1862 }
1863 t->nb_qids = i;
1864
1865 rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1866
1867 if (rte_event_dev_start(evdev) < 0) {
1868 printf("%d: Error with start call\n", __LINE__);
1869 return -1;
1870 }
1871
1872
1873 for (i = 0; i < 3; i++) {
1874 struct rte_event ev;
1875 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1876 if (!arp) {
1877 printf("%d: gen of pkt failed\n", __LINE__);
1878 return -1;
1879 }
1880 ev.queue_id = t->qid[i];
1881 ev.op = RTE_EVENT_OP_NEW;
1882 ev.mbuf = arp;
1883 *rte_event_pmd_selftest_seqn(arp) = i;
1884
1885 int err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
1886 if (err != 1) {
1887 printf("%d: Failed to enqueue\n", __LINE__);
1888 return -1;
1889 }
1890 }
1891
1892 rte_service_run_iter_on_app_lcore(t->service_id, 1);
1893
1894
1895 struct rte_event ev[32];
1896 uint32_t deq_pkts =
1897 rte_event_dequeue_burst(evdev, t->port[0], ev, 32, 0);
1898 if (deq_pkts != 3) {
1899 printf("%d: failed to deq packets\n", __LINE__);
1900 rte_event_dev_dump(evdev, stdout);
1901 return -1;
1902 }
1903 for (i = 0; i < 3; i++) {
1904 if (*rte_event_pmd_selftest_seqn(ev[i].mbuf) != 2-i) {
1905 printf(
1906 "%d: qid priority test: seqn %d incorrectly prioritized\n",
1907 __LINE__, i);
1908 }
1909 }
1910
1911 cleanup(t);
1912 return 0;
1913}
1914
1915static int
1916unlink_in_progress(struct test *t)
1917{
1918
1919
1920
1921
1922 unsigned int i;
1923
1924 if (init(t, 3, 1) < 0 ||
1925 create_ports(t, 1) < 0) {
1926 printf("%d: Error initializing device\n", __LINE__);
1927 return -1;
1928 }
1929
1930 for (i = 0; i < 3; i++) {
1931
1932 const struct rte_event_queue_conf conf = {
1933 .schedule_type = RTE_SCHED_TYPE_ATOMIC,
1934
1935 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL - i,
1936 .nb_atomic_flows = 1024,
1937 .nb_atomic_order_sequences = 1024,
1938 };
1939
1940 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
1941 printf("%d: error creating qid %d\n", __LINE__, i);
1942 return -1;
1943 }
1944 t->qid[i] = i;
1945 }
1946 t->nb_qids = i;
1947
1948 rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1949
1950 if (rte_event_dev_start(evdev) < 0) {
1951 printf("%d: Error with start call\n", __LINE__);
1952 return -1;
1953 }
1954
1955
1956 int ret = rte_event_port_unlink(evdev, t->port[0], NULL, 0);
1957 if (ret < 0) {
1958 printf("%d: Failed to unlink queues\n", __LINE__);
1959 return -1;
1960 }
1961
1962
1963 int unlinks_in_progress =
1964 rte_event_port_unlinks_in_progress(evdev, t->port[0]);
1965 if (unlinks_in_progress != 3) {
1966 printf("%d: Expected num unlinks in progress == 3, got %d\n",
1967 __LINE__, unlinks_in_progress);
1968 return -1;
1969 }
1970
1971
1972 rte_service_run_iter_on_app_lcore(t->service_id, 1);
1973
1974
1975 unlinks_in_progress =
1976 rte_event_port_unlinks_in_progress(evdev, t->port[0]);
1977 if (unlinks_in_progress != 0) {
1978 printf("%d: Expected num unlinks in progress == 0, got %d\n",
1979 __LINE__, unlinks_in_progress);
1980 }
1981
1982 cleanup(t);
1983 return 0;
1984}
1985
1986static int
1987load_balancing(struct test *t)
1988{
1989 const int rx_enq = 0;
1990 int err;
1991 uint32_t i;
1992
1993 if (init(t, 1, 4) < 0 ||
1994 create_ports(t, 4) < 0 ||
1995 create_atomic_qids(t, 1) < 0) {
1996 printf("%d: Error initializing device\n", __LINE__);
1997 return -1;
1998 }
1999
2000 for (i = 0; i < 3; i++) {
2001
2002 if (rte_event_port_link(evdev, t->port[i+1], &t->qid[0],
2003 NULL, 1) != 1) {
2004 printf("%d: error mapping qid to port %d\n",
2005 __LINE__, i);
2006 return -1;
2007 }
2008 }
2009
2010 if (rte_event_dev_start(evdev) < 0) {
2011 printf("%d: Error with start call\n", __LINE__);
2012 return -1;
2013 }
2014
2015
2016
2017
2018
2019
2020
2021 static uint32_t flows[] = {0, 1, 1, 0, 0, 2, 2, 0, 2};
2022
2023 for (i = 0; i < RTE_DIM(flows); i++) {
2024 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2025 if (!arp) {
2026 printf("%d: gen of pkt failed\n", __LINE__);
2027 return -1;
2028 }
2029
2030 struct rte_event ev = {
2031 .op = RTE_EVENT_OP_NEW,
2032 .queue_id = t->qid[0],
2033 .flow_id = flows[i],
2034 .mbuf = arp,
2035 };
2036
2037 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2038 if (err != 1) {
2039 printf("%d: Failed to enqueue\n", __LINE__);
2040 return -1;
2041 }
2042 }
2043
2044 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2045
2046 struct test_event_dev_stats stats;
2047 err = test_event_dev_stats_get(evdev, &stats);
2048 if (err) {
2049 printf("%d: failed to get stats\n", __LINE__);
2050 return -1;
2051 }
2052
2053 if (stats.port_inflight[1] != 4) {
2054 printf("%d:%s: port 1 inflight not correct\n", __LINE__,
2055 __func__);
2056 return -1;
2057 }
2058 if (stats.port_inflight[2] != 2) {
2059 printf("%d:%s: port 2 inflight not correct\n", __LINE__,
2060 __func__);
2061 return -1;
2062 }
2063 if (stats.port_inflight[3] != 3) {
2064 printf("%d:%s: port 3 inflight not correct\n", __LINE__,
2065 __func__);
2066 return -1;
2067 }
2068
2069 cleanup(t);
2070 return 0;
2071}
2072
2073static int
2074load_balancing_history(struct test *t)
2075{
2076 struct test_event_dev_stats stats = {0};
2077 const int rx_enq = 0;
2078 int err;
2079 uint32_t i;
2080
2081
2082 if (init(t, 1, 4) < 0 ||
2083 create_ports(t, 4) < 0 ||
2084 create_atomic_qids(t, 1) < 0)
2085 return -1;
2086
2087
2088 if (rte_event_port_link(evdev, t->port[1], &t->qid[0], NULL, 1) != 1) {
2089 printf("%d: error mapping port 1 qid\n", __LINE__);
2090 return -1;
2091 }
2092 if (rte_event_port_link(evdev, t->port[2], &t->qid[0], NULL, 1) != 1) {
2093 printf("%d: error mapping port 2 qid\n", __LINE__);
2094 return -1;
2095 }
2096 if (rte_event_port_link(evdev, t->port[3], &t->qid[0], NULL, 1) != 1) {
2097 printf("%d: error mapping port 3 qid\n", __LINE__);
2098 return -1;
2099 }
2100 if (rte_event_dev_start(evdev) < 0) {
2101 printf("%d: Error with start call\n", __LINE__);
2102 return -1;
2103 }
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118 static uint32_t flows1[] = {0, 1, 1, 2};
2119
2120 for (i = 0; i < RTE_DIM(flows1); i++) {
2121 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2122 struct rte_event ev = {
2123 .flow_id = flows1[i],
2124 .op = RTE_EVENT_OP_NEW,
2125 .queue_id = t->qid[0],
2126 .event_type = RTE_EVENT_TYPE_CPU,
2127 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
2128 .mbuf = arp
2129 };
2130
2131 if (!arp) {
2132 printf("%d: gen of pkt failed\n", __LINE__);
2133 return -1;
2134 }
2135 arp->hash.rss = flows1[i];
2136 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2137 if (err != 1) {
2138 printf("%d: Failed to enqueue\n", __LINE__);
2139 return -1;
2140 }
2141 }
2142
2143
2144 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2145
2146
2147 struct rte_event ev;
2148 if (!rte_event_dequeue_burst(evdev, t->port[1], &ev, 1, 0)) {
2149 printf("%d: failed to dequeue\n", __LINE__);
2150 return -1;
2151 }
2152 if (ev.mbuf->hash.rss != flows1[0]) {
2153 printf("%d: unexpected flow received\n", __LINE__);
2154 return -1;
2155 }
2156
2157
2158 rte_event_enqueue_burst(evdev, t->port[1], &release_ev, 1);
2159
2160
2161 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2162
2163
2164
2165
2166
2167 static uint32_t flows2[] = { 3, 3, 3, 1, 1, 0 };
2168
2169 for (i = 0; i < RTE_DIM(flows2); i++) {
2170 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2171 struct rte_event ev = {
2172 .flow_id = flows2[i],
2173 .op = RTE_EVENT_OP_NEW,
2174 .queue_id = t->qid[0],
2175 .event_type = RTE_EVENT_TYPE_CPU,
2176 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
2177 .mbuf = arp
2178 };
2179
2180 if (!arp) {
2181 printf("%d: gen of pkt failed\n", __LINE__);
2182 return -1;
2183 }
2184 arp->hash.rss = flows2[i];
2185
2186 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2187 if (err != 1) {
2188 printf("%d: Failed to enqueue\n", __LINE__);
2189 return -1;
2190 }
2191 }
2192
2193
2194 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2195
2196 err = test_event_dev_stats_get(evdev, &stats);
2197 if (err) {
2198 printf("%d:failed to get stats\n", __LINE__);
2199 return -1;
2200 }
2201
2202
2203
2204
2205 if (stats.port_inflight[1] != 3) {
2206 printf("%d:%s: port 1 inflight not correct\n", __LINE__,
2207 __func__);
2208 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2209 (unsigned int)stats.port_inflight[1],
2210 (unsigned int)stats.port_inflight[2],
2211 (unsigned int)stats.port_inflight[3]);
2212 return -1;
2213 }
2214 if (stats.port_inflight[2] != 4) {
2215 printf("%d:%s: port 2 inflight not correct\n", __LINE__,
2216 __func__);
2217 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2218 (unsigned int)stats.port_inflight[1],
2219 (unsigned int)stats.port_inflight[2],
2220 (unsigned int)stats.port_inflight[3]);
2221 return -1;
2222 }
2223 if (stats.port_inflight[3] != 2) {
2224 printf("%d:%s: port 3 inflight not correct\n", __LINE__,
2225 __func__);
2226 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2227 (unsigned int)stats.port_inflight[1],
2228 (unsigned int)stats.port_inflight[2],
2229 (unsigned int)stats.port_inflight[3]);
2230 return -1;
2231 }
2232
2233 for (i = 1; i <= 3; i++) {
2234 struct rte_event ev;
2235 while (rte_event_dequeue_burst(evdev, i, &ev, 1, 0))
2236 rte_event_enqueue_burst(evdev, i, &release_ev, 1);
2237 }
2238 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2239
2240 cleanup(t);
2241 return 0;
2242}
2243
2244static int
2245invalid_qid(struct test *t)
2246{
2247 struct test_event_dev_stats stats;
2248 const int rx_enq = 0;
2249 int err;
2250 uint32_t i;
2251
2252 if (init(t, 1, 4) < 0 ||
2253 create_ports(t, 4) < 0 ||
2254 create_atomic_qids(t, 1) < 0) {
2255 printf("%d: Error initializing device\n", __LINE__);
2256 return -1;
2257 }
2258
2259
2260 for (i = 0; i < 4; i++) {
2261 err = rte_event_port_link(evdev, t->port[i], &t->qid[0],
2262 NULL, 1);
2263 if (err != 1) {
2264 printf("%d: error mapping port 1 qid\n", __LINE__);
2265 return -1;
2266 }
2267 }
2268
2269 if (rte_event_dev_start(evdev) < 0) {
2270 printf("%d: Error with start call\n", __LINE__);
2271 return -1;
2272 }
2273
2274
2275
2276
2277
2278
2279
2280 static uint32_t flows1[] = {20};
2281
2282 for (i = 0; i < RTE_DIM(flows1); i++) {
2283 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2284 if (!arp) {
2285 printf("%d: gen of pkt failed\n", __LINE__);
2286 return -1;
2287 }
2288
2289 struct rte_event ev = {
2290 .op = RTE_EVENT_OP_NEW,
2291 .queue_id = t->qid[0] + flows1[i],
2292 .flow_id = i,
2293 .mbuf = arp,
2294 };
2295
2296 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2297 if (err != 1) {
2298 printf("%d: Failed to enqueue\n", __LINE__);
2299 return -1;
2300 }
2301 }
2302
2303
2304 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2305
2306 err = test_event_dev_stats_get(evdev, &stats);
2307 if (err) {
2308 printf("%d: failed to get stats\n", __LINE__);
2309 return -1;
2310 }
2311
2312
2313
2314
2315 if (stats.port_inflight[0] != 0) {
2316 printf("%d:%s: port 1 inflight count not correct\n", __LINE__,
2317 __func__);
2318 rte_event_dev_dump(evdev, stdout);
2319 return -1;
2320 }
2321 if (stats.port_rx_dropped[0] != 1) {
2322 printf("%d:%s: port 1 drops\n", __LINE__, __func__);
2323 rte_event_dev_dump(evdev, stdout);
2324 return -1;
2325 }
2326
2327 if (stats.rx_dropped != 0) {
2328 printf("%d:%s: port 1 dropped count not correct\n", __LINE__,
2329 __func__);
2330 rte_event_dev_dump(evdev, stdout);
2331 return -1;
2332 }
2333
2334 cleanup(t);
2335 return 0;
2336}
2337
2338static int
2339single_packet(struct test *t)
2340{
2341 const uint32_t MAGIC_SEQN = 7321;
2342 struct rte_event ev;
2343 struct test_event_dev_stats stats;
2344 const int rx_enq = 0;
2345 const int wrk_enq = 2;
2346 int err;
2347
2348
2349 if (init(t, 1, 4) < 0 ||
2350 create_ports(t, 4) < 0 ||
2351 create_atomic_qids(t, 1) < 0) {
2352 printf("%d: Error initializing device\n", __LINE__);
2353 return -1;
2354 }
2355
2356
2357 err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
2358 if (err != 1) {
2359 printf("%d: error mapping lb qid\n", __LINE__);
2360 cleanup(t);
2361 return -1;
2362 }
2363
2364 if (rte_event_dev_start(evdev) < 0) {
2365 printf("%d: Error with start call\n", __LINE__);
2366 return -1;
2367 }
2368
2369
2370 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2371 if (!arp) {
2372 printf("%d: gen of pkt failed\n", __LINE__);
2373 return -1;
2374 }
2375
2376 ev.op = RTE_EVENT_OP_NEW;
2377 ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
2378 ev.mbuf = arp;
2379 ev.queue_id = 0;
2380 ev.flow_id = 3;
2381 *rte_event_pmd_selftest_seqn(arp) = MAGIC_SEQN;
2382
2383 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2384 if (err != 1) {
2385 printf("%d: Failed to enqueue\n", __LINE__);
2386 return -1;
2387 }
2388
2389 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2390
2391 err = test_event_dev_stats_get(evdev, &stats);
2392 if (err) {
2393 printf("%d: failed to get stats\n", __LINE__);
2394 return -1;
2395 }
2396
2397 if (stats.rx_pkts != 1 ||
2398 stats.tx_pkts != 1 ||
2399 stats.port_inflight[wrk_enq] != 1) {
2400 printf("%d: Sched core didn't handle pkt as expected\n",
2401 __LINE__);
2402 rte_event_dev_dump(evdev, stdout);
2403 return -1;
2404 }
2405
2406 uint32_t deq_pkts;
2407
2408 deq_pkts = rte_event_dequeue_burst(evdev, t->port[wrk_enq], &ev, 1, 0);
2409 if (deq_pkts < 1) {
2410 printf("%d: Failed to deq\n", __LINE__);
2411 return -1;
2412 }
2413
2414 err = test_event_dev_stats_get(evdev, &stats);
2415 if (err) {
2416 printf("%d: failed to get stats\n", __LINE__);
2417 return -1;
2418 }
2419
2420 err = test_event_dev_stats_get(evdev, &stats);
2421 if (*rte_event_pmd_selftest_seqn(ev.mbuf) != MAGIC_SEQN) {
2422 printf("%d: magic sequence number not dequeued\n", __LINE__);
2423 return -1;
2424 }
2425
2426 rte_pktmbuf_free(ev.mbuf);
2427 err = rte_event_enqueue_burst(evdev, t->port[wrk_enq], &release_ev, 1);
2428 if (err != 1) {
2429 printf("%d: Failed to enqueue\n", __LINE__);
2430 return -1;
2431 }
2432 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2433
2434 err = test_event_dev_stats_get(evdev, &stats);
2435 if (stats.port_inflight[wrk_enq] != 0) {
2436 printf("%d: port inflight not correct\n", __LINE__);
2437 return -1;
2438 }
2439
2440 cleanup(t);
2441 return 0;
2442}
2443
2444static int
2445inflight_counts(struct test *t)
2446{
2447 struct rte_event ev;
2448 struct test_event_dev_stats stats;
2449 const int rx_enq = 0;
2450 const int p1 = 1;
2451 const int p2 = 2;
2452 int err;
2453 int i;
2454
2455
2456 if (init(t, 2, 3) < 0 ||
2457 create_ports(t, 3) < 0 ||
2458 create_atomic_qids(t, 2) < 0) {
2459 printf("%d: Error initializing device\n", __LINE__);
2460 return -1;
2461 }
2462
2463
2464 err = rte_event_port_link(evdev, t->port[p1], &t->qid[0], NULL, 1);
2465 if (err != 1) {
2466 printf("%d: error mapping lb qid\n", __LINE__);
2467 cleanup(t);
2468 return -1;
2469 }
2470 err = rte_event_port_link(evdev, t->port[p2], &t->qid[1], NULL, 1);
2471 if (err != 1) {
2472 printf("%d: error mapping lb qid\n", __LINE__);
2473 cleanup(t);
2474 return -1;
2475 }
2476
2477 if (rte_event_dev_start(evdev) < 0) {
2478 printf("%d: Error with start call\n", __LINE__);
2479 return -1;
2480 }
2481
2482
2483#define QID1_NUM 5
2484 for (i = 0; i < QID1_NUM; i++) {
2485 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2486
2487 if (!arp) {
2488 printf("%d: gen of pkt failed\n", __LINE__);
2489 goto err;
2490 }
2491
2492 ev.queue_id = t->qid[0];
2493 ev.op = RTE_EVENT_OP_NEW;
2494 ev.mbuf = arp;
2495 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2496 if (err != 1) {
2497 printf("%d: Failed to enqueue\n", __LINE__);
2498 goto err;
2499 }
2500 }
2501#define QID2_NUM 3
2502 for (i = 0; i < QID2_NUM; i++) {
2503 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2504
2505 if (!arp) {
2506 printf("%d: gen of pkt failed\n", __LINE__);
2507 goto err;
2508 }
2509 ev.queue_id = t->qid[1];
2510 ev.op = RTE_EVENT_OP_NEW;
2511 ev.mbuf = arp;
2512 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2513 if (err != 1) {
2514 printf("%d: Failed to enqueue\n", __LINE__);
2515 goto err;
2516 }
2517 }
2518
2519
2520 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2521
2522 err = test_event_dev_stats_get(evdev, &stats);
2523 if (err) {
2524 printf("%d: failed to get stats\n", __LINE__);
2525 goto err;
2526 }
2527
2528 if (stats.rx_pkts != QID1_NUM + QID2_NUM ||
2529 stats.tx_pkts != QID1_NUM + QID2_NUM) {
2530 printf("%d: Sched core didn't handle pkt as expected\n",
2531 __LINE__);
2532 goto err;
2533 }
2534
2535 if (stats.port_inflight[p1] != QID1_NUM) {
2536 printf("%d: %s port 1 inflight not correct\n", __LINE__,
2537 __func__);
2538 goto err;
2539 }
2540 if (stats.port_inflight[p2] != QID2_NUM) {
2541 printf("%d: %s port 2 inflight not correct\n", __LINE__,
2542 __func__);
2543 goto err;
2544 }
2545
2546
2547
2548 struct rte_event events[QID1_NUM + QID2_NUM];
2549 uint32_t deq_pkts = rte_event_dequeue_burst(evdev, t->port[p1], events,
2550 RTE_DIM(events), 0);
2551
2552 if (deq_pkts != QID1_NUM) {
2553 printf("%d: Port 1: DEQUEUE inflight failed\n", __LINE__);
2554 goto err;
2555 }
2556 err = test_event_dev_stats_get(evdev, &stats);
2557 if (stats.port_inflight[p1] != QID1_NUM) {
2558 printf("%d: port 1 inflight decrement after DEQ != 0\n",
2559 __LINE__);
2560 goto err;
2561 }
2562 for (i = 0; i < QID1_NUM; i++) {
2563 err = rte_event_enqueue_burst(evdev, t->port[p1], &release_ev,
2564 1);
2565 if (err != 1) {
2566 printf("%d: %s rte enqueue of inf release failed\n",
2567 __LINE__, __func__);
2568 goto err;
2569 }
2570 }
2571
2572
2573
2574
2575
2576 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2577
2578 err = test_event_dev_stats_get(evdev, &stats);
2579 if (stats.port_inflight[p1] != 0) {
2580 printf("%d: port 1 inflight NON NULL after DROP\n", __LINE__);
2581 goto err;
2582 }
2583
2584
2585 deq_pkts = rte_event_dequeue_burst(evdev, t->port[p2], events,
2586 RTE_DIM(events), 0);
2587 if (deq_pkts != QID2_NUM) {
2588 printf("%d: Port 2: DEQUEUE inflight failed\n", __LINE__);
2589 goto err;
2590 }
2591 err = test_event_dev_stats_get(evdev, &stats);
2592 if (stats.port_inflight[p2] != QID2_NUM) {
2593 printf("%d: port 1 inflight decrement after DEQ != 0\n",
2594 __LINE__);
2595 goto err;
2596 }
2597 for (i = 0; i < QID2_NUM; i++) {
2598 err = rte_event_enqueue_burst(evdev, t->port[p2], &release_ev,
2599 1);
2600 if (err != 1) {
2601 printf("%d: %s rte enqueue of inf release failed\n",
2602 __LINE__, __func__);
2603 goto err;
2604 }
2605 }
2606
2607
2608
2609
2610
2611 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2612
2613 err = test_event_dev_stats_get(evdev, &stats);
2614 if (stats.port_inflight[p2] != 0) {
2615 printf("%d: port 2 inflight NON NULL after DROP\n", __LINE__);
2616 goto err;
2617 }
2618 cleanup(t);
2619 return 0;
2620
2621err:
2622 rte_event_dev_dump(evdev, stdout);
2623 cleanup(t);
2624 return -1;
2625}
2626
2627static int
2628parallel_basic(struct test *t, int check_order)
2629{
2630 const uint8_t rx_port = 0;
2631 const uint8_t w1_port = 1;
2632 const uint8_t w3_port = 3;
2633 const uint8_t tx_port = 4;
2634 int err;
2635 int i;
2636 uint32_t deq_pkts, j;
2637 struct rte_mbuf *mbufs[3];
2638 struct rte_mbuf *mbufs_out[3] = { 0 };
2639 const uint32_t MAGIC_SEQN = 1234;
2640
2641
2642 if (init(t, 2, tx_port + 1) < 0 ||
2643 create_ports(t, tx_port + 1) < 0 ||
2644 (check_order ? create_ordered_qids(t, 1) :
2645 create_unordered_qids(t, 1)) < 0 ||
2646 create_directed_qids(t, 1, &tx_port)) {
2647 printf("%d: Error initializing device\n", __LINE__);
2648 return -1;
2649 }
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667 for (i = w1_port; i <= w3_port; i++) {
2668 err = rte_event_port_link(evdev, t->port[i], &t->qid[0], NULL,
2669 1);
2670 if (err != 1) {
2671 printf("%d: error mapping lb qid\n", __LINE__);
2672 cleanup(t);
2673 return -1;
2674 }
2675 }
2676
2677 if (rte_event_dev_start(evdev) < 0) {
2678 printf("%d: Error with start call\n", __LINE__);
2679 return -1;
2680 }
2681
2682
2683 for (i = 0; i < 3; i++) {
2684 struct rte_event ev;
2685 mbufs[i] = rte_gen_arp(0, t->mbuf_pool);
2686 if (!mbufs[i]) {
2687 printf("%d: gen of pkt failed\n", __LINE__);
2688 return -1;
2689 }
2690
2691 ev.queue_id = t->qid[0];
2692 ev.op = RTE_EVENT_OP_NEW;
2693 ev.mbuf = mbufs[i];
2694 *rte_event_pmd_selftest_seqn(mbufs[i]) = MAGIC_SEQN + i;
2695
2696
2697 err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
2698 if (err != 1) {
2699 printf("%d: Failed to enqueue pkt %u, retval = %u\n",
2700 __LINE__, i, err);
2701 return -1;
2702 }
2703 }
2704
2705 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2706
2707
2708 struct rte_event deq_ev[w3_port + 1];
2709
2710
2711 for (i = w1_port; i <= w3_port; i++) {
2712 deq_pkts = rte_event_dequeue_burst(evdev, t->port[i],
2713 &deq_ev[i], 1, 0);
2714 if (deq_pkts != 1) {
2715 printf("%d: Failed to deq\n", __LINE__);
2716 rte_event_dev_dump(evdev, stdout);
2717 return -1;
2718 }
2719 }
2720
2721
2722 for (i = w3_port; i >= w1_port; i--) {
2723
2724 deq_ev[i].op = RTE_EVENT_OP_FORWARD;
2725 deq_ev[i].queue_id = t->qid[1];
2726 err = rte_event_enqueue_burst(evdev, t->port[i], &deq_ev[i], 1);
2727 if (err != 1) {
2728 printf("%d: Failed to enqueue\n", __LINE__);
2729 return -1;
2730 }
2731 }
2732 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2733
2734
2735 deq_pkts = rte_event_dequeue_burst(evdev, t->port[tx_port], deq_ev,
2736 3, 0);
2737
2738
2739 if (deq_pkts != 3) {
2740 printf("%d: expected 3 pkts at tx port got %d from port %d\n",
2741 __LINE__, deq_pkts, tx_port);
2742 rte_event_dev_dump(evdev, stdout);
2743 return 1;
2744 }
2745
2746
2747 if (check_order) {
2748 for (j = 0 ; j < deq_pkts ; j++) {
2749 if (*rte_event_pmd_selftest_seqn(deq_ev[j].mbuf) !=
2750 MAGIC_SEQN + j) {
2751 printf("%d: Incorrect sequence number(%d) from port %d\n",
2752 __LINE__,
2753 *rte_event_pmd_selftest_seqn(mbufs_out[j]),
2754 tx_port);
2755 return -1;
2756 }
2757 }
2758 }
2759
2760
2761 cleanup(t);
2762 return 0;
2763}
2764
2765static int
2766ordered_basic(struct test *t)
2767{
2768 return parallel_basic(t, 1);
2769}
2770
2771static int
2772unordered_basic(struct test *t)
2773{
2774 return parallel_basic(t, 0);
2775}
2776
2777static int
2778holb(struct test *t)
2779{
2780 const struct rte_event new_ev = {
2781 .op = RTE_EVENT_OP_NEW
2782
2783 };
2784 struct rte_event ev = new_ev;
2785 unsigned int rx_port = 0;
2786 char rx_port_used_stat[64];
2787 char rx_port_free_stat[64];
2788 char other_port_used_stat[64];
2789
2790 if (init(t, 1, 2) < 0 ||
2791 create_ports(t, 2) < 0 ||
2792 create_atomic_qids(t, 1) < 0) {
2793 printf("%d: Error initializing device\n", __LINE__);
2794 return -1;
2795 }
2796 int nb_links = rte_event_port_link(evdev, t->port[1], NULL, NULL, 0);
2797 if (rte_event_port_link(evdev, t->port[0], NULL, NULL, 0) != 1 ||
2798 nb_links != 1) {
2799 printf("%d: Error links queue to ports\n", __LINE__);
2800 goto err;
2801 }
2802 if (rte_event_dev_start(evdev) < 0) {
2803 printf("%d: Error with start call\n", __LINE__);
2804 goto err;
2805 }
2806
2807
2808 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2809 printf("%d: Error doing first enqueue\n", __LINE__);
2810 goto err;
2811 }
2812 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2813
2814 if (rte_event_dev_xstats_by_name_get(evdev, "port_0_cq_ring_used", NULL)
2815 != 1)
2816 rx_port = 1;
2817
2818 snprintf(rx_port_used_stat, sizeof(rx_port_used_stat),
2819 "port_%u_cq_ring_used", rx_port);
2820 snprintf(rx_port_free_stat, sizeof(rx_port_free_stat),
2821 "port_%u_cq_ring_free", rx_port);
2822 snprintf(other_port_used_stat, sizeof(other_port_used_stat),
2823 "port_%u_cq_ring_used", rx_port ^ 1);
2824 if (rte_event_dev_xstats_by_name_get(evdev, rx_port_used_stat, NULL)
2825 != 1) {
2826 printf("%d: Error, first event not scheduled\n", __LINE__);
2827 goto err;
2828 }
2829
2830
2831 do {
2832 ev = new_ev;
2833 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2834 printf("%d: Error with enqueue\n", __LINE__);
2835 goto err;
2836 }
2837 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2838 } while (rte_event_dev_xstats_by_name_get(evdev,
2839 rx_port_free_stat, NULL) != 0);
2840
2841
2842 ev = new_ev;
2843 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2844 printf("%d: Error with enqueue\n", __LINE__);
2845 goto err;
2846 }
2847 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2848
2849
2850 if (rte_event_dev_xstats_by_name_get(evdev, other_port_used_stat, NULL)
2851 != 0) {
2852 printf("%d: Error, second port CQ is not empty\n", __LINE__);
2853 goto err;
2854 }
2855
2856 if (rte_event_dev_xstats_by_name_get(evdev, "qid_0_iq_0_used", NULL)
2857 != 1) {
2858 printf("%d: Error, QID does not have exactly 1 packet\n",
2859 __LINE__);
2860 goto err;
2861 }
2862
2863
2864 ev = new_ev;
2865 ev.flow_id = 1;
2866 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2867 printf("%d: Error with enqueue\n", __LINE__);
2868 goto err;
2869 }
2870 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2871
2872 if (rte_event_dev_xstats_by_name_get(evdev, other_port_used_stat, NULL)
2873 != 1) {
2874 printf("%d: Error, second flow did not pass out first\n",
2875 __LINE__);
2876 goto err;
2877 }
2878
2879 if (rte_event_dev_xstats_by_name_get(evdev, "qid_0_iq_0_used", NULL)
2880 != 1) {
2881 printf("%d: Error, QID does not have exactly 1 packet\n",
2882 __LINE__);
2883 goto err;
2884 }
2885 cleanup(t);
2886 return 0;
2887err:
2888 rte_event_dev_dump(evdev, stdout);
2889 cleanup(t);
2890 return -1;
2891}
2892
2893static void
2894flush(uint8_t dev_id __rte_unused, struct rte_event event, void *arg)
2895{
2896 *((uint8_t *) arg) += (event.u64 == 0xCA11BACC) ? 1 : 0;
2897}
2898
2899static int
2900dev_stop_flush(struct test *t)
2901{
2902 const struct rte_event new_ev = {
2903 .op = RTE_EVENT_OP_NEW,
2904 .u64 = 0xCA11BACC,
2905 .queue_id = 0
2906 };
2907 struct rte_event ev = new_ev;
2908 uint8_t count = 0;
2909 int i;
2910
2911 if (init(t, 1, 1) < 0 ||
2912 create_ports(t, 1) < 0 ||
2913 create_atomic_qids(t, 1) < 0) {
2914 printf("%d: Error initializing device\n", __LINE__);
2915 return -1;
2916 }
2917
2918
2919 if (rte_event_port_link(evdev, t->port[0], NULL, NULL, 0) != 1) {
2920 printf("%d: Error linking queue to port\n", __LINE__);
2921 goto err;
2922 }
2923
2924 if (rte_event_dev_start(evdev) < 0) {
2925 printf("%d: Error with start call\n", __LINE__);
2926 goto err;
2927 }
2928
2929 for (i = 0; i < DEQUEUE_DEPTH + 1; i++) {
2930 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2931 printf("%d: Error enqueuing events\n", __LINE__);
2932 goto err;
2933 }
2934 }
2935
2936
2937
2938
2939 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2940
2941 if (rte_event_dev_stop_flush_callback_register(evdev, flush, &count)) {
2942 printf("%d: Error installing the flush callback\n", __LINE__);
2943 goto err;
2944 }
2945
2946 cleanup(t);
2947
2948 if (count == 0) {
2949 printf("%d: Error executing the flush callback\n", __LINE__);
2950 goto err;
2951 }
2952
2953 if (rte_event_dev_stop_flush_callback_register(evdev, NULL, NULL)) {
2954 printf("%d: Error uninstalling the flush callback\n", __LINE__);
2955 goto err;
2956 }
2957
2958 return 0;
2959err:
2960 rte_event_dev_dump(evdev, stdout);
2961 cleanup(t);
2962 return -1;
2963}
2964
2965static int
2966worker_loopback_worker_fn(void *arg)
2967{
2968 struct test *t = arg;
2969 uint8_t port = t->port[1];
2970 int count = 0;
2971 int enqd;
2972
2973
2974
2975
2976
2977
2978 printf("%d: \tWorker function started\n", __LINE__);
2979 while (count < NUM_PACKETS) {
2980#define BURST_SIZE 32
2981 struct rte_event ev[BURST_SIZE];
2982 uint16_t i, nb_rx = rte_event_dequeue_burst(evdev, port, ev,
2983 BURST_SIZE, 0);
2984 if (nb_rx == 0) {
2985 rte_pause();
2986 continue;
2987 }
2988
2989 for (i = 0; i < nb_rx; i++) {
2990 ev[i].queue_id++;
2991 if (ev[i].queue_id != 8) {
2992 ev[i].op = RTE_EVENT_OP_FORWARD;
2993 enqd = rte_event_enqueue_burst(evdev, port,
2994 &ev[i], 1);
2995 if (enqd != 1) {
2996 printf("%d: Can't enqueue FWD!!\n",
2997 __LINE__);
2998 return -1;
2999 }
3000 continue;
3001 }
3002
3003 ev[i].queue_id = 0;
3004 (*counter_field(ev[i].mbuf))++;
3005 if (*counter_field(ev[i].mbuf) != 16) {
3006 ev[i].op = RTE_EVENT_OP_FORWARD;
3007 enqd = rte_event_enqueue_burst(evdev, port,
3008 &ev[i], 1);
3009 if (enqd != 1) {
3010 printf("%d: Can't enqueue FWD!!\n",
3011 __LINE__);
3012 return -1;
3013 }
3014 continue;
3015 }
3016
3017 rte_pktmbuf_free(ev[i].mbuf);
3018 count++;
3019 ev[i].op = RTE_EVENT_OP_RELEASE;
3020 enqd = rte_event_enqueue_burst(evdev, port, &ev[i], 1);
3021 if (enqd != 1) {
3022 printf("%d drop enqueue failed\n", __LINE__);
3023 return -1;
3024 }
3025 }
3026 }
3027
3028 return 0;
3029}
3030
3031static int
3032worker_loopback_producer_fn(void *arg)
3033{
3034 struct test *t = arg;
3035 uint8_t port = t->port[0];
3036 uint64_t count = 0;
3037
3038 printf("%d: \tProducer function started\n", __LINE__);
3039 while (count < NUM_PACKETS) {
3040 struct rte_mbuf *m = 0;
3041 do {
3042 m = rte_pktmbuf_alloc(t->mbuf_pool);
3043 } while (m == NULL);
3044
3045 *counter_field(m) = 0;
3046
3047 struct rte_event ev = {
3048 .op = RTE_EVENT_OP_NEW,
3049 .queue_id = t->qid[0],
3050 .flow_id = (uintptr_t)m & 0xFFFF,
3051 .mbuf = m,
3052 };
3053
3054 if (rte_event_enqueue_burst(evdev, port, &ev, 1) != 1) {
3055 while (rte_event_enqueue_burst(evdev, port, &ev, 1) !=
3056 1)
3057 rte_pause();
3058 }
3059
3060 count++;
3061 }
3062
3063 return 0;
3064}
3065
3066static int
3067worker_loopback(struct test *t, uint8_t disable_implicit_release)
3068{
3069
3070
3071
3072 struct test_event_dev_stats stats;
3073 uint64_t print_cycles = 0, cycles = 0;
3074 uint64_t tx_pkts = 0;
3075 int err;
3076 int w_lcore, p_lcore;
3077
3078 static const struct rte_mbuf_dynfield counter_dynfield_desc = {
3079 .name = "rte_event_sw_dynfield_selftest_counter",
3080 .size = sizeof(counter_dynfield_t),
3081 .align = __alignof__(counter_dynfield_t),
3082 };
3083 counter_dynfield_offset =
3084 rte_mbuf_dynfield_register(&counter_dynfield_desc);
3085 if (counter_dynfield_offset < 0) {
3086 printf("Error registering mbuf field\n");
3087 return -rte_errno;
3088 }
3089
3090 if (init(t, 8, 2) < 0 ||
3091 create_atomic_qids(t, 8) < 0) {
3092 printf("%d: Error initializing device\n", __LINE__);
3093 return -1;
3094 }
3095
3096
3097 static struct rte_event_port_conf conf = {
3098 .dequeue_depth = 32,
3099 .enqueue_depth = 64,
3100 };
3101
3102
3103
3104 conf.new_event_threshold = 512;
3105 conf.event_port_cfg = disable_implicit_release ?
3106 RTE_EVENT_PORT_CFG_DISABLE_IMPL_REL : 0;
3107
3108 if (rte_event_port_setup(evdev, 0, &conf) < 0) {
3109 printf("Error setting up RX port\n");
3110 return -1;
3111 }
3112 t->port[0] = 0;
3113
3114 conf.new_event_threshold = 4096;
3115 if (rte_event_port_setup(evdev, 1, &conf) < 0) {
3116 printf("Error setting up TX port\n");
3117 return -1;
3118 }
3119 t->port[1] = 1;
3120
3121
3122 err = rte_event_port_link(evdev, t->port[1], NULL, NULL, 0);
3123 if (err != 8) {
3124 printf("%d: error mapping port 2 to all qids\n", __LINE__);
3125 return -1;
3126 }
3127
3128 if (rte_event_dev_start(evdev) < 0) {
3129 printf("%d: Error with start call\n", __LINE__);
3130 return -1;
3131 }
3132
3133 p_lcore = rte_get_next_lcore(
3134 -1,
3135 1,
3136 0);
3137 w_lcore = rte_get_next_lcore(p_lcore, 1, 0);
3138
3139 rte_eal_remote_launch(worker_loopback_producer_fn, t, p_lcore);
3140 rte_eal_remote_launch(worker_loopback_worker_fn, t, w_lcore);
3141
3142 print_cycles = cycles = rte_get_timer_cycles();
3143 while (rte_eal_get_lcore_state(p_lcore) != WAIT ||
3144 rte_eal_get_lcore_state(w_lcore) != WAIT) {
3145
3146 rte_service_run_iter_on_app_lcore(t->service_id, 1);
3147
3148 uint64_t new_cycles = rte_get_timer_cycles();
3149
3150 if (new_cycles - print_cycles > rte_get_timer_hz()) {
3151 test_event_dev_stats_get(evdev, &stats);
3152 printf(
3153 "%d: \tSched Rx = %"PRIu64", Tx = %"PRIu64"\n",
3154 __LINE__, stats.rx_pkts, stats.tx_pkts);
3155
3156 print_cycles = new_cycles;
3157 }
3158 if (new_cycles - cycles > rte_get_timer_hz() * 3) {
3159 test_event_dev_stats_get(evdev, &stats);
3160 if (stats.tx_pkts == tx_pkts) {
3161 rte_event_dev_dump(evdev, stdout);
3162 printf("Dumping xstats:\n");
3163 xstats_print();
3164 printf(
3165 "%d: No schedules for seconds, deadlock\n",
3166 __LINE__);
3167 return -1;
3168 }
3169 tx_pkts = stats.tx_pkts;
3170 cycles = new_cycles;
3171 }
3172 }
3173 rte_service_run_iter_on_app_lcore(t->service_id, 1);
3174
3175
3176 rte_eal_mp_wait_lcore();
3177
3178 cleanup(t);
3179 return 0;
3180}
3181
3182static struct rte_mempool *eventdev_func_mempool;
3183
3184int
3185test_sw_eventdev(void)
3186{
3187 struct test *t;
3188 int ret;
3189
3190 t = malloc(sizeof(struct test));
3191 if (t == NULL)
3192 return -1;
3193
3194
3195
3196 release_ev.op = RTE_EVENT_OP_RELEASE;
3197
3198 const char *eventdev_name = "event_sw";
3199 evdev = rte_event_dev_get_dev_id(eventdev_name);
3200 if (evdev < 0) {
3201 printf("%d: Eventdev %s not found - creating.\n",
3202 __LINE__, eventdev_name);
3203 if (rte_vdev_init(eventdev_name, NULL) < 0) {
3204 printf("Error creating eventdev\n");
3205 goto test_fail;
3206 }
3207 evdev = rte_event_dev_get_dev_id(eventdev_name);
3208 if (evdev < 0) {
3209 printf("Error finding newly created eventdev\n");
3210 goto test_fail;
3211 }
3212 }
3213
3214 if (rte_event_dev_service_id_get(evdev, &t->service_id) < 0) {
3215 printf("Failed to get service ID for software event dev\n");
3216 goto test_fail;
3217 }
3218
3219 rte_service_runstate_set(t->service_id, 1);
3220 rte_service_set_runstate_mapped_check(t->service_id, 0);
3221
3222
3223 if (!eventdev_func_mempool) {
3224 eventdev_func_mempool = rte_pktmbuf_pool_create(
3225 "EVENTDEV_SW_SA_MBUF_POOL",
3226 (1<<12),
3227 32 ,
3228 0,
3229 512,
3230 rte_socket_id());
3231 if (!eventdev_func_mempool) {
3232 printf("ERROR creating mempool\n");
3233 goto test_fail;
3234 }
3235 }
3236 t->mbuf_pool = eventdev_func_mempool;
3237 printf("*** Running Single Directed Packet test...\n");
3238 ret = test_single_directed_packet(t);
3239 if (ret != 0) {
3240 printf("ERROR - Single Directed Packet test FAILED.\n");
3241 goto test_fail;
3242 }
3243 printf("*** Running Directed Forward Credit test...\n");
3244 ret = test_directed_forward_credits(t);
3245 if (ret != 0) {
3246 printf("ERROR - Directed Forward Credit test FAILED.\n");
3247 goto test_fail;
3248 }
3249 printf("*** Running Single Load Balanced Packet test...\n");
3250 ret = single_packet(t);
3251 if (ret != 0) {
3252 printf("ERROR - Single Packet test FAILED.\n");
3253 goto test_fail;
3254 }
3255 printf("*** Running Unordered Basic test...\n");
3256 ret = unordered_basic(t);
3257 if (ret != 0) {
3258 printf("ERROR - Unordered Basic test FAILED.\n");
3259 goto test_fail;
3260 }
3261 printf("*** Running Ordered Basic test...\n");
3262 ret = ordered_basic(t);
3263 if (ret != 0) {
3264 printf("ERROR - Ordered Basic test FAILED.\n");
3265 goto test_fail;
3266 }
3267 printf("*** Running Burst Packets test...\n");
3268 ret = burst_packets(t);
3269 if (ret != 0) {
3270 printf("ERROR - Burst Packets test FAILED.\n");
3271 goto test_fail;
3272 }
3273 printf("*** Running Load Balancing test...\n");
3274 ret = load_balancing(t);
3275 if (ret != 0) {
3276 printf("ERROR - Load Balancing test FAILED.\n");
3277 goto test_fail;
3278 }
3279 printf("*** Running Prioritized Directed test...\n");
3280 ret = test_priority_directed(t);
3281 if (ret != 0) {
3282 printf("ERROR - Prioritized Directed test FAILED.\n");
3283 goto test_fail;
3284 }
3285 printf("*** Running Prioritized Atomic test...\n");
3286 ret = test_priority_atomic(t);
3287 if (ret != 0) {
3288 printf("ERROR - Prioritized Atomic test FAILED.\n");
3289 goto test_fail;
3290 }
3291
3292 printf("*** Running Prioritized Ordered test...\n");
3293 ret = test_priority_ordered(t);
3294 if (ret != 0) {
3295 printf("ERROR - Prioritized Ordered test FAILED.\n");
3296 goto test_fail;
3297 }
3298 printf("*** Running Prioritized Unordered test...\n");
3299 ret = test_priority_unordered(t);
3300 if (ret != 0) {
3301 printf("ERROR - Prioritized Unordered test FAILED.\n");
3302 goto test_fail;
3303 }
3304 printf("*** Running Invalid QID test...\n");
3305 ret = invalid_qid(t);
3306 if (ret != 0) {
3307 printf("ERROR - Invalid QID test FAILED.\n");
3308 goto test_fail;
3309 }
3310 printf("*** Running Load Balancing History test...\n");
3311 ret = load_balancing_history(t);
3312 if (ret != 0) {
3313 printf("ERROR - Load Balancing History test FAILED.\n");
3314 goto test_fail;
3315 }
3316 printf("*** Running Inflight Count test...\n");
3317 ret = inflight_counts(t);
3318 if (ret != 0) {
3319 printf("ERROR - Inflight Count test FAILED.\n");
3320 goto test_fail;
3321 }
3322 printf("*** Running Abuse Inflights test...\n");
3323 ret = abuse_inflights(t);
3324 if (ret != 0) {
3325 printf("ERROR - Abuse Inflights test FAILED.\n");
3326 goto test_fail;
3327 }
3328 printf("*** Running XStats test...\n");
3329 ret = xstats_tests(t);
3330 if (ret != 0) {
3331 printf("ERROR - XStats test FAILED.\n");
3332 goto test_fail;
3333 }
3334 printf("*** Running XStats ID Reset test...\n");
3335 ret = xstats_id_reset_tests(t);
3336 if (ret != 0) {
3337 printf("ERROR - XStats ID Reset test FAILED.\n");
3338 goto test_fail;
3339 }
3340 printf("*** Running XStats Brute Force test...\n");
3341 ret = xstats_brute_force(t);
3342 if (ret != 0) {
3343 printf("ERROR - XStats Brute Force test FAILED.\n");
3344 goto test_fail;
3345 }
3346 printf("*** Running XStats ID Abuse test...\n");
3347 ret = xstats_id_abuse_tests(t);
3348 if (ret != 0) {
3349 printf("ERROR - XStats ID Abuse test FAILED.\n");
3350 goto test_fail;
3351 }
3352 printf("*** Running QID Priority test...\n");
3353 ret = qid_priorities(t);
3354 if (ret != 0) {
3355 printf("ERROR - QID Priority test FAILED.\n");
3356 goto test_fail;
3357 }
3358 printf("*** Running Unlink-in-progress test...\n");
3359 ret = unlink_in_progress(t);
3360 if (ret != 0) {
3361 printf("ERROR - Unlink in progress test FAILED.\n");
3362 goto test_fail;
3363 }
3364 printf("*** Running Ordered Reconfigure test...\n");
3365 ret = ordered_reconfigure(t);
3366 if (ret != 0) {
3367 printf("ERROR - Ordered Reconfigure test FAILED.\n");
3368 goto test_fail;
3369 }
3370 printf("*** Running Port LB Single Reconfig test...\n");
3371 ret = port_single_lb_reconfig(t);
3372 if (ret != 0) {
3373 printf("ERROR - Port LB Single Reconfig test FAILED.\n");
3374 goto test_fail;
3375 }
3376 printf("*** Running Port Reconfig Credits test...\n");
3377 ret = port_reconfig_credits(t);
3378 if (ret != 0) {
3379 printf("ERROR - Port Reconfig Credits Reset test FAILED.\n");
3380 goto test_fail;
3381 }
3382 printf("*** Running Head-of-line-blocking test...\n");
3383 ret = holb(t);
3384 if (ret != 0) {
3385 printf("ERROR - Head-of-line-blocking test FAILED.\n");
3386 goto test_fail;
3387 }
3388 printf("*** Running Stop Flush test...\n");
3389 ret = dev_stop_flush(t);
3390 if (ret != 0) {
3391 printf("ERROR - Stop Flush test FAILED.\n");
3392 goto test_fail;
3393 }
3394 if (rte_lcore_count() >= 3) {
3395 printf("*** Running Worker loopback test...\n");
3396 ret = worker_loopback(t, 0);
3397 if (ret != 0) {
3398 printf("ERROR - Worker loopback test FAILED.\n");
3399 return ret;
3400 }
3401
3402 printf("*** Running Worker loopback test (implicit release disabled)...\n");
3403 ret = worker_loopback(t, 1);
3404 if (ret != 0) {
3405 printf("ERROR - Worker loopback test FAILED.\n");
3406 goto test_fail;
3407 }
3408 } else {
3409 printf("### Not enough cores for worker loopback tests.\n");
3410 printf("### Need at least 3 cores for the tests.\n");
3411 }
3412
3413
3414
3415
3416
3417 free(t);
3418
3419 printf("SW Eventdev Selftest Successful.\n");
3420 return 0;
3421test_fail:
3422 free(t);
3423 printf("SW Eventdev Selftest Failed.\n");
3424 return -1;
3425}
3426