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