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 != 6) {
877 printf("%d: expected 6 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 != 6) {
884 printf("%d: expected 6 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};
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};
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 6
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 };
1508 uint64_t dev_expected[] = {NPKTS, NPKTS, 0, 1, 0, 0};
1509 for (i = 0; (int)i < ret; i++) {
1510 unsigned int id;
1511 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1512 dev_names[i],
1513 &id);
1514 if (id != i) {
1515 printf("%d: %s id incorrect, expected %d got %d\n",
1516 __LINE__, dev_names[i], i, id);
1517 goto fail;
1518 }
1519 if (val != dev_expected[i]) {
1520 printf("%d: %s value incorrect, expected %"
1521 PRIu64" got %d\n", __LINE__, dev_names[i],
1522 dev_expected[i], id);
1523 goto fail;
1524 }
1525
1526 int reset_ret = rte_event_dev_xstats_reset(evdev,
1527 RTE_EVENT_DEV_XSTATS_DEVICE, 0,
1528 &id,
1529 1);
1530 if (reset_ret) {
1531 printf("%d: failed to reset successfully\n", __LINE__);
1532 goto fail;
1533 }
1534 dev_expected[i] = 0;
1535
1536 val = rte_event_dev_xstats_by_name_get(evdev, dev_names[i], 0);
1537 if (val != dev_expected[i]) {
1538 printf("%d: %s value incorrect, expected %"PRIu64
1539 " got %"PRIu64"\n", __LINE__, dev_names[i],
1540 dev_expected[i], val);
1541 goto fail;
1542 }
1543 };
1544
1545
1546
1547
1548
1549#define PORT_OFF 48
1550
1551#define NUM_PORT_STATS 21
1552
1553#define PORT 2
1554 num_stats = rte_event_dev_xstats_names_get(evdev,
1555 RTE_EVENT_DEV_XSTATS_PORT, PORT,
1556 xstats_names, ids, XSTATS_MAX);
1557 if (num_stats != NUM_PORT_STATS) {
1558 printf("%d: expected %d stats, got return %d\n",
1559 __LINE__, NUM_PORT_STATS, num_stats);
1560 goto fail;
1561 }
1562 ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_PORT, PORT,
1563 ids, values, num_stats);
1564
1565 if (ret != NUM_PORT_STATS) {
1566 printf("%d: expected %d stats, got return %d\n",
1567 __LINE__, NUM_PORT_STATS, ret);
1568 goto fail;
1569 }
1570 static const char * const port_names[] = {
1571 "port_2_rx",
1572 "port_2_tx",
1573 "port_2_drop",
1574 "port_2_inflight",
1575 "port_2_avg_pkt_cycles",
1576 "port_2_credits",
1577 "port_2_rx_ring_used",
1578 "port_2_rx_ring_free",
1579 "port_2_cq_ring_used",
1580 "port_2_cq_ring_free",
1581 "port_2_dequeue_calls",
1582 "port_2_dequeues_returning_0",
1583 "port_2_dequeues_returning_1-4",
1584 "port_2_dequeues_returning_5-8",
1585 "port_2_dequeues_returning_9-12",
1586 "port_2_dequeues_returning_13-16",
1587 "port_2_dequeues_returning_17-20",
1588 "port_2_dequeues_returning_21-24",
1589 "port_2_dequeues_returning_25-28",
1590 "port_2_dequeues_returning_29-32",
1591 "port_2_dequeues_returning_33-36",
1592 };
1593 uint64_t port_expected[] = {
1594 0,
1595 NPKTS,
1596 0,
1597 NPKTS,
1598 0,
1599 0,
1600 0,
1601 4096,
1602 NPKTS,
1603 25,
1604 0,
1605 0, 0, 0, 0, 0,
1606 0, 0, 0, 0, 0,
1607 };
1608 uint64_t port_expected_zero[] = {
1609 0,
1610 0,
1611 0,
1612 NPKTS,
1613 0,
1614 0,
1615 0,
1616 4096,
1617 NPKTS,
1618 25,
1619 0,
1620 0, 0, 0, 0, 0,
1621 0, 0, 0, 0, 0,
1622 };
1623 if (RTE_DIM(port_expected) != NUM_PORT_STATS ||
1624 RTE_DIM(port_names) != NUM_PORT_STATS) {
1625 printf("%d: port array of wrong size\n", __LINE__);
1626 goto fail;
1627 }
1628
1629 int failed = 0;
1630 for (i = 0; (int)i < ret; i++) {
1631 unsigned int id;
1632 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1633 port_names[i],
1634 &id);
1635 if (id != i + PORT_OFF) {
1636 printf("%d: %s id incorrect, expected %d got %d\n",
1637 __LINE__, port_names[i], i+PORT_OFF,
1638 id);
1639 failed = 1;
1640 }
1641 if (val != port_expected[i]) {
1642 printf("%d: %s value incorrect, expected %"PRIu64
1643 " got %d\n", __LINE__, port_names[i],
1644 port_expected[i], id);
1645 failed = 1;
1646 }
1647
1648 int reset_ret = rte_event_dev_xstats_reset(evdev,
1649 RTE_EVENT_DEV_XSTATS_PORT, PORT,
1650 &id,
1651 1);
1652 if (reset_ret) {
1653 printf("%d: failed to reset successfully\n", __LINE__);
1654 failed = 1;
1655 }
1656
1657 val = rte_event_dev_xstats_by_name_get(evdev, port_names[i], 0);
1658 if (val != port_expected_zero[i]) {
1659 printf("%d: %s value incorrect, expected %"PRIu64
1660 " got %"PRIu64"\n", __LINE__, port_names[i],
1661 port_expected_zero[i], val);
1662 failed = 1;
1663 }
1664 };
1665 if (failed)
1666 goto fail;
1667
1668
1669#define NUM_Q_STATS 16
1670
1671
1672
1673#define QUEUE_OFF 90
1674 const uint32_t queue = 0;
1675 num_stats = rte_event_dev_xstats_names_get(evdev,
1676 RTE_EVENT_DEV_XSTATS_QUEUE, queue,
1677 xstats_names, ids, XSTATS_MAX);
1678 if (num_stats != NUM_Q_STATS) {
1679 printf("%d: expected %d stats, got return %d\n",
1680 __LINE__, NUM_Q_STATS, num_stats);
1681 goto fail;
1682 }
1683 ret = rte_event_dev_xstats_get(evdev, RTE_EVENT_DEV_XSTATS_QUEUE,
1684 queue, ids, values, num_stats);
1685 if (ret != NUM_Q_STATS) {
1686 printf("%d: expected 21 stats, got return %d\n", __LINE__, ret);
1687 goto fail;
1688 }
1689 static const char * const queue_names[] = {
1690 "qid_0_rx",
1691 "qid_0_tx",
1692 "qid_0_drop",
1693 "qid_0_inflight",
1694 "qid_0_iq_0_used",
1695 "qid_0_iq_1_used",
1696 "qid_0_iq_2_used",
1697 "qid_0_iq_3_used",
1698 "qid_0_port_0_pinned_flows",
1699 "qid_0_port_0_packets",
1700 "qid_0_port_1_pinned_flows",
1701 "qid_0_port_1_packets",
1702 "qid_0_port_2_pinned_flows",
1703 "qid_0_port_2_packets",
1704 "qid_0_port_3_pinned_flows",
1705 "qid_0_port_3_packets",
1706 };
1707 uint64_t queue_expected[] = {
1708 7,
1709 7,
1710 0,
1711 7,
1712 0,
1713 0,
1714 0,
1715 0,
1716
1717 0, 0,
1718 0, 0,
1719 1, 7,
1720 0, 0,
1721 };
1722 uint64_t queue_expected_zero[] = {
1723 0,
1724 0,
1725 0,
1726 7,
1727 0,
1728 0,
1729 0,
1730 0,
1731
1732 0, 0,
1733 0, 0,
1734 1, 0,
1735 0, 0,
1736 };
1737 if (RTE_DIM(queue_expected) != NUM_Q_STATS ||
1738 RTE_DIM(queue_expected_zero) != NUM_Q_STATS ||
1739 RTE_DIM(queue_names) != NUM_Q_STATS) {
1740 printf("%d : queue array of wrong size\n", __LINE__);
1741 goto fail;
1742 }
1743
1744 failed = 0;
1745 for (i = 0; (int)i < ret; i++) {
1746 unsigned int id;
1747 uint64_t val = rte_event_dev_xstats_by_name_get(evdev,
1748 queue_names[i],
1749 &id);
1750 if (id != i + QUEUE_OFF) {
1751 printf("%d: %s id incorrect, expected %d got %d\n",
1752 __LINE__, queue_names[i], i+QUEUE_OFF,
1753 id);
1754 failed = 1;
1755 }
1756 if (val != queue_expected[i]) {
1757 printf("%d: %d: %s value , expected %"PRIu64
1758 " got %"PRIu64"\n", i, __LINE__,
1759 queue_names[i], queue_expected[i], val);
1760 failed = 1;
1761 }
1762
1763 int reset_ret = rte_event_dev_xstats_reset(evdev,
1764 RTE_EVENT_DEV_XSTATS_QUEUE,
1765 queue, &id, 1);
1766 if (reset_ret) {
1767 printf("%d: failed to reset successfully\n", __LINE__);
1768 failed = 1;
1769 }
1770
1771 val = rte_event_dev_xstats_by_name_get(evdev, queue_names[i],
1772 0);
1773 if (val != queue_expected_zero[i]) {
1774 printf("%d: %s value incorrect, expected %"PRIu64
1775 " got %"PRIu64"\n", __LINE__, queue_names[i],
1776 queue_expected_zero[i], val);
1777 failed = 1;
1778 }
1779 };
1780
1781 if (failed)
1782 goto fail;
1783
1784 cleanup(t);
1785 return 0;
1786fail:
1787 cleanup(t);
1788 return -1;
1789}
1790
1791static int
1792ordered_reconfigure(struct test *t)
1793{
1794 if (init(t, 1, 1) < 0 ||
1795 create_ports(t, 1) < 0) {
1796 printf("%d: Error initializing device\n", __LINE__);
1797 return -1;
1798 }
1799
1800 const struct rte_event_queue_conf conf = {
1801 .schedule_type = RTE_SCHED_TYPE_ORDERED,
1802 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
1803 .nb_atomic_flows = 1024,
1804 .nb_atomic_order_sequences = 1024,
1805 };
1806
1807 if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1808 printf("%d: error creating qid\n", __LINE__);
1809 goto failed;
1810 }
1811
1812 if (rte_event_queue_setup(evdev, 0, &conf) < 0) {
1813 printf("%d: error creating qid, for 2nd time\n", __LINE__);
1814 goto failed;
1815 }
1816
1817 rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1818 if (rte_event_dev_start(evdev) < 0) {
1819 printf("%d: Error with start call\n", __LINE__);
1820 return -1;
1821 }
1822
1823 cleanup(t);
1824 return 0;
1825failed:
1826 cleanup(t);
1827 return -1;
1828}
1829
1830static int
1831qid_priorities(struct test *t)
1832{
1833
1834
1835
1836
1837 unsigned int i;
1838
1839 if (init(t, 3, 1) < 0 ||
1840 create_ports(t, 1) < 0) {
1841 printf("%d: Error initializing device\n", __LINE__);
1842 return -1;
1843 }
1844
1845 for (i = 0; i < 3; i++) {
1846
1847 const struct rte_event_queue_conf conf = {
1848 .schedule_type = RTE_SCHED_TYPE_ATOMIC,
1849
1850 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL - i,
1851 .nb_atomic_flows = 1024,
1852 .nb_atomic_order_sequences = 1024,
1853 };
1854
1855 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
1856 printf("%d: error creating qid %d\n", __LINE__, i);
1857 return -1;
1858 }
1859 t->qid[i] = i;
1860 }
1861 t->nb_qids = i;
1862
1863 rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1864
1865 if (rte_event_dev_start(evdev) < 0) {
1866 printf("%d: Error with start call\n", __LINE__);
1867 return -1;
1868 }
1869
1870
1871 for (i = 0; i < 3; i++) {
1872 struct rte_event ev;
1873 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
1874 if (!arp) {
1875 printf("%d: gen of pkt failed\n", __LINE__);
1876 return -1;
1877 }
1878 ev.queue_id = t->qid[i];
1879 ev.op = RTE_EVENT_OP_NEW;
1880 ev.mbuf = arp;
1881 *rte_event_pmd_selftest_seqn(arp) = i;
1882
1883 int err = rte_event_enqueue_burst(evdev, t->port[0], &ev, 1);
1884 if (err != 1) {
1885 printf("%d: Failed to enqueue\n", __LINE__);
1886 return -1;
1887 }
1888 }
1889
1890 rte_service_run_iter_on_app_lcore(t->service_id, 1);
1891
1892
1893 struct rte_event ev[32];
1894 uint32_t deq_pkts =
1895 rte_event_dequeue_burst(evdev, t->port[0], ev, 32, 0);
1896 if (deq_pkts != 3) {
1897 printf("%d: failed to deq packets\n", __LINE__);
1898 rte_event_dev_dump(evdev, stdout);
1899 return -1;
1900 }
1901 for (i = 0; i < 3; i++) {
1902 if (*rte_event_pmd_selftest_seqn(ev[i].mbuf) != 2-i) {
1903 printf(
1904 "%d: qid priority test: seqn %d incorrectly prioritized\n",
1905 __LINE__, i);
1906 }
1907 }
1908
1909 cleanup(t);
1910 return 0;
1911}
1912
1913static int
1914unlink_in_progress(struct test *t)
1915{
1916
1917
1918
1919
1920 unsigned int i;
1921
1922 if (init(t, 3, 1) < 0 ||
1923 create_ports(t, 1) < 0) {
1924 printf("%d: Error initializing device\n", __LINE__);
1925 return -1;
1926 }
1927
1928 for (i = 0; i < 3; i++) {
1929
1930 const struct rte_event_queue_conf conf = {
1931 .schedule_type = RTE_SCHED_TYPE_ATOMIC,
1932
1933 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL - i,
1934 .nb_atomic_flows = 1024,
1935 .nb_atomic_order_sequences = 1024,
1936 };
1937
1938 if (rte_event_queue_setup(evdev, i, &conf) < 0) {
1939 printf("%d: error creating qid %d\n", __LINE__, i);
1940 return -1;
1941 }
1942 t->qid[i] = i;
1943 }
1944 t->nb_qids = i;
1945
1946 rte_event_port_link(evdev, t->port[0], NULL, NULL, 0);
1947
1948 if (rte_event_dev_start(evdev) < 0) {
1949 printf("%d: Error with start call\n", __LINE__);
1950 return -1;
1951 }
1952
1953
1954 int ret = rte_event_port_unlink(evdev, t->port[0], NULL, 0);
1955 if (ret < 0) {
1956 printf("%d: Failed to unlink queues\n", __LINE__);
1957 return -1;
1958 }
1959
1960
1961 int unlinks_in_progress =
1962 rte_event_port_unlinks_in_progress(evdev, t->port[0]);
1963 if (unlinks_in_progress != 3) {
1964 printf("%d: Expected num unlinks in progress == 3, got %d\n",
1965 __LINE__, unlinks_in_progress);
1966 return -1;
1967 }
1968
1969
1970 rte_service_run_iter_on_app_lcore(t->service_id, 1);
1971
1972
1973 unlinks_in_progress =
1974 rte_event_port_unlinks_in_progress(evdev, t->port[0]);
1975 if (unlinks_in_progress != 0) {
1976 printf("%d: Expected num unlinks in progress == 0, got %d\n",
1977 __LINE__, unlinks_in_progress);
1978 }
1979
1980 cleanup(t);
1981 return 0;
1982}
1983
1984static int
1985load_balancing(struct test *t)
1986{
1987 const int rx_enq = 0;
1988 int err;
1989 uint32_t i;
1990
1991 if (init(t, 1, 4) < 0 ||
1992 create_ports(t, 4) < 0 ||
1993 create_atomic_qids(t, 1) < 0) {
1994 printf("%d: Error initializing device\n", __LINE__);
1995 return -1;
1996 }
1997
1998 for (i = 0; i < 3; i++) {
1999
2000 if (rte_event_port_link(evdev, t->port[i+1], &t->qid[0],
2001 NULL, 1) != 1) {
2002 printf("%d: error mapping qid to port %d\n",
2003 __LINE__, i);
2004 return -1;
2005 }
2006 }
2007
2008 if (rte_event_dev_start(evdev) < 0) {
2009 printf("%d: Error with start call\n", __LINE__);
2010 return -1;
2011 }
2012
2013
2014
2015
2016
2017
2018
2019 static uint32_t flows[] = {0, 1, 1, 0, 0, 2, 2, 0, 2};
2020
2021 for (i = 0; i < RTE_DIM(flows); i++) {
2022 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2023 if (!arp) {
2024 printf("%d: gen of pkt failed\n", __LINE__);
2025 return -1;
2026 }
2027
2028 struct rte_event ev = {
2029 .op = RTE_EVENT_OP_NEW,
2030 .queue_id = t->qid[0],
2031 .flow_id = flows[i],
2032 .mbuf = arp,
2033 };
2034
2035 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2036 if (err != 1) {
2037 printf("%d: Failed to enqueue\n", __LINE__);
2038 return -1;
2039 }
2040 }
2041
2042 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2043
2044 struct test_event_dev_stats stats;
2045 err = test_event_dev_stats_get(evdev, &stats);
2046 if (err) {
2047 printf("%d: failed to get stats\n", __LINE__);
2048 return -1;
2049 }
2050
2051 if (stats.port_inflight[1] != 4) {
2052 printf("%d:%s: port 1 inflight not correct\n", __LINE__,
2053 __func__);
2054 return -1;
2055 }
2056 if (stats.port_inflight[2] != 2) {
2057 printf("%d:%s: port 2 inflight not correct\n", __LINE__,
2058 __func__);
2059 return -1;
2060 }
2061 if (stats.port_inflight[3] != 3) {
2062 printf("%d:%s: port 3 inflight not correct\n", __LINE__,
2063 __func__);
2064 return -1;
2065 }
2066
2067 cleanup(t);
2068 return 0;
2069}
2070
2071static int
2072load_balancing_history(struct test *t)
2073{
2074 struct test_event_dev_stats stats = {0};
2075 const int rx_enq = 0;
2076 int err;
2077 uint32_t i;
2078
2079
2080 if (init(t, 1, 4) < 0 ||
2081 create_ports(t, 4) < 0 ||
2082 create_atomic_qids(t, 1) < 0)
2083 return -1;
2084
2085
2086 if (rte_event_port_link(evdev, t->port[1], &t->qid[0], NULL, 1) != 1) {
2087 printf("%d: error mapping port 1 qid\n", __LINE__);
2088 return -1;
2089 }
2090 if (rte_event_port_link(evdev, t->port[2], &t->qid[0], NULL, 1) != 1) {
2091 printf("%d: error mapping port 2 qid\n", __LINE__);
2092 return -1;
2093 }
2094 if (rte_event_port_link(evdev, t->port[3], &t->qid[0], NULL, 1) != 1) {
2095 printf("%d: error mapping port 3 qid\n", __LINE__);
2096 return -1;
2097 }
2098 if (rte_event_dev_start(evdev) < 0) {
2099 printf("%d: Error with start call\n", __LINE__);
2100 return -1;
2101 }
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116 static uint32_t flows1[] = {0, 1, 1, 2};
2117
2118 for (i = 0; i < RTE_DIM(flows1); i++) {
2119 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2120 struct rte_event ev = {
2121 .flow_id = flows1[i],
2122 .op = RTE_EVENT_OP_NEW,
2123 .queue_id = t->qid[0],
2124 .event_type = RTE_EVENT_TYPE_CPU,
2125 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
2126 .mbuf = arp
2127 };
2128
2129 if (!arp) {
2130 printf("%d: gen of pkt failed\n", __LINE__);
2131 return -1;
2132 }
2133 arp->hash.rss = flows1[i];
2134 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2135 if (err != 1) {
2136 printf("%d: Failed to enqueue\n", __LINE__);
2137 return -1;
2138 }
2139 }
2140
2141
2142 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2143
2144
2145 struct rte_event ev;
2146 if (!rte_event_dequeue_burst(evdev, t->port[1], &ev, 1, 0)) {
2147 printf("%d: failed to dequeue\n", __LINE__);
2148 return -1;
2149 }
2150 if (ev.mbuf->hash.rss != flows1[0]) {
2151 printf("%d: unexpected flow received\n", __LINE__);
2152 return -1;
2153 }
2154
2155
2156 rte_event_enqueue_burst(evdev, t->port[1], &release_ev, 1);
2157
2158
2159 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2160
2161
2162
2163
2164
2165 static uint32_t flows2[] = { 3, 3, 3, 1, 1, 0 };
2166
2167 for (i = 0; i < RTE_DIM(flows2); i++) {
2168 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2169 struct rte_event ev = {
2170 .flow_id = flows2[i],
2171 .op = RTE_EVENT_OP_NEW,
2172 .queue_id = t->qid[0],
2173 .event_type = RTE_EVENT_TYPE_CPU,
2174 .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
2175 .mbuf = arp
2176 };
2177
2178 if (!arp) {
2179 printf("%d: gen of pkt failed\n", __LINE__);
2180 return -1;
2181 }
2182 arp->hash.rss = flows2[i];
2183
2184 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2185 if (err != 1) {
2186 printf("%d: Failed to enqueue\n", __LINE__);
2187 return -1;
2188 }
2189 }
2190
2191
2192 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2193
2194 err = test_event_dev_stats_get(evdev, &stats);
2195 if (err) {
2196 printf("%d:failed to get stats\n", __LINE__);
2197 return -1;
2198 }
2199
2200
2201
2202
2203 if (stats.port_inflight[1] != 3) {
2204 printf("%d:%s: port 1 inflight not correct\n", __LINE__,
2205 __func__);
2206 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2207 (unsigned int)stats.port_inflight[1],
2208 (unsigned int)stats.port_inflight[2],
2209 (unsigned int)stats.port_inflight[3]);
2210 return -1;
2211 }
2212 if (stats.port_inflight[2] != 4) {
2213 printf("%d:%s: port 2 inflight not correct\n", __LINE__,
2214 __func__);
2215 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2216 (unsigned int)stats.port_inflight[1],
2217 (unsigned int)stats.port_inflight[2],
2218 (unsigned int)stats.port_inflight[3]);
2219 return -1;
2220 }
2221 if (stats.port_inflight[3] != 2) {
2222 printf("%d:%s: port 3 inflight not correct\n", __LINE__,
2223 __func__);
2224 printf("Inflights, ports 1, 2, 3: %u, %u, %u\n",
2225 (unsigned int)stats.port_inflight[1],
2226 (unsigned int)stats.port_inflight[2],
2227 (unsigned int)stats.port_inflight[3]);
2228 return -1;
2229 }
2230
2231 for (i = 1; i <= 3; i++) {
2232 struct rte_event ev;
2233 while (rte_event_dequeue_burst(evdev, i, &ev, 1, 0))
2234 rte_event_enqueue_burst(evdev, i, &release_ev, 1);
2235 }
2236 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2237
2238 cleanup(t);
2239 return 0;
2240}
2241
2242static int
2243invalid_qid(struct test *t)
2244{
2245 struct test_event_dev_stats stats;
2246 const int rx_enq = 0;
2247 int err;
2248 uint32_t i;
2249
2250 if (init(t, 1, 4) < 0 ||
2251 create_ports(t, 4) < 0 ||
2252 create_atomic_qids(t, 1) < 0) {
2253 printf("%d: Error initializing device\n", __LINE__);
2254 return -1;
2255 }
2256
2257
2258 for (i = 0; i < 4; i++) {
2259 err = rte_event_port_link(evdev, t->port[i], &t->qid[0],
2260 NULL, 1);
2261 if (err != 1) {
2262 printf("%d: error mapping port 1 qid\n", __LINE__);
2263 return -1;
2264 }
2265 }
2266
2267 if (rte_event_dev_start(evdev) < 0) {
2268 printf("%d: Error with start call\n", __LINE__);
2269 return -1;
2270 }
2271
2272
2273
2274
2275
2276
2277
2278 static uint32_t flows1[] = {20};
2279
2280 for (i = 0; i < RTE_DIM(flows1); i++) {
2281 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2282 if (!arp) {
2283 printf("%d: gen of pkt failed\n", __LINE__);
2284 return -1;
2285 }
2286
2287 struct rte_event ev = {
2288 .op = RTE_EVENT_OP_NEW,
2289 .queue_id = t->qid[0] + flows1[i],
2290 .flow_id = i,
2291 .mbuf = arp,
2292 };
2293
2294 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2295 if (err != 1) {
2296 printf("%d: Failed to enqueue\n", __LINE__);
2297 return -1;
2298 }
2299 }
2300
2301
2302 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2303
2304 err = test_event_dev_stats_get(evdev, &stats);
2305 if (err) {
2306 printf("%d: failed to get stats\n", __LINE__);
2307 return -1;
2308 }
2309
2310
2311
2312
2313 if (stats.port_inflight[0] != 0) {
2314 printf("%d:%s: port 1 inflight count not correct\n", __LINE__,
2315 __func__);
2316 rte_event_dev_dump(evdev, stdout);
2317 return -1;
2318 }
2319 if (stats.port_rx_dropped[0] != 1) {
2320 printf("%d:%s: port 1 drops\n", __LINE__, __func__);
2321 rte_event_dev_dump(evdev, stdout);
2322 return -1;
2323 }
2324
2325 if (stats.rx_dropped != 0) {
2326 printf("%d:%s: port 1 dropped count not correct\n", __LINE__,
2327 __func__);
2328 rte_event_dev_dump(evdev, stdout);
2329 return -1;
2330 }
2331
2332 cleanup(t);
2333 return 0;
2334}
2335
2336static int
2337single_packet(struct test *t)
2338{
2339 const uint32_t MAGIC_SEQN = 7321;
2340 struct rte_event ev;
2341 struct test_event_dev_stats stats;
2342 const int rx_enq = 0;
2343 const int wrk_enq = 2;
2344 int err;
2345
2346
2347 if (init(t, 1, 4) < 0 ||
2348 create_ports(t, 4) < 0 ||
2349 create_atomic_qids(t, 1) < 0) {
2350 printf("%d: Error initializing device\n", __LINE__);
2351 return -1;
2352 }
2353
2354
2355 err = rte_event_port_link(evdev, t->port[wrk_enq], NULL, NULL, 0);
2356 if (err != 1) {
2357 printf("%d: error mapping lb qid\n", __LINE__);
2358 cleanup(t);
2359 return -1;
2360 }
2361
2362 if (rte_event_dev_start(evdev) < 0) {
2363 printf("%d: Error with start call\n", __LINE__);
2364 return -1;
2365 }
2366
2367
2368 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2369 if (!arp) {
2370 printf("%d: gen of pkt failed\n", __LINE__);
2371 return -1;
2372 }
2373
2374 ev.op = RTE_EVENT_OP_NEW;
2375 ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
2376 ev.mbuf = arp;
2377 ev.queue_id = 0;
2378 ev.flow_id = 3;
2379 *rte_event_pmd_selftest_seqn(arp) = MAGIC_SEQN;
2380
2381 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2382 if (err != 1) {
2383 printf("%d: Failed to enqueue\n", __LINE__);
2384 return -1;
2385 }
2386
2387 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2388
2389 err = test_event_dev_stats_get(evdev, &stats);
2390 if (err) {
2391 printf("%d: failed to get stats\n", __LINE__);
2392 return -1;
2393 }
2394
2395 if (stats.rx_pkts != 1 ||
2396 stats.tx_pkts != 1 ||
2397 stats.port_inflight[wrk_enq] != 1) {
2398 printf("%d: Sched core didn't handle pkt as expected\n",
2399 __LINE__);
2400 rte_event_dev_dump(evdev, stdout);
2401 return -1;
2402 }
2403
2404 uint32_t deq_pkts;
2405
2406 deq_pkts = rte_event_dequeue_burst(evdev, t->port[wrk_enq], &ev, 1, 0);
2407 if (deq_pkts < 1) {
2408 printf("%d: Failed to deq\n", __LINE__);
2409 return -1;
2410 }
2411
2412 err = test_event_dev_stats_get(evdev, &stats);
2413 if (err) {
2414 printf("%d: failed to get stats\n", __LINE__);
2415 return -1;
2416 }
2417
2418 err = test_event_dev_stats_get(evdev, &stats);
2419 if (*rte_event_pmd_selftest_seqn(ev.mbuf) != MAGIC_SEQN) {
2420 printf("%d: magic sequence number not dequeued\n", __LINE__);
2421 return -1;
2422 }
2423
2424 rte_pktmbuf_free(ev.mbuf);
2425 err = rte_event_enqueue_burst(evdev, t->port[wrk_enq], &release_ev, 1);
2426 if (err != 1) {
2427 printf("%d: Failed to enqueue\n", __LINE__);
2428 return -1;
2429 }
2430 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2431
2432 err = test_event_dev_stats_get(evdev, &stats);
2433 if (stats.port_inflight[wrk_enq] != 0) {
2434 printf("%d: port inflight not correct\n", __LINE__);
2435 return -1;
2436 }
2437
2438 cleanup(t);
2439 return 0;
2440}
2441
2442static int
2443inflight_counts(struct test *t)
2444{
2445 struct rte_event ev;
2446 struct test_event_dev_stats stats;
2447 const int rx_enq = 0;
2448 const int p1 = 1;
2449 const int p2 = 2;
2450 int err;
2451 int i;
2452
2453
2454 if (init(t, 2, 3) < 0 ||
2455 create_ports(t, 3) < 0 ||
2456 create_atomic_qids(t, 2) < 0) {
2457 printf("%d: Error initializing device\n", __LINE__);
2458 return -1;
2459 }
2460
2461
2462 err = rte_event_port_link(evdev, t->port[p1], &t->qid[0], NULL, 1);
2463 if (err != 1) {
2464 printf("%d: error mapping lb qid\n", __LINE__);
2465 cleanup(t);
2466 return -1;
2467 }
2468 err = rte_event_port_link(evdev, t->port[p2], &t->qid[1], NULL, 1);
2469 if (err != 1) {
2470 printf("%d: error mapping lb qid\n", __LINE__);
2471 cleanup(t);
2472 return -1;
2473 }
2474
2475 if (rte_event_dev_start(evdev) < 0) {
2476 printf("%d: Error with start call\n", __LINE__);
2477 return -1;
2478 }
2479
2480
2481#define QID1_NUM 5
2482 for (i = 0; i < QID1_NUM; i++) {
2483 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2484
2485 if (!arp) {
2486 printf("%d: gen of pkt failed\n", __LINE__);
2487 goto err;
2488 }
2489
2490 ev.queue_id = t->qid[0];
2491 ev.op = RTE_EVENT_OP_NEW;
2492 ev.mbuf = arp;
2493 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2494 if (err != 1) {
2495 printf("%d: Failed to enqueue\n", __LINE__);
2496 goto err;
2497 }
2498 }
2499#define QID2_NUM 3
2500 for (i = 0; i < QID2_NUM; i++) {
2501 struct rte_mbuf *arp = rte_gen_arp(0, t->mbuf_pool);
2502
2503 if (!arp) {
2504 printf("%d: gen of pkt failed\n", __LINE__);
2505 goto err;
2506 }
2507 ev.queue_id = t->qid[1];
2508 ev.op = RTE_EVENT_OP_NEW;
2509 ev.mbuf = arp;
2510 err = rte_event_enqueue_burst(evdev, t->port[rx_enq], &ev, 1);
2511 if (err != 1) {
2512 printf("%d: Failed to enqueue\n", __LINE__);
2513 goto err;
2514 }
2515 }
2516
2517
2518 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2519
2520 err = test_event_dev_stats_get(evdev, &stats);
2521 if (err) {
2522 printf("%d: failed to get stats\n", __LINE__);
2523 goto err;
2524 }
2525
2526 if (stats.rx_pkts != QID1_NUM + QID2_NUM ||
2527 stats.tx_pkts != QID1_NUM + QID2_NUM) {
2528 printf("%d: Sched core didn't handle pkt as expected\n",
2529 __LINE__);
2530 goto err;
2531 }
2532
2533 if (stats.port_inflight[p1] != QID1_NUM) {
2534 printf("%d: %s port 1 inflight not correct\n", __LINE__,
2535 __func__);
2536 goto err;
2537 }
2538 if (stats.port_inflight[p2] != QID2_NUM) {
2539 printf("%d: %s port 2 inflight not correct\n", __LINE__,
2540 __func__);
2541 goto err;
2542 }
2543
2544
2545
2546 struct rte_event events[QID1_NUM + QID2_NUM];
2547 uint32_t deq_pkts = rte_event_dequeue_burst(evdev, t->port[p1], events,
2548 RTE_DIM(events), 0);
2549
2550 if (deq_pkts != QID1_NUM) {
2551 printf("%d: Port 1: DEQUEUE inflight failed\n", __LINE__);
2552 goto err;
2553 }
2554 err = test_event_dev_stats_get(evdev, &stats);
2555 if (stats.port_inflight[p1] != QID1_NUM) {
2556 printf("%d: port 1 inflight decrement after DEQ != 0\n",
2557 __LINE__);
2558 goto err;
2559 }
2560 for (i = 0; i < QID1_NUM; i++) {
2561 err = rte_event_enqueue_burst(evdev, t->port[p1], &release_ev,
2562 1);
2563 if (err != 1) {
2564 printf("%d: %s rte enqueue of inf release failed\n",
2565 __LINE__, __func__);
2566 goto err;
2567 }
2568 }
2569
2570
2571
2572
2573
2574 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2575
2576 err = test_event_dev_stats_get(evdev, &stats);
2577 if (stats.port_inflight[p1] != 0) {
2578 printf("%d: port 1 inflight NON NULL after DROP\n", __LINE__);
2579 goto err;
2580 }
2581
2582
2583 deq_pkts = rte_event_dequeue_burst(evdev, t->port[p2], events,
2584 RTE_DIM(events), 0);
2585 if (deq_pkts != QID2_NUM) {
2586 printf("%d: Port 2: DEQUEUE inflight failed\n", __LINE__);
2587 goto err;
2588 }
2589 err = test_event_dev_stats_get(evdev, &stats);
2590 if (stats.port_inflight[p2] != QID2_NUM) {
2591 printf("%d: port 1 inflight decrement after DEQ != 0\n",
2592 __LINE__);
2593 goto err;
2594 }
2595 for (i = 0; i < QID2_NUM; i++) {
2596 err = rte_event_enqueue_burst(evdev, t->port[p2], &release_ev,
2597 1);
2598 if (err != 1) {
2599 printf("%d: %s rte enqueue of inf release failed\n",
2600 __LINE__, __func__);
2601 goto err;
2602 }
2603 }
2604
2605
2606
2607
2608
2609 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2610
2611 err = test_event_dev_stats_get(evdev, &stats);
2612 if (stats.port_inflight[p2] != 0) {
2613 printf("%d: port 2 inflight NON NULL after DROP\n", __LINE__);
2614 goto err;
2615 }
2616 cleanup(t);
2617 return 0;
2618
2619err:
2620 rte_event_dev_dump(evdev, stdout);
2621 cleanup(t);
2622 return -1;
2623}
2624
2625static int
2626parallel_basic(struct test *t, int check_order)
2627{
2628 const uint8_t rx_port = 0;
2629 const uint8_t w1_port = 1;
2630 const uint8_t w3_port = 3;
2631 const uint8_t tx_port = 4;
2632 int err;
2633 int i;
2634 uint32_t deq_pkts, j;
2635 struct rte_mbuf *mbufs[3];
2636 struct rte_mbuf *mbufs_out[3] = { 0 };
2637 const uint32_t MAGIC_SEQN = 1234;
2638
2639
2640 if (init(t, 2, tx_port + 1) < 0 ||
2641 create_ports(t, tx_port + 1) < 0 ||
2642 (check_order ? create_ordered_qids(t, 1) :
2643 create_unordered_qids(t, 1)) < 0 ||
2644 create_directed_qids(t, 1, &tx_port)) {
2645 printf("%d: Error initializing device\n", __LINE__);
2646 return -1;
2647 }
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665 for (i = w1_port; i <= w3_port; i++) {
2666 err = rte_event_port_link(evdev, t->port[i], &t->qid[0], NULL,
2667 1);
2668 if (err != 1) {
2669 printf("%d: error mapping lb qid\n", __LINE__);
2670 cleanup(t);
2671 return -1;
2672 }
2673 }
2674
2675 if (rte_event_dev_start(evdev) < 0) {
2676 printf("%d: Error with start call\n", __LINE__);
2677 return -1;
2678 }
2679
2680
2681 for (i = 0; i < 3; i++) {
2682 struct rte_event ev;
2683 mbufs[i] = rte_gen_arp(0, t->mbuf_pool);
2684 if (!mbufs[i]) {
2685 printf("%d: gen of pkt failed\n", __LINE__);
2686 return -1;
2687 }
2688
2689 ev.queue_id = t->qid[0];
2690 ev.op = RTE_EVENT_OP_NEW;
2691 ev.mbuf = mbufs[i];
2692 *rte_event_pmd_selftest_seqn(mbufs[i]) = MAGIC_SEQN + i;
2693
2694
2695 err = rte_event_enqueue_burst(evdev, t->port[rx_port], &ev, 1);
2696 if (err != 1) {
2697 printf("%d: Failed to enqueue pkt %u, retval = %u\n",
2698 __LINE__, i, err);
2699 return -1;
2700 }
2701 }
2702
2703 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2704
2705
2706 struct rte_event deq_ev[w3_port + 1];
2707
2708
2709 for (i = w1_port; i <= w3_port; i++) {
2710 deq_pkts = rte_event_dequeue_burst(evdev, t->port[i],
2711 &deq_ev[i], 1, 0);
2712 if (deq_pkts != 1) {
2713 printf("%d: Failed to deq\n", __LINE__);
2714 rte_event_dev_dump(evdev, stdout);
2715 return -1;
2716 }
2717 }
2718
2719
2720 for (i = w3_port; i >= w1_port; i--) {
2721
2722 deq_ev[i].op = RTE_EVENT_OP_FORWARD;
2723 deq_ev[i].queue_id = t->qid[1];
2724 err = rte_event_enqueue_burst(evdev, t->port[i], &deq_ev[i], 1);
2725 if (err != 1) {
2726 printf("%d: Failed to enqueue\n", __LINE__);
2727 return -1;
2728 }
2729 }
2730 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2731
2732
2733 deq_pkts = rte_event_dequeue_burst(evdev, t->port[tx_port], deq_ev,
2734 3, 0);
2735
2736
2737 if (deq_pkts != 3) {
2738 printf("%d: expected 3 pkts at tx port got %d from port %d\n",
2739 __LINE__, deq_pkts, tx_port);
2740 rte_event_dev_dump(evdev, stdout);
2741 return 1;
2742 }
2743
2744
2745 if (check_order) {
2746 for (j = 0 ; j < deq_pkts ; j++) {
2747 if (*rte_event_pmd_selftest_seqn(deq_ev[j].mbuf) !=
2748 MAGIC_SEQN + j) {
2749 printf("%d: Incorrect sequence number(%d) from port %d\n",
2750 __LINE__,
2751 *rte_event_pmd_selftest_seqn(mbufs_out[j]),
2752 tx_port);
2753 return -1;
2754 }
2755 }
2756 }
2757
2758
2759 cleanup(t);
2760 return 0;
2761}
2762
2763static int
2764ordered_basic(struct test *t)
2765{
2766 return parallel_basic(t, 1);
2767}
2768
2769static int
2770unordered_basic(struct test *t)
2771{
2772 return parallel_basic(t, 0);
2773}
2774
2775static int
2776holb(struct test *t)
2777{
2778 const struct rte_event new_ev = {
2779 .op = RTE_EVENT_OP_NEW
2780
2781 };
2782 struct rte_event ev = new_ev;
2783 unsigned int rx_port = 0;
2784 char rx_port_used_stat[64];
2785 char rx_port_free_stat[64];
2786 char other_port_used_stat[64];
2787
2788 if (init(t, 1, 2) < 0 ||
2789 create_ports(t, 2) < 0 ||
2790 create_atomic_qids(t, 1) < 0) {
2791 printf("%d: Error initializing device\n", __LINE__);
2792 return -1;
2793 }
2794 int nb_links = rte_event_port_link(evdev, t->port[1], NULL, NULL, 0);
2795 if (rte_event_port_link(evdev, t->port[0], NULL, NULL, 0) != 1 ||
2796 nb_links != 1) {
2797 printf("%d: Error links queue to ports\n", __LINE__);
2798 goto err;
2799 }
2800 if (rte_event_dev_start(evdev) < 0) {
2801 printf("%d: Error with start call\n", __LINE__);
2802 goto err;
2803 }
2804
2805
2806 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2807 printf("%d: Error doing first enqueue\n", __LINE__);
2808 goto err;
2809 }
2810 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2811
2812 if (rte_event_dev_xstats_by_name_get(evdev, "port_0_cq_ring_used", NULL)
2813 != 1)
2814 rx_port = 1;
2815
2816 snprintf(rx_port_used_stat, sizeof(rx_port_used_stat),
2817 "port_%u_cq_ring_used", rx_port);
2818 snprintf(rx_port_free_stat, sizeof(rx_port_free_stat),
2819 "port_%u_cq_ring_free", rx_port);
2820 snprintf(other_port_used_stat, sizeof(other_port_used_stat),
2821 "port_%u_cq_ring_used", rx_port ^ 1);
2822 if (rte_event_dev_xstats_by_name_get(evdev, rx_port_used_stat, NULL)
2823 != 1) {
2824 printf("%d: Error, first event not scheduled\n", __LINE__);
2825 goto err;
2826 }
2827
2828
2829 do {
2830 ev = new_ev;
2831 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2832 printf("%d: Error with enqueue\n", __LINE__);
2833 goto err;
2834 }
2835 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2836 } while (rte_event_dev_xstats_by_name_get(evdev,
2837 rx_port_free_stat, NULL) != 0);
2838
2839
2840 ev = new_ev;
2841 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2842 printf("%d: Error with enqueue\n", __LINE__);
2843 goto err;
2844 }
2845 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2846
2847
2848 if (rte_event_dev_xstats_by_name_get(evdev, other_port_used_stat, NULL)
2849 != 0) {
2850 printf("%d: Error, second port CQ is not empty\n", __LINE__);
2851 goto err;
2852 }
2853
2854 if (rte_event_dev_xstats_by_name_get(evdev, "qid_0_iq_0_used", NULL)
2855 != 1) {
2856 printf("%d: Error, QID does not have exactly 1 packet\n",
2857 __LINE__);
2858 goto err;
2859 }
2860
2861
2862 ev = new_ev;
2863 ev.flow_id = 1;
2864 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2865 printf("%d: Error with enqueue\n", __LINE__);
2866 goto err;
2867 }
2868 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2869
2870 if (rte_event_dev_xstats_by_name_get(evdev, other_port_used_stat, NULL)
2871 != 1) {
2872 printf("%d: Error, second flow did not pass out first\n",
2873 __LINE__);
2874 goto err;
2875 }
2876
2877 if (rte_event_dev_xstats_by_name_get(evdev, "qid_0_iq_0_used", NULL)
2878 != 1) {
2879 printf("%d: Error, QID does not have exactly 1 packet\n",
2880 __LINE__);
2881 goto err;
2882 }
2883 cleanup(t);
2884 return 0;
2885err:
2886 rte_event_dev_dump(evdev, stdout);
2887 cleanup(t);
2888 return -1;
2889}
2890
2891static void
2892flush(uint8_t dev_id __rte_unused, struct rte_event event, void *arg)
2893{
2894 *((uint8_t *) arg) += (event.u64 == 0xCA11BACC) ? 1 : 0;
2895}
2896
2897static int
2898dev_stop_flush(struct test *t)
2899{
2900 const struct rte_event new_ev = {
2901 .op = RTE_EVENT_OP_NEW,
2902 .u64 = 0xCA11BACC,
2903 .queue_id = 0
2904 };
2905 struct rte_event ev = new_ev;
2906 uint8_t count = 0;
2907 int i;
2908
2909 if (init(t, 1, 1) < 0 ||
2910 create_ports(t, 1) < 0 ||
2911 create_atomic_qids(t, 1) < 0) {
2912 printf("%d: Error initializing device\n", __LINE__);
2913 return -1;
2914 }
2915
2916
2917 if (rte_event_port_link(evdev, t->port[0], NULL, NULL, 0) != 1) {
2918 printf("%d: Error linking queue to port\n", __LINE__);
2919 goto err;
2920 }
2921
2922 if (rte_event_dev_start(evdev) < 0) {
2923 printf("%d: Error with start call\n", __LINE__);
2924 goto err;
2925 }
2926
2927 for (i = 0; i < DEQUEUE_DEPTH + 1; i++) {
2928 if (rte_event_enqueue_burst(evdev, t->port[0], &ev, 1) != 1) {
2929 printf("%d: Error enqueuing events\n", __LINE__);
2930 goto err;
2931 }
2932 }
2933
2934
2935
2936
2937 rte_service_run_iter_on_app_lcore(t->service_id, 1);
2938
2939 if (rte_event_dev_stop_flush_callback_register(evdev, flush, &count)) {
2940 printf("%d: Error installing the flush callback\n", __LINE__);
2941 goto err;
2942 }
2943
2944 cleanup(t);
2945
2946 if (count == 0) {
2947 printf("%d: Error executing the flush callback\n", __LINE__);
2948 goto err;
2949 }
2950
2951 if (rte_event_dev_stop_flush_callback_register(evdev, NULL, NULL)) {
2952 printf("%d: Error uninstalling the flush callback\n", __LINE__);
2953 goto err;
2954 }
2955
2956 return 0;
2957err:
2958 rte_event_dev_dump(evdev, stdout);
2959 cleanup(t);
2960 return -1;
2961}
2962
2963static int
2964worker_loopback_worker_fn(void *arg)
2965{
2966 struct test *t = arg;
2967 uint8_t port = t->port[1];
2968 int count = 0;
2969 int enqd;
2970
2971
2972
2973
2974
2975
2976 printf("%d: \tWorker function started\n", __LINE__);
2977 while (count < NUM_PACKETS) {
2978#define BURST_SIZE 32
2979 struct rte_event ev[BURST_SIZE];
2980 uint16_t i, nb_rx = rte_event_dequeue_burst(evdev, port, ev,
2981 BURST_SIZE, 0);
2982 if (nb_rx == 0) {
2983 rte_pause();
2984 continue;
2985 }
2986
2987 for (i = 0; i < nb_rx; i++) {
2988 ev[i].queue_id++;
2989 if (ev[i].queue_id != 8) {
2990 ev[i].op = RTE_EVENT_OP_FORWARD;
2991 enqd = rte_event_enqueue_burst(evdev, port,
2992 &ev[i], 1);
2993 if (enqd != 1) {
2994 printf("%d: Can't enqueue FWD!!\n",
2995 __LINE__);
2996 return -1;
2997 }
2998 continue;
2999 }
3000
3001 ev[i].queue_id = 0;
3002 (*counter_field(ev[i].mbuf))++;
3003 if (*counter_field(ev[i].mbuf) != 16) {
3004 ev[i].op = RTE_EVENT_OP_FORWARD;
3005 enqd = rte_event_enqueue_burst(evdev, port,
3006 &ev[i], 1);
3007 if (enqd != 1) {
3008 printf("%d: Can't enqueue FWD!!\n",
3009 __LINE__);
3010 return -1;
3011 }
3012 continue;
3013 }
3014
3015 rte_pktmbuf_free(ev[i].mbuf);
3016 count++;
3017 ev[i].op = RTE_EVENT_OP_RELEASE;
3018 enqd = rte_event_enqueue_burst(evdev, port, &ev[i], 1);
3019 if (enqd != 1) {
3020 printf("%d drop enqueue failed\n", __LINE__);
3021 return -1;
3022 }
3023 }
3024 }
3025
3026 return 0;
3027}
3028
3029static int
3030worker_loopback_producer_fn(void *arg)
3031{
3032 struct test *t = arg;
3033 uint8_t port = t->port[0];
3034 uint64_t count = 0;
3035
3036 printf("%d: \tProducer function started\n", __LINE__);
3037 while (count < NUM_PACKETS) {
3038 struct rte_mbuf *m = 0;
3039 do {
3040 m = rte_pktmbuf_alloc(t->mbuf_pool);
3041 } while (m == NULL);
3042
3043 *counter_field(m) = 0;
3044
3045 struct rte_event ev = {
3046 .op = RTE_EVENT_OP_NEW,
3047 .queue_id = t->qid[0],
3048 .flow_id = (uintptr_t)m & 0xFFFF,
3049 .mbuf = m,
3050 };
3051
3052 if (rte_event_enqueue_burst(evdev, port, &ev, 1) != 1) {
3053 while (rte_event_enqueue_burst(evdev, port, &ev, 1) !=
3054 1)
3055 rte_pause();
3056 }
3057
3058 count++;
3059 }
3060
3061 return 0;
3062}
3063
3064static int
3065worker_loopback(struct test *t, uint8_t disable_implicit_release)
3066{
3067
3068
3069
3070 struct test_event_dev_stats stats;
3071 uint64_t print_cycles = 0, cycles = 0;
3072 uint64_t tx_pkts = 0;
3073 int err;
3074 int w_lcore, p_lcore;
3075
3076 static const struct rte_mbuf_dynfield counter_dynfield_desc = {
3077 .name = "rte_event_sw_dynfield_selftest_counter",
3078 .size = sizeof(counter_dynfield_t),
3079 .align = __alignof__(counter_dynfield_t),
3080 };
3081 counter_dynfield_offset =
3082 rte_mbuf_dynfield_register(&counter_dynfield_desc);
3083 if (counter_dynfield_offset < 0) {
3084 printf("Error registering mbuf field\n");
3085 return -rte_errno;
3086 }
3087
3088 if (init(t, 8, 2) < 0 ||
3089 create_atomic_qids(t, 8) < 0) {
3090 printf("%d: Error initializing device\n", __LINE__);
3091 return -1;
3092 }
3093
3094
3095 static struct rte_event_port_conf conf = {
3096 .dequeue_depth = 32,
3097 .enqueue_depth = 64,
3098 };
3099
3100
3101
3102 conf.new_event_threshold = 512;
3103 conf.event_port_cfg = disable_implicit_release ?
3104 RTE_EVENT_PORT_CFG_DISABLE_IMPL_REL : 0;
3105
3106 if (rte_event_port_setup(evdev, 0, &conf) < 0) {
3107 printf("Error setting up RX port\n");
3108 return -1;
3109 }
3110 t->port[0] = 0;
3111
3112 conf.new_event_threshold = 4096;
3113 if (rte_event_port_setup(evdev, 1, &conf) < 0) {
3114 printf("Error setting up TX port\n");
3115 return -1;
3116 }
3117 t->port[1] = 1;
3118
3119
3120 err = rte_event_port_link(evdev, t->port[1], NULL, NULL, 0);
3121 if (err != 8) {
3122 printf("%d: error mapping port 2 to all qids\n", __LINE__);
3123 return -1;
3124 }
3125
3126 if (rte_event_dev_start(evdev) < 0) {
3127 printf("%d: Error with start call\n", __LINE__);
3128 return -1;
3129 }
3130
3131 p_lcore = rte_get_next_lcore(
3132 -1,
3133 1,
3134 0);
3135 w_lcore = rte_get_next_lcore(p_lcore, 1, 0);
3136
3137 rte_eal_remote_launch(worker_loopback_producer_fn, t, p_lcore);
3138 rte_eal_remote_launch(worker_loopback_worker_fn, t, w_lcore);
3139
3140 print_cycles = cycles = rte_get_timer_cycles();
3141 while (rte_eal_get_lcore_state(p_lcore) != FINISHED ||
3142 rte_eal_get_lcore_state(w_lcore) != FINISHED) {
3143
3144 rte_service_run_iter_on_app_lcore(t->service_id, 1);
3145
3146 uint64_t new_cycles = rte_get_timer_cycles();
3147
3148 if (new_cycles - print_cycles > rte_get_timer_hz()) {
3149 test_event_dev_stats_get(evdev, &stats);
3150 printf(
3151 "%d: \tSched Rx = %"PRIu64", Tx = %"PRIu64"\n",
3152 __LINE__, stats.rx_pkts, stats.tx_pkts);
3153
3154 print_cycles = new_cycles;
3155 }
3156 if (new_cycles - cycles > rte_get_timer_hz() * 3) {
3157 test_event_dev_stats_get(evdev, &stats);
3158 if (stats.tx_pkts == tx_pkts) {
3159 rte_event_dev_dump(evdev, stdout);
3160 printf("Dumping xstats:\n");
3161 xstats_print();
3162 printf(
3163 "%d: No schedules for seconds, deadlock\n",
3164 __LINE__);
3165 return -1;
3166 }
3167 tx_pkts = stats.tx_pkts;
3168 cycles = new_cycles;
3169 }
3170 }
3171 rte_service_run_iter_on_app_lcore(t->service_id, 1);
3172
3173
3174 rte_eal_mp_wait_lcore();
3175
3176 cleanup(t);
3177 return 0;
3178}
3179
3180static struct rte_mempool *eventdev_func_mempool;
3181
3182int
3183test_sw_eventdev(void)
3184{
3185 struct test *t;
3186 int ret;
3187
3188 t = malloc(sizeof(struct test));
3189 if (t == NULL)
3190 return -1;
3191
3192
3193
3194 release_ev.op = RTE_EVENT_OP_RELEASE;
3195
3196 const char *eventdev_name = "event_sw";
3197 evdev = rte_event_dev_get_dev_id(eventdev_name);
3198 if (evdev < 0) {
3199 printf("%d: Eventdev %s not found - creating.\n",
3200 __LINE__, eventdev_name);
3201 if (rte_vdev_init(eventdev_name, NULL) < 0) {
3202 printf("Error creating eventdev\n");
3203 goto test_fail;
3204 }
3205 evdev = rte_event_dev_get_dev_id(eventdev_name);
3206 if (evdev < 0) {
3207 printf("Error finding newly created eventdev\n");
3208 goto test_fail;
3209 }
3210 }
3211
3212 if (rte_event_dev_service_id_get(evdev, &t->service_id) < 0) {
3213 printf("Failed to get service ID for software event dev\n");
3214 goto test_fail;
3215 }
3216
3217 rte_service_runstate_set(t->service_id, 1);
3218 rte_service_set_runstate_mapped_check(t->service_id, 0);
3219
3220
3221 if (!eventdev_func_mempool) {
3222 eventdev_func_mempool = rte_pktmbuf_pool_create(
3223 "EVENTDEV_SW_SA_MBUF_POOL",
3224 (1<<12),
3225 32 ,
3226 0,
3227 512,
3228 rte_socket_id());
3229 if (!eventdev_func_mempool) {
3230 printf("ERROR creating mempool\n");
3231 goto test_fail;
3232 }
3233 }
3234 t->mbuf_pool = eventdev_func_mempool;
3235 printf("*** Running Single Directed Packet test...\n");
3236 ret = test_single_directed_packet(t);
3237 if (ret != 0) {
3238 printf("ERROR - Single Directed Packet test FAILED.\n");
3239 goto test_fail;
3240 }
3241 printf("*** Running Directed Forward Credit test...\n");
3242 ret = test_directed_forward_credits(t);
3243 if (ret != 0) {
3244 printf("ERROR - Directed Forward Credit test FAILED.\n");
3245 goto test_fail;
3246 }
3247 printf("*** Running Single Load Balanced Packet test...\n");
3248 ret = single_packet(t);
3249 if (ret != 0) {
3250 printf("ERROR - Single Packet test FAILED.\n");
3251 goto test_fail;
3252 }
3253 printf("*** Running Unordered Basic test...\n");
3254 ret = unordered_basic(t);
3255 if (ret != 0) {
3256 printf("ERROR - Unordered Basic test FAILED.\n");
3257 goto test_fail;
3258 }
3259 printf("*** Running Ordered Basic test...\n");
3260 ret = ordered_basic(t);
3261 if (ret != 0) {
3262 printf("ERROR - Ordered Basic test FAILED.\n");
3263 goto test_fail;
3264 }
3265 printf("*** Running Burst Packets test...\n");
3266 ret = burst_packets(t);
3267 if (ret != 0) {
3268 printf("ERROR - Burst Packets test FAILED.\n");
3269 goto test_fail;
3270 }
3271 printf("*** Running Load Balancing test...\n");
3272 ret = load_balancing(t);
3273 if (ret != 0) {
3274 printf("ERROR - Load Balancing test FAILED.\n");
3275 goto test_fail;
3276 }
3277 printf("*** Running Prioritized Directed test...\n");
3278 ret = test_priority_directed(t);
3279 if (ret != 0) {
3280 printf("ERROR - Prioritized Directed test FAILED.\n");
3281 goto test_fail;
3282 }
3283 printf("*** Running Prioritized Atomic test...\n");
3284 ret = test_priority_atomic(t);
3285 if (ret != 0) {
3286 printf("ERROR - Prioritized Atomic test FAILED.\n");
3287 goto test_fail;
3288 }
3289
3290 printf("*** Running Prioritized Ordered test...\n");
3291 ret = test_priority_ordered(t);
3292 if (ret != 0) {
3293 printf("ERROR - Prioritized Ordered test FAILED.\n");
3294 goto test_fail;
3295 }
3296 printf("*** Running Prioritized Unordered test...\n");
3297 ret = test_priority_unordered(t);
3298 if (ret != 0) {
3299 printf("ERROR - Prioritized Unordered test FAILED.\n");
3300 goto test_fail;
3301 }
3302 printf("*** Running Invalid QID test...\n");
3303 ret = invalid_qid(t);
3304 if (ret != 0) {
3305 printf("ERROR - Invalid QID test FAILED.\n");
3306 goto test_fail;
3307 }
3308 printf("*** Running Load Balancing History test...\n");
3309 ret = load_balancing_history(t);
3310 if (ret != 0) {
3311 printf("ERROR - Load Balancing History test FAILED.\n");
3312 goto test_fail;
3313 }
3314 printf("*** Running Inflight Count test...\n");
3315 ret = inflight_counts(t);
3316 if (ret != 0) {
3317 printf("ERROR - Inflight Count test FAILED.\n");
3318 goto test_fail;
3319 }
3320 printf("*** Running Abuse Inflights test...\n");
3321 ret = abuse_inflights(t);
3322 if (ret != 0) {
3323 printf("ERROR - Abuse Inflights test FAILED.\n");
3324 goto test_fail;
3325 }
3326 printf("*** Running XStats test...\n");
3327 ret = xstats_tests(t);
3328 if (ret != 0) {
3329 printf("ERROR - XStats test FAILED.\n");
3330 goto test_fail;
3331 }
3332 printf("*** Running XStats ID Reset test...\n");
3333 ret = xstats_id_reset_tests(t);
3334 if (ret != 0) {
3335 printf("ERROR - XStats ID Reset test FAILED.\n");
3336 goto test_fail;
3337 }
3338 printf("*** Running XStats Brute Force test...\n");
3339 ret = xstats_brute_force(t);
3340 if (ret != 0) {
3341 printf("ERROR - XStats Brute Force test FAILED.\n");
3342 goto test_fail;
3343 }
3344 printf("*** Running XStats ID Abuse test...\n");
3345 ret = xstats_id_abuse_tests(t);
3346 if (ret != 0) {
3347 printf("ERROR - XStats ID Abuse test FAILED.\n");
3348 goto test_fail;
3349 }
3350 printf("*** Running QID Priority test...\n");
3351 ret = qid_priorities(t);
3352 if (ret != 0) {
3353 printf("ERROR - QID Priority test FAILED.\n");
3354 goto test_fail;
3355 }
3356 printf("*** Running Unlink-in-progress test...\n");
3357 ret = unlink_in_progress(t);
3358 if (ret != 0) {
3359 printf("ERROR - Unlink in progress test FAILED.\n");
3360 goto test_fail;
3361 }
3362 printf("*** Running Ordered Reconfigure test...\n");
3363 ret = ordered_reconfigure(t);
3364 if (ret != 0) {
3365 printf("ERROR - Ordered Reconfigure test FAILED.\n");
3366 goto test_fail;
3367 }
3368 printf("*** Running Port LB Single Reconfig test...\n");
3369 ret = port_single_lb_reconfig(t);
3370 if (ret != 0) {
3371 printf("ERROR - Port LB Single Reconfig test FAILED.\n");
3372 goto test_fail;
3373 }
3374 printf("*** Running Port Reconfig Credits test...\n");
3375 ret = port_reconfig_credits(t);
3376 if (ret != 0) {
3377 printf("ERROR - Port Reconfig Credits Reset test FAILED.\n");
3378 goto test_fail;
3379 }
3380 printf("*** Running Head-of-line-blocking test...\n");
3381 ret = holb(t);
3382 if (ret != 0) {
3383 printf("ERROR - Head-of-line-blocking test FAILED.\n");
3384 goto test_fail;
3385 }
3386 printf("*** Running Stop Flush test...\n");
3387 ret = dev_stop_flush(t);
3388 if (ret != 0) {
3389 printf("ERROR - Stop Flush test FAILED.\n");
3390 goto test_fail;
3391 }
3392 if (rte_lcore_count() >= 3) {
3393 printf("*** Running Worker loopback test...\n");
3394 ret = worker_loopback(t, 0);
3395 if (ret != 0) {
3396 printf("ERROR - Worker loopback test FAILED.\n");
3397 return ret;
3398 }
3399
3400 printf("*** Running Worker loopback test (implicit release disabled)...\n");
3401 ret = worker_loopback(t, 1);
3402 if (ret != 0) {
3403 printf("ERROR - Worker loopback test FAILED.\n");
3404 goto test_fail;
3405 }
3406 } else {
3407 printf("### Not enough cores for worker loopback tests.\n");
3408 printf("### Need at least 3 cores for the tests.\n");
3409 }
3410
3411
3412
3413
3414
3415 free(t);
3416
3417 printf("SW Eventdev Selftest Successful.\n");
3418 return 0;
3419test_fail:
3420 free(t);
3421 printf("SW Eventdev Selftest Failed.\n");
3422 return -1;
3423}
3424