Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <rte_common.h>
6 : : #include <rte_cycles.h>
7 : : #include <rte_debug.h>
8 : : #include <rte_eal.h>
9 : : #include <rte_ethdev.h>
10 : : #include <rte_eventdev.h>
11 : : #include <rte_hexdump.h>
12 : : #include <rte_launch.h>
13 : : #include <rte_lcore.h>
14 : : #include <rte_malloc.h>
15 : : #include <rte_mbuf.h>
16 : : #include <rte_memcpy.h>
17 : : #include <rte_per_lcore.h>
18 : : #include <rte_random.h>
19 : : #include <rte_test.h>
20 : :
21 : : #include "roc_api.h"
22 : :
23 : : #include "cnxk_eventdev.h"
24 : : #include "cnxk_eventdev_dp.h"
25 : :
26 : : #define NUM_PACKETS (1024)
27 : : #define MAX_EVENTS (1024)
28 : : #define MAX_STAGES (255)
29 : :
30 : : #define CNXK_TEST_RUN(setup, teardown, test) \
31 : : cnxk_test_run(setup, teardown, test, #test)
32 : :
33 : : static int total;
34 : : static int passed;
35 : : static int failed;
36 : : static int unsupported;
37 : :
38 : : static int evdev;
39 : : static struct rte_mempool *eventdev_test_mempool;
40 : :
41 : : struct event_attr {
42 : : uint32_t flow_id;
43 : : uint8_t event_type;
44 : : uint8_t sub_event_type;
45 : : uint8_t sched_type;
46 : : uint8_t queue;
47 : : uint8_t port;
48 : : };
49 : :
50 : : static uint32_t seqn_list_index;
51 : : static int seqn_list[NUM_PACKETS];
52 : :
53 : : static inline void
54 : : seqn_list_init(void)
55 : : {
56 : : RTE_BUILD_BUG_ON(NUM_PACKETS < MAX_EVENTS);
57 : : memset(seqn_list, 0, sizeof(seqn_list));
58 : 0 : seqn_list_index = 0;
59 : : }
60 : :
61 : : static inline int
62 : : seqn_list_update(int val)
63 : : {
64 : 0 : if (seqn_list_index >= NUM_PACKETS)
65 : : return -1;
66 : :
67 : 0 : seqn_list[seqn_list_index++] = val;
68 : : rte_atomic_thread_fence(rte_memory_order_release);
69 : : return 0;
70 : : }
71 : :
72 : : static inline int
73 : 0 : seqn_list_check(int limit)
74 : : {
75 : : int i;
76 : :
77 [ # # ]: 0 : for (i = 0; i < limit; i++) {
78 [ # # ]: 0 : if (seqn_list[i] != i) {
79 : 0 : plt_err("Seqn mismatch %d %d", seqn_list[i], i);
80 : 0 : return -1;
81 : : }
82 : : }
83 : : return 0;
84 : : }
85 : :
86 : : struct test_core_param {
87 : : uint32_t __rte_atomic *total_events;
88 : : uint64_t dequeue_tmo_ticks;
89 : : uint8_t port;
90 : : uint8_t sched_type;
91 : : };
92 : :
93 : : static int
94 : 0 : testsuite_setup(const char *eventdev_name)
95 : : {
96 : 0 : evdev = rte_event_dev_get_dev_id(eventdev_name);
97 [ # # ]: 0 : if (evdev < 0) {
98 : 0 : plt_err("%d: Eventdev %s not found", __LINE__, eventdev_name);
99 : 0 : return -1;
100 : : }
101 : : return 0;
102 : : }
103 : :
104 : : static void
105 : : testsuite_teardown(void)
106 : : {
107 : 0 : rte_event_dev_close(evdev);
108 : 0 : total = 0;
109 : 0 : passed = 0;
110 : 0 : failed = 0;
111 : 0 : unsupported = 0;
112 : : }
113 : :
114 : : static inline void
115 : 0 : devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
116 : : struct rte_event_dev_info *info)
117 : : {
118 : : memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
119 : 0 : dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
120 : 0 : dev_conf->nb_event_ports = info->max_event_ports;
121 : 0 : dev_conf->nb_event_queues = info->max_event_queues;
122 : 0 : dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
123 : 0 : dev_conf->nb_event_port_dequeue_depth =
124 : 0 : info->max_event_port_dequeue_depth;
125 : 0 : dev_conf->nb_event_port_enqueue_depth =
126 : 0 : info->max_event_port_enqueue_depth;
127 : : dev_conf->nb_event_port_enqueue_depth =
128 : : info->max_event_port_enqueue_depth;
129 : 0 : dev_conf->nb_events_limit = info->max_num_events;
130 : 0 : }
131 : :
132 : : enum {
133 : : TEST_EVENTDEV_SETUP_DEFAULT,
134 : : TEST_EVENTDEV_SETUP_PRIORITY,
135 : : TEST_EVENTDEV_SETUP_DEQUEUE_TIMEOUT,
136 : : };
137 : :
138 : : static inline int
139 : 0 : _eventdev_setup(int mode)
140 : : {
141 : : const char *pool_name = "evdev_cnxk_test_pool";
142 : : struct rte_event_dev_config dev_conf;
143 : : struct rte_event_dev_info info;
144 : : int i, ret;
145 : :
146 : : /* Create and destroy pool for each test case to make it standalone */
147 : 0 : eventdev_test_mempool = rte_pktmbuf_pool_create(
148 : 0 : pool_name, MAX_EVENTS, 0, 0, 512, rte_socket_id());
149 [ # # ]: 0 : if (!eventdev_test_mempool) {
150 : 0 : plt_err("ERROR creating mempool");
151 : 0 : return -1;
152 : : }
153 : :
154 : 0 : ret = rte_event_dev_info_get(evdev, &info);
155 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info");
156 : :
157 : 0 : devconf_set_default_sane_values(&dev_conf, &info);
158 [ # # ]: 0 : if (mode == TEST_EVENTDEV_SETUP_DEQUEUE_TIMEOUT)
159 : 0 : dev_conf.event_dev_cfg |= RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT;
160 : :
161 : 0 : ret = rte_event_dev_configure(evdev, &dev_conf);
162 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure eventdev");
163 : :
164 : : uint32_t queue_count;
165 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
166 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
167 : : &queue_count),
168 : : "Queue count get failed");
169 : :
170 [ # # ]: 0 : if (mode == TEST_EVENTDEV_SETUP_PRIORITY) {
171 [ # # ]: 0 : if (queue_count > 8)
172 : 0 : queue_count = 8;
173 : :
174 : : /* Configure event queues(0 to n) with
175 : : * RTE_EVENT_DEV_PRIORITY_HIGHEST to
176 : : * RTE_EVENT_DEV_PRIORITY_LOWEST
177 : : */
178 : 0 : uint8_t step =
179 : 0 : (RTE_EVENT_DEV_PRIORITY_LOWEST + 1) / queue_count;
180 [ # # ]: 0 : for (i = 0; i < (int)queue_count; i++) {
181 : : struct rte_event_queue_conf queue_conf;
182 : :
183 : 0 : ret = rte_event_queue_default_conf_get(evdev, i,
184 : : &queue_conf);
185 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get def_conf%d",
186 : : i);
187 : 0 : queue_conf.priority = i * step;
188 : 0 : ret = rte_event_queue_setup(evdev, i, &queue_conf);
189 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d",
190 : : i);
191 : : }
192 : :
193 : : } else {
194 : : /* Configure event queues with default priority */
195 [ # # ]: 0 : for (i = 0; i < (int)queue_count; i++) {
196 : 0 : ret = rte_event_queue_setup(evdev, i, NULL);
197 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup queue=%d",
198 : : i);
199 : : }
200 : : }
201 : : /* Configure event ports */
202 : : uint32_t port_count;
203 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
204 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
205 : : &port_count),
206 : : "Port count get failed");
207 [ # # ]: 0 : for (i = 0; i < (int)port_count; i++) {
208 : 0 : ret = rte_event_port_setup(evdev, i, NULL);
209 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup port=%d", i);
210 : 0 : ret = rte_event_port_link(evdev, i, NULL, NULL, 0);
211 [ # # ]: 0 : RTE_TEST_ASSERT(ret >= 0, "Failed to link all queues port=%d",
212 : : i);
213 : : }
214 : :
215 : 0 : ret = rte_event_dev_start(evdev);
216 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start device");
217 : :
218 : : return 0;
219 : : }
220 : :
221 : : static inline int
222 : 0 : eventdev_setup(void)
223 : : {
224 : 0 : return _eventdev_setup(TEST_EVENTDEV_SETUP_DEFAULT);
225 : : }
226 : :
227 : : static inline int
228 : 0 : eventdev_setup_priority(void)
229 : : {
230 : 0 : return _eventdev_setup(TEST_EVENTDEV_SETUP_PRIORITY);
231 : : }
232 : :
233 : : static inline int
234 : 0 : eventdev_setup_dequeue_timeout(void)
235 : : {
236 : 0 : return _eventdev_setup(TEST_EVENTDEV_SETUP_DEQUEUE_TIMEOUT);
237 : : }
238 : :
239 : : static inline void
240 : 0 : eventdev_teardown(void)
241 : : {
242 : 0 : rte_event_dev_stop(evdev);
243 : 0 : rte_mempool_free(eventdev_test_mempool);
244 : 0 : }
245 : :
246 : : static inline void
247 : : update_event_and_validation_attr(struct rte_mbuf *m, struct rte_event *ev,
248 : : uint32_t flow_id, uint8_t event_type,
249 : : uint8_t sub_event_type, uint8_t sched_type,
250 : : uint8_t queue, uint8_t port)
251 : : {
252 : : struct event_attr *attr;
253 : :
254 : : /* Store the event attributes in mbuf for future reference */
255 : 0 : attr = rte_pktmbuf_mtod(m, struct event_attr *);
256 : 0 : attr->flow_id = flow_id;
257 : 0 : attr->event_type = event_type;
258 : 0 : attr->sub_event_type = sub_event_type;
259 : 0 : attr->sched_type = sched_type;
260 : 0 : attr->queue = queue;
261 : 0 : attr->port = port;
262 : :
263 : 0 : ev->flow_id = flow_id;
264 : 0 : ev->sub_event_type = sub_event_type;
265 : 0 : ev->event_type = event_type;
266 : : /* Inject the new event */
267 : 0 : ev->op = RTE_EVENT_OP_NEW;
268 : 0 : ev->sched_type = sched_type;
269 : 0 : ev->queue_id = queue;
270 : 0 : ev->mbuf = m;
271 : : }
272 : :
273 : : static inline int
274 : 0 : inject_events(uint32_t flow_id, uint8_t event_type, uint8_t sub_event_type,
275 : : uint8_t sched_type, uint8_t queue, uint8_t port,
276 : : unsigned int events)
277 : : {
278 : : struct rte_mbuf *m;
279 : : unsigned int i;
280 : :
281 [ # # ]: 0 : for (i = 0; i < events; i++) {
282 : 0 : struct rte_event ev = {.event = 0, .u64 = 0};
283 : :
284 : 0 : m = rte_pktmbuf_alloc(eventdev_test_mempool);
285 [ # # ]: 0 : RTE_TEST_ASSERT_NOT_NULL(m, "mempool alloc failed");
286 : :
287 : 0 : *rte_event_pmd_selftest_seqn(m) = i;
288 : : update_event_and_validation_attr(m, &ev, flow_id, event_type,
289 : : sub_event_type, sched_type,
290 : : queue, port);
291 : 0 : rte_event_enqueue_burst(evdev, port, &ev, 1);
292 : : }
293 : : return 0;
294 : : }
295 : :
296 : : static inline int
297 : 0 : check_excess_events(uint8_t port)
298 : : {
299 : : uint16_t valid_event;
300 : : struct rte_event ev;
301 : : int i;
302 : :
303 : : /* Check for excess events, try for a few times and exit */
304 [ # # ]: 0 : for (i = 0; i < 32; i++) {
305 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
306 : :
307 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(valid_event,
308 : : "Unexpected valid event=%d",
309 : : *rte_event_pmd_selftest_seqn(ev.mbuf));
310 : : }
311 : : return 0;
312 : : }
313 : :
314 : : static inline int
315 : 0 : generate_random_events(const unsigned int total_events)
316 : : {
317 : : struct rte_event_dev_info info;
318 : : uint32_t queue_count;
319 : : unsigned int i;
320 : : int ret;
321 : :
322 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
323 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
324 : : &queue_count),
325 : : "Queue count get failed");
326 : :
327 : 0 : ret = rte_event_dev_info_get(evdev, &info);
328 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get event dev info");
329 [ # # ]: 0 : for (i = 0; i < total_events; i++) {
330 : 0 : ret = inject_events(
331 : 0 : rte_rand() % info.max_event_queue_flows /*flow_id */,
332 : : RTE_EVENT_TYPE_CPU /* event_type */,
333 : 0 : rte_rand() % 256 /* sub_event_type */,
334 : 0 : rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
335 : 0 : rte_rand() % queue_count /* queue */, 0 /* port */,
336 : : 1 /* events */);
337 [ # # ]: 0 : if (ret)
338 : : return -1;
339 : : }
340 : : return ret;
341 : : }
342 : :
343 : : static inline int
344 : 0 : validate_event(struct rte_event *ev)
345 : : {
346 : : struct event_attr *attr;
347 : :
348 : 0 : attr = rte_pktmbuf_mtod(ev->mbuf, struct event_attr *);
349 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(attr->flow_id, ev->flow_id,
350 : : "flow_id mismatch enq=%d deq =%d", attr->flow_id,
351 : : ev->flow_id);
352 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(attr->event_type, ev->event_type,
353 : : "event_type mismatch enq=%d deq =%d",
354 : : attr->event_type, ev->event_type);
355 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(attr->sub_event_type, ev->sub_event_type,
356 : : "sub_event_type mismatch enq=%d deq =%d",
357 : : attr->sub_event_type, ev->sub_event_type);
358 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(attr->sched_type, ev->sched_type,
359 : : "sched_type mismatch enq=%d deq =%d",
360 : : attr->sched_type, ev->sched_type);
361 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(attr->queue, ev->queue_id,
362 : : "queue mismatch enq=%d deq =%d", attr->queue,
363 : : ev->queue_id);
364 : : return 0;
365 : : }
366 : :
367 : : typedef int (*validate_event_cb)(uint32_t index, uint8_t port,
368 : : struct rte_event *ev);
369 : :
370 : : static inline int
371 : 0 : consume_events(uint8_t port, const uint32_t total_events, validate_event_cb fn)
372 : : {
373 : : uint32_t events = 0, forward_progress_cnt = 0, index = 0;
374 : : uint16_t valid_event;
375 : : struct rte_event ev;
376 : : int ret;
377 : :
378 : : while (1) {
379 [ # # ]: 0 : if (++forward_progress_cnt > UINT16_MAX) {
380 : 0 : plt_err("Detected deadlock");
381 : 0 : return -1;
382 : : }
383 : :
384 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
385 [ # # ]: 0 : if (!valid_event)
386 : 0 : continue;
387 : :
388 : : forward_progress_cnt = 0;
389 : 0 : ret = validate_event(&ev);
390 [ # # ]: 0 : if (ret)
391 : : return -1;
392 : :
393 [ # # ]: 0 : if (fn != NULL) {
394 : 0 : ret = fn(index, port, &ev);
395 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
396 : : ret, "Failed to validate test specific event");
397 : : }
398 : :
399 : 0 : ++index;
400 : :
401 : 0 : rte_pktmbuf_free(ev.mbuf);
402 [ # # ]: 0 : if (++events >= total_events)
403 : : break;
404 : : }
405 : :
406 : 0 : return check_excess_events(port);
407 : : }
408 : :
409 : : static int
410 : 0 : validate_simple_enqdeq(uint32_t index, uint8_t port, struct rte_event *ev)
411 : : {
412 : : RTE_SET_USED(port);
413 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(index, *rte_event_pmd_selftest_seqn(ev->mbuf),
414 : : "index=%d != seqn=%d", index,
415 : : *rte_event_pmd_selftest_seqn(ev->mbuf));
416 : : return 0;
417 : : }
418 : :
419 : : static inline int
420 : 0 : test_simple_enqdeq(uint8_t sched_type)
421 : : {
422 : : int ret;
423 : :
424 : 0 : ret = inject_events(0 /*flow_id */, RTE_EVENT_TYPE_CPU /* event_type */,
425 : : 0 /* sub_event_type */, sched_type, 0 /* queue */,
426 : : 0 /* port */, MAX_EVENTS);
427 [ # # ]: 0 : if (ret)
428 : : return -1;
429 : :
430 : 0 : return consume_events(0 /* port */, MAX_EVENTS, validate_simple_enqdeq);
431 : : }
432 : :
433 : : static int
434 : 0 : test_simple_enqdeq_ordered(void)
435 : : {
436 : 0 : return test_simple_enqdeq(RTE_SCHED_TYPE_ORDERED);
437 : : }
438 : :
439 : : static int
440 : 0 : test_simple_enqdeq_atomic(void)
441 : : {
442 : 0 : return test_simple_enqdeq(RTE_SCHED_TYPE_ATOMIC);
443 : : }
444 : :
445 : : static int
446 : 0 : test_simple_enqdeq_parallel(void)
447 : : {
448 : 0 : return test_simple_enqdeq(RTE_SCHED_TYPE_PARALLEL);
449 : : }
450 : :
451 : : /*
452 : : * Generate a prescribed number of events and spread them across available
453 : : * queues. On dequeue, using single event port(port 0) verify the enqueued
454 : : * event attributes
455 : : */
456 : : static int
457 : 0 : test_multi_queue_enq_single_port_deq(void)
458 : : {
459 : : int ret;
460 : :
461 : 0 : ret = generate_random_events(MAX_EVENTS);
462 [ # # ]: 0 : if (ret)
463 : : return -1;
464 : :
465 : 0 : return consume_events(0 /* port */, MAX_EVENTS, NULL);
466 : : }
467 : :
468 : : /*
469 : : * Inject 0..MAX_EVENTS events over 0..queue_count with modulus
470 : : * operation
471 : : *
472 : : * For example, Inject 32 events over 0..7 queues
473 : : * enqueue events 0, 8, 16, 24 in queue 0
474 : : * enqueue events 1, 9, 17, 25 in queue 1
475 : : * ..
476 : : * ..
477 : : * enqueue events 7, 15, 23, 31 in queue 7
478 : : *
479 : : * On dequeue, Validate the events comes in 0,8,16,24,1,9,17,25..,7,15,23,31
480 : : * order from queue0(highest priority) to queue7(lowest_priority)
481 : : */
482 : : static int
483 : 0 : validate_queue_priority(uint32_t index, uint8_t port, struct rte_event *ev)
484 : : {
485 : : uint32_t queue_count;
486 : :
487 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
488 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
489 : : &queue_count),
490 : : "Queue count get failed");
491 [ # # ]: 0 : if (queue_count > 8)
492 : 0 : queue_count = 8;
493 : 0 : uint32_t range = MAX_EVENTS / queue_count;
494 : 0 : uint32_t expected_val = (index % range) * queue_count;
495 : :
496 : 0 : expected_val += ev->queue_id;
497 : : RTE_SET_USED(port);
498 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(
499 : : *rte_event_pmd_selftest_seqn(ev->mbuf), expected_val,
500 : : "seqn=%d index=%d expected=%d range=%d nb_queues=%d max_event=%d",
501 : : *rte_event_pmd_selftest_seqn(ev->mbuf), index, expected_val,
502 : : range, queue_count, MAX_EVENTS);
503 : : return 0;
504 : : }
505 : :
506 : : static int
507 : 0 : test_multi_queue_priority(void)
508 : : {
509 : : int i, max_evts_roundoff;
510 : : /* See validate_queue_priority() comments for priority validate logic */
511 : : uint32_t queue_count;
512 : : struct rte_mbuf *m;
513 : : uint8_t queue;
514 : :
515 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
516 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
517 : : &queue_count),
518 : : "Queue count get failed");
519 [ # # ]: 0 : if (queue_count > 8)
520 : 0 : queue_count = 8;
521 : 0 : max_evts_roundoff = MAX_EVENTS / queue_count;
522 : 0 : max_evts_roundoff *= queue_count;
523 : :
524 [ # # ]: 0 : for (i = 0; i < max_evts_roundoff; i++) {
525 : 0 : struct rte_event ev = {.event = 0, .u64 = 0};
526 : :
527 : 0 : m = rte_pktmbuf_alloc(eventdev_test_mempool);
528 [ # # ]: 0 : RTE_TEST_ASSERT_NOT_NULL(m, "mempool alloc failed");
529 : :
530 : 0 : *rte_event_pmd_selftest_seqn(m) = i;
531 : 0 : queue = i % queue_count;
532 : : update_event_and_validation_attr(m, &ev, 0, RTE_EVENT_TYPE_CPU,
533 : : 0, RTE_SCHED_TYPE_PARALLEL,
534 : : queue, 0);
535 : 0 : rte_event_enqueue_burst(evdev, 0, &ev, 1);
536 : : }
537 : :
538 : 0 : return consume_events(0, max_evts_roundoff, validate_queue_priority);
539 : : }
540 : :
541 : : static int
542 : 0 : worker_multi_port_fn(void *arg)
543 : : {
544 : : struct test_core_param *param = arg;
545 : 0 : uint32_t __rte_atomic *total_events = param->total_events;
546 : 0 : uint8_t port = param->port;
547 : : uint16_t valid_event;
548 : : struct rte_event ev;
549 : : int ret;
550 : :
551 [ # # ]: 0 : while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
552 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
553 [ # # ]: 0 : if (!valid_event)
554 : 0 : continue;
555 : :
556 : 0 : ret = validate_event(&ev);
557 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to validate event");
558 : 0 : rte_pktmbuf_free(ev.mbuf);
559 : 0 : rte_atomic_fetch_sub_explicit(total_events, 1, rte_memory_order_relaxed);
560 : : }
561 : :
562 : : return 0;
563 : : }
564 : :
565 : : static inline int
566 : 0 : wait_workers_to_join(const uint32_t __rte_atomic *count)
567 : : {
568 : : uint64_t cycles, print_cycles;
569 : :
570 : : cycles = rte_get_timer_cycles();
571 : : print_cycles = cycles;
572 [ # # ]: 0 : while (rte_atomic_load_explicit(count, rte_memory_order_relaxed)) {
573 : : uint64_t new_cycles = rte_get_timer_cycles();
574 : :
575 [ # # ]: 0 : if (new_cycles - print_cycles > rte_get_timer_hz()) {
576 : 0 : plt_info("Events %d",
577 : : rte_atomic_load_explicit(count, rte_memory_order_relaxed));
578 : : print_cycles = new_cycles;
579 : : }
580 [ # # ]: 0 : if (new_cycles - cycles > rte_get_timer_hz() * 10000000000) {
581 : 0 : plt_err("No schedules for seconds, deadlock (%d)",
582 : : rte_atomic_load_explicit(count, rte_memory_order_relaxed));
583 : 0 : rte_event_dev_dump(evdev, stdout);
584 : : cycles = new_cycles;
585 : 0 : return -1;
586 : : }
587 : : }
588 : 0 : rte_eal_mp_wait_lcore();
589 : :
590 : 0 : return 0;
591 : : }
592 : :
593 : : static inline int
594 : 0 : launch_workers_and_wait(int (*main_thread)(void *),
595 : : int (*worker_thread)(void *), uint32_t total_events,
596 : : uint8_t nb_workers, uint8_t sched_type)
597 : : {
598 : : uint32_t __rte_atomic atomic_total_events;
599 : : struct test_core_param *param;
600 : : uint64_t dequeue_tmo_ticks;
601 : : uint8_t port = 0;
602 : : int w_lcore;
603 : : int ret;
604 : :
605 [ # # ]: 0 : if (!nb_workers)
606 : : return 0;
607 : :
608 [ # # ]: 0 : rte_atomic_store_explicit(&atomic_total_events, total_events, rte_memory_order_relaxed);
609 : : seqn_list_init();
610 : :
611 : 0 : param = malloc(sizeof(struct test_core_param) * nb_workers);
612 [ # # ]: 0 : if (!param)
613 : : return -1;
614 : :
615 : 0 : ret = rte_event_dequeue_timeout_ticks(
616 : 0 : evdev, rte_rand() % 10000000 /* 10ms */, &dequeue_tmo_ticks);
617 [ # # ]: 0 : if (ret) {
618 : 0 : free(param);
619 : 0 : return -1;
620 : : }
621 : :
622 : 0 : param[0].total_events = &atomic_total_events;
623 : 0 : param[0].sched_type = sched_type;
624 : 0 : param[0].port = 0;
625 : 0 : param[0].dequeue_tmo_ticks = dequeue_tmo_ticks;
626 : : rte_wmb();
627 : :
628 : 0 : w_lcore = rte_get_next_lcore(
629 : : /* start core */ -1,
630 : : /* skip main */ 1,
631 : : /* wrap */ 0);
632 [ # # ]: 0 : if (w_lcore == RTE_MAX_LCORE) {
633 : 0 : plt_err("Failed to get next available lcore");
634 : 0 : free(param);
635 : 0 : return -1;
636 : : }
637 : :
638 : 0 : rte_eal_remote_launch(main_thread, ¶m[0], w_lcore);
639 : :
640 [ # # ]: 0 : for (port = 1; port < nb_workers; port++) {
641 : 0 : param[port].total_events = &atomic_total_events;
642 : 0 : param[port].sched_type = sched_type;
643 : 0 : param[port].port = port;
644 : 0 : param[port].dequeue_tmo_ticks = dequeue_tmo_ticks;
645 : : rte_atomic_thread_fence(rte_memory_order_release);
646 : 0 : w_lcore = rte_get_next_lcore(w_lcore, 1, 0);
647 [ # # ]: 0 : if (w_lcore == RTE_MAX_LCORE) {
648 : 0 : plt_err("Failed to get next available lcore");
649 : 0 : free(param);
650 : 0 : return -1;
651 : : }
652 : :
653 : 0 : rte_eal_remote_launch(worker_thread, ¶m[port], w_lcore);
654 : : }
655 : :
656 : : rte_atomic_thread_fence(rte_memory_order_release);
657 : 0 : ret = wait_workers_to_join(&atomic_total_events);
658 : 0 : free(param);
659 : :
660 : 0 : return ret;
661 : : }
662 : :
663 : : /*
664 : : * Generate a prescribed number of events and spread them across available
665 : : * queues. Dequeue the events through multiple ports and verify the enqueued
666 : : * event attributes
667 : : */
668 : : static int
669 : 0 : test_multi_queue_enq_multi_port_deq(void)
670 : : {
671 : : const unsigned int total_events = MAX_EVENTS;
672 : : uint32_t nr_ports;
673 : : int ret;
674 : :
675 : 0 : ret = generate_random_events(total_events);
676 [ # # ]: 0 : if (ret)
677 : : return -1;
678 : :
679 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
680 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
681 : : &nr_ports),
682 : : "Port count get failed");
683 : 0 : nr_ports = RTE_MIN(nr_ports, rte_lcore_count() - 1);
684 : :
685 [ # # ]: 0 : if (!nr_ports) {
686 : 0 : plt_err("Not enough ports=%d or workers=%d", nr_ports,
687 : : rte_lcore_count() - 1);
688 : 0 : return 0;
689 : : }
690 : :
691 : 0 : return launch_workers_and_wait(worker_multi_port_fn,
692 : : worker_multi_port_fn, total_events,
693 : : nr_ports, 0xff /* invalid */);
694 : : }
695 : :
696 : : static void
697 : 0 : flush(uint8_t dev_id, struct rte_event event, void *arg)
698 : : {
699 : : unsigned int *count = arg;
700 : :
701 : : RTE_SET_USED(dev_id);
702 [ # # ]: 0 : if (event.event_type == RTE_EVENT_TYPE_CPU)
703 : 0 : *count = *count + 1;
704 : 0 : }
705 : :
706 : : static int
707 : 0 : test_dev_stop_flush(void)
708 : : {
709 : 0 : unsigned int total_events = MAX_EVENTS, count = 0;
710 : : int ret;
711 : :
712 : 0 : ret = generate_random_events(total_events);
713 [ # # ]: 0 : if (ret)
714 : : return -1;
715 : :
716 : 0 : ret = rte_event_dev_stop_flush_callback_register(evdev, flush, &count);
717 [ # # ]: 0 : if (ret)
718 : : return -2;
719 : 0 : rte_event_dev_stop(evdev);
720 : 0 : ret = rte_event_dev_stop_flush_callback_register(evdev, NULL, NULL);
721 [ # # ]: 0 : if (ret)
722 : : return -3;
723 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(total_events, count,
724 : : "count mismatch total_events=%d count=%d",
725 : : total_events, count);
726 : :
727 : : return 0;
728 : : }
729 : :
730 : : static int
731 : 0 : validate_queue_to_port_single_link(uint32_t index, uint8_t port,
732 : : struct rte_event *ev)
733 : : {
734 : : RTE_SET_USED(index);
735 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(port, ev->queue_id,
736 : : "queue mismatch enq=%d deq =%d", port,
737 : : ev->queue_id);
738 : :
739 : : return 0;
740 : : }
741 : :
742 : : /*
743 : : * Link queue x to port x and check correctness of link by checking
744 : : * queue_id == x on dequeue on the specific port x
745 : : */
746 : : static int
747 : 0 : test_queue_to_port_single_link(void)
748 : : {
749 : : int i, nr_links, ret;
750 : : uint32_t queue_count;
751 : : uint32_t port_count;
752 : :
753 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
754 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
755 : : &port_count),
756 : : "Port count get failed");
757 : :
758 : : /* Unlink all connections that created in eventdev_setup */
759 [ # # ]: 0 : for (i = 0; i < (int)port_count; i++) {
760 : 0 : ret = rte_event_port_unlink(evdev, i, NULL, 0);
761 [ # # ]: 0 : RTE_TEST_ASSERT(ret >= 0, "Failed to unlink all queues port=%d",
762 : : i);
763 : : }
764 : :
765 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
766 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
767 : : &queue_count),
768 : : "Queue count get failed");
769 : :
770 : 0 : nr_links = RTE_MIN(port_count, queue_count);
771 : 0 : const unsigned int total_events = MAX_EVENTS / nr_links;
772 : :
773 : : /* Link queue x to port x and inject events to queue x through port x */
774 [ # # ]: 0 : for (i = 0; i < nr_links; i++) {
775 : 0 : uint8_t queue = (uint8_t)i;
776 : :
777 : 0 : ret = rte_event_port_link(evdev, i, &queue, NULL, 1);
778 [ # # ]: 0 : RTE_TEST_ASSERT(ret == 1, "Failed to link queue to port %d", i);
779 : :
780 : 0 : ret = inject_events(0x100 /*flow_id */,
781 : : RTE_EVENT_TYPE_CPU /* event_type */,
782 : 0 : rte_rand() % 256 /* sub_event_type */,
783 : 0 : rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
784 : : queue /* queue */, i /* port */,
785 : : total_events /* events */);
786 [ # # ]: 0 : if (ret)
787 : : return -1;
788 : : }
789 : :
790 : : /* Verify the events generated from correct queue */
791 [ # # ]: 0 : for (i = 0; i < nr_links; i++) {
792 : 0 : ret = consume_events(i /* port */, total_events,
793 : : validate_queue_to_port_single_link);
794 [ # # ]: 0 : if (ret)
795 : : return -1;
796 : : }
797 : :
798 : : return 0;
799 : : }
800 : :
801 : : static int
802 : 0 : validate_queue_to_port_multi_link(uint32_t index, uint8_t port,
803 : : struct rte_event *ev)
804 : : {
805 : : RTE_SET_USED(index);
806 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(port, (ev->queue_id & 0x1),
807 : : "queue mismatch enq=%d deq =%d", port,
808 : : ev->queue_id);
809 : :
810 : : return 0;
811 : : }
812 : :
813 : : /*
814 : : * Link all even number of queues to port 0 and all odd number of queues to
815 : : * port 1 and verify the link connection on dequeue
816 : : */
817 : : static int
818 : 0 : test_queue_to_port_multi_link(void)
819 : : {
820 : : int ret, port0_events = 0, port1_events = 0;
821 : 0 : uint32_t nr_queues = 0;
822 : 0 : uint32_t nr_ports = 0;
823 : : uint8_t queue, port;
824 : :
825 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
826 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
827 : : &nr_queues),
828 : : "Queue count get failed");
829 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
830 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
831 : : &nr_queues),
832 : : "Queue count get failed");
833 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
834 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
835 : : &nr_ports),
836 : : "Port count get failed");
837 : :
838 [ # # ]: 0 : if (nr_ports < 2) {
839 : 0 : plt_err("Not enough ports to test ports=%d", nr_ports);
840 : 0 : return 0;
841 : : }
842 : :
843 : : /* Unlink all connections that created in eventdev_setup */
844 [ # # ]: 0 : for (port = 0; port < nr_ports; port++) {
845 : 0 : ret = rte_event_port_unlink(evdev, port, NULL, 0);
846 [ # # ]: 0 : RTE_TEST_ASSERT(ret >= 0, "Failed to unlink all queues port=%d",
847 : : port);
848 : : }
849 : :
850 : 0 : unsigned int total_events = MAX_EVENTS / nr_queues;
851 [ # # ]: 0 : if (!total_events) {
852 : 0 : nr_queues = MAX_EVENTS;
853 : : total_events = MAX_EVENTS / nr_queues;
854 : : }
855 : :
856 : : /* Link all even number of queues to port0 and odd numbers to port 1*/
857 [ # # ]: 0 : for (queue = 0; queue < nr_queues; queue++) {
858 : 0 : port = queue & 0x1;
859 : 0 : ret = rte_event_port_link(evdev, port, &queue, NULL, 1);
860 [ # # ]: 0 : RTE_TEST_ASSERT(ret == 1, "Failed to link queue=%d to port=%d",
861 : : queue, port);
862 : :
863 : 0 : ret = inject_events(0x100 /*flow_id */,
864 : : RTE_EVENT_TYPE_CPU /* event_type */,
865 : 0 : rte_rand() % 256 /* sub_event_type */,
866 : 0 : rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1),
867 : : queue /* queue */, port /* port */,
868 : : total_events /* events */);
869 [ # # ]: 0 : if (ret)
870 : : return -1;
871 : :
872 [ # # ]: 0 : if (port == 0)
873 : 0 : port0_events += total_events;
874 : : else
875 : 0 : port1_events += total_events;
876 : : }
877 : :
878 : 0 : ret = consume_events(0 /* port */, port0_events,
879 : : validate_queue_to_port_multi_link);
880 [ # # ]: 0 : if (ret)
881 : : return -1;
882 : 0 : ret = consume_events(1 /* port */, port1_events,
883 : : validate_queue_to_port_multi_link);
884 [ # # ]: 0 : if (ret)
885 : 0 : return -1;
886 : :
887 : : return 0;
888 : : }
889 : :
890 : : static int
891 : 0 : worker_flow_based_pipeline(void *arg)
892 : : {
893 : : struct test_core_param *param = arg;
894 : 0 : uint64_t dequeue_tmo_ticks = param->dequeue_tmo_ticks;
895 : 0 : uint32_t __rte_atomic *total_events = param->total_events;
896 : 0 : uint8_t new_sched_type = param->sched_type;
897 : 0 : uint8_t port = param->port;
898 : : uint16_t valid_event;
899 : : struct rte_event ev;
900 : :
901 [ # # ]: 0 : while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
902 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1,
903 : : dequeue_tmo_ticks);
904 [ # # ]: 0 : if (!valid_event)
905 : 0 : continue;
906 : :
907 : : /* Events from stage 0 */
908 [ # # ]: 0 : if (ev.sub_event_type == 0) {
909 : : /* Move to atomic flow to maintain the ordering */
910 : 0 : ev.flow_id = 0x2;
911 : 0 : ev.event_type = RTE_EVENT_TYPE_CPU;
912 : 0 : ev.sub_event_type = 1; /* stage 1 */
913 : 0 : ev.sched_type = new_sched_type;
914 : 0 : ev.op = RTE_EVENT_OP_FORWARD;
915 : 0 : rte_event_enqueue_burst(evdev, port, &ev, 1);
916 [ # # ]: 0 : } else if (ev.sub_event_type == 1) { /* Events from stage 1*/
917 [ # # ]: 0 : uint32_t seqn = *rte_event_pmd_selftest_seqn(ev.mbuf);
918 : :
919 [ # # ]: 0 : if (seqn_list_update(seqn) == 0) {
920 : 0 : rte_pktmbuf_free(ev.mbuf);
921 : 0 : rte_atomic_fetch_sub_explicit(total_events, 1,
922 : : rte_memory_order_relaxed);
923 : : } else {
924 : 0 : plt_err("Failed to update seqn_list");
925 : 0 : return -1;
926 : : }
927 : : } else {
928 : 0 : plt_err("Invalid ev.sub_event_type = %d",
929 : : ev.sub_event_type);
930 : 0 : return -1;
931 : : }
932 : : }
933 : : return 0;
934 : : }
935 : :
936 : : static int
937 : 0 : test_multiport_flow_sched_type_test(uint8_t in_sched_type,
938 : : uint8_t out_sched_type)
939 : : {
940 : : const unsigned int total_events = MAX_EVENTS;
941 : : uint32_t nr_ports;
942 : : int ret;
943 : :
944 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
945 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
946 : : &nr_ports),
947 : : "Port count get failed");
948 : 0 : nr_ports = RTE_MIN(nr_ports, rte_lcore_count() - 1);
949 : :
950 [ # # ]: 0 : if (!nr_ports) {
951 : 0 : plt_err("Not enough ports=%d or workers=%d", nr_ports,
952 : : rte_lcore_count() - 1);
953 : 0 : return 0;
954 : : }
955 : :
956 : : /* Injects events with a 0 sequence number to total_events */
957 : 0 : ret = inject_events(
958 : : 0x1 /*flow_id */, RTE_EVENT_TYPE_CPU /* event_type */,
959 : : 0 /* sub_event_type (stage 0) */, in_sched_type, 0 /* queue */,
960 : : 0 /* port */, total_events /* events */);
961 [ # # ]: 0 : if (ret)
962 : : return -1;
963 : :
964 : : rte_mb();
965 : 0 : ret = launch_workers_and_wait(worker_flow_based_pipeline,
966 : : worker_flow_based_pipeline, total_events,
967 : : nr_ports, out_sched_type);
968 [ # # ]: 0 : if (ret)
969 : : return -1;
970 : :
971 : 0 : if (in_sched_type != RTE_SCHED_TYPE_PARALLEL &&
972 [ # # ]: 0 : out_sched_type == RTE_SCHED_TYPE_ATOMIC) {
973 : : /* Check the events order maintained or not */
974 : 0 : return seqn_list_check(total_events);
975 : : }
976 : :
977 : : return 0;
978 : : }
979 : :
980 : : /* Multi port ordered to atomic transaction */
981 : : static int
982 : 0 : test_multi_port_flow_ordered_to_atomic(void)
983 : : {
984 : : /* Ingress event order test */
985 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_ORDERED,
986 : : RTE_SCHED_TYPE_ATOMIC);
987 : : }
988 : :
989 : : static int
990 : 0 : test_multi_port_flow_ordered_to_ordered(void)
991 : : {
992 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_ORDERED,
993 : : RTE_SCHED_TYPE_ORDERED);
994 : : }
995 : :
996 : : static int
997 : 0 : test_multi_port_flow_ordered_to_parallel(void)
998 : : {
999 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_ORDERED,
1000 : : RTE_SCHED_TYPE_PARALLEL);
1001 : : }
1002 : :
1003 : : static int
1004 : 0 : test_multi_port_flow_atomic_to_atomic(void)
1005 : : {
1006 : : /* Ingress event order test */
1007 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_ATOMIC,
1008 : : RTE_SCHED_TYPE_ATOMIC);
1009 : : }
1010 : :
1011 : : static int
1012 : 0 : test_multi_port_flow_atomic_to_ordered(void)
1013 : : {
1014 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_ATOMIC,
1015 : : RTE_SCHED_TYPE_ORDERED);
1016 : : }
1017 : :
1018 : : static int
1019 : 0 : test_multi_port_flow_atomic_to_parallel(void)
1020 : : {
1021 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_ATOMIC,
1022 : : RTE_SCHED_TYPE_PARALLEL);
1023 : : }
1024 : :
1025 : : static int
1026 : 0 : test_multi_port_flow_parallel_to_atomic(void)
1027 : : {
1028 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_PARALLEL,
1029 : : RTE_SCHED_TYPE_ATOMIC);
1030 : : }
1031 : :
1032 : : static int
1033 : 0 : test_multi_port_flow_parallel_to_ordered(void)
1034 : : {
1035 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_PARALLEL,
1036 : : RTE_SCHED_TYPE_ORDERED);
1037 : : }
1038 : :
1039 : : static int
1040 : 0 : test_multi_port_flow_parallel_to_parallel(void)
1041 : : {
1042 : 0 : return test_multiport_flow_sched_type_test(RTE_SCHED_TYPE_PARALLEL,
1043 : : RTE_SCHED_TYPE_PARALLEL);
1044 : : }
1045 : :
1046 : : static int
1047 : 0 : worker_group_based_pipeline(void *arg)
1048 : : {
1049 : : struct test_core_param *param = arg;
1050 : 0 : uint64_t dequeue_tmo_ticks = param->dequeue_tmo_ticks;
1051 : 0 : uint32_t __rte_atomic *total_events = param->total_events;
1052 : 0 : uint8_t new_sched_type = param->sched_type;
1053 : 0 : uint8_t port = param->port;
1054 : : uint16_t valid_event;
1055 : : struct rte_event ev;
1056 : :
1057 [ # # ]: 0 : while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
1058 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1,
1059 : : dequeue_tmo_ticks);
1060 [ # # ]: 0 : if (!valid_event)
1061 : 0 : continue;
1062 : :
1063 : : /* Events from stage 0(group 0) */
1064 [ # # ]: 0 : if (ev.queue_id == 0) {
1065 : : /* Move to atomic flow to maintain the ordering */
1066 : 0 : ev.flow_id = 0x2;
1067 : 0 : ev.event_type = RTE_EVENT_TYPE_CPU;
1068 : 0 : ev.sched_type = new_sched_type;
1069 : 0 : ev.queue_id = 1; /* Stage 1*/
1070 : 0 : ev.op = RTE_EVENT_OP_FORWARD;
1071 : 0 : rte_event_enqueue_burst(evdev, port, &ev, 1);
1072 [ # # ]: 0 : } else if (ev.queue_id == 1) { /* Events from stage 1(group 1)*/
1073 [ # # ]: 0 : uint32_t seqn = *rte_event_pmd_selftest_seqn(ev.mbuf);
1074 : :
1075 [ # # ]: 0 : if (seqn_list_update(seqn) == 0) {
1076 : 0 : rte_pktmbuf_free(ev.mbuf);
1077 : 0 : rte_atomic_fetch_sub_explicit(total_events, 1,
1078 : : rte_memory_order_relaxed);
1079 : : } else {
1080 : 0 : plt_err("Failed to update seqn_list");
1081 : 0 : return -1;
1082 : : }
1083 : : } else {
1084 : 0 : plt_err("Invalid ev.queue_id = %d", ev.queue_id);
1085 : 0 : return -1;
1086 : : }
1087 : : }
1088 : :
1089 : : return 0;
1090 : : }
1091 : :
1092 : : static int
1093 : 0 : test_multiport_queue_sched_type_test(uint8_t in_sched_type,
1094 : : uint8_t out_sched_type)
1095 : : {
1096 : : const unsigned int total_events = MAX_EVENTS;
1097 : : uint32_t queue_count;
1098 : : uint32_t nr_ports;
1099 : : int ret;
1100 : :
1101 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
1102 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
1103 : : &nr_ports),
1104 : : "Port count get failed");
1105 : :
1106 : 0 : nr_ports = RTE_MIN(nr_ports, rte_lcore_count() - 1);
1107 : :
1108 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
1109 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
1110 : : &queue_count),
1111 : : "Queue count get failed");
1112 [ # # # # ]: 0 : if (queue_count < 2 || !nr_ports) {
1113 : 0 : plt_err("Not enough queues=%d ports=%d or workers=%d",
1114 : : queue_count, nr_ports, rte_lcore_count() - 1);
1115 : 0 : return 0;
1116 : : }
1117 : :
1118 : : /* Injects events with a 0 sequence number to total_events */
1119 : 0 : ret = inject_events(
1120 : : 0x1 /*flow_id */, RTE_EVENT_TYPE_CPU /* event_type */,
1121 : : 0 /* sub_event_type (stage 0) */, in_sched_type, 0 /* queue */,
1122 : : 0 /* port */, total_events /* events */);
1123 [ # # ]: 0 : if (ret)
1124 : : return -1;
1125 : :
1126 : 0 : ret = launch_workers_and_wait(worker_group_based_pipeline,
1127 : : worker_group_based_pipeline, total_events,
1128 : : nr_ports, out_sched_type);
1129 [ # # ]: 0 : if (ret)
1130 : : return -1;
1131 : :
1132 : 0 : if (in_sched_type != RTE_SCHED_TYPE_PARALLEL &&
1133 [ # # ]: 0 : out_sched_type == RTE_SCHED_TYPE_ATOMIC) {
1134 : : /* Check the events order maintained or not */
1135 : 0 : return seqn_list_check(total_events);
1136 : : }
1137 : :
1138 : : return 0;
1139 : : }
1140 : :
1141 : : static int
1142 : 0 : test_multi_port_queue_ordered_to_atomic(void)
1143 : : {
1144 : : /* Ingress event order test */
1145 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_ORDERED,
1146 : : RTE_SCHED_TYPE_ATOMIC);
1147 : : }
1148 : :
1149 : : static int
1150 : 0 : test_multi_port_queue_ordered_to_ordered(void)
1151 : : {
1152 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_ORDERED,
1153 : : RTE_SCHED_TYPE_ORDERED);
1154 : : }
1155 : :
1156 : : static int
1157 : 0 : test_multi_port_queue_ordered_to_parallel(void)
1158 : : {
1159 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_ORDERED,
1160 : : RTE_SCHED_TYPE_PARALLEL);
1161 : : }
1162 : :
1163 : : static int
1164 : 0 : test_multi_port_queue_atomic_to_atomic(void)
1165 : : {
1166 : : /* Ingress event order test */
1167 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_ATOMIC,
1168 : : RTE_SCHED_TYPE_ATOMIC);
1169 : : }
1170 : :
1171 : : static int
1172 : 0 : test_multi_port_queue_atomic_to_ordered(void)
1173 : : {
1174 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_ATOMIC,
1175 : : RTE_SCHED_TYPE_ORDERED);
1176 : : }
1177 : :
1178 : : static int
1179 : 0 : test_multi_port_queue_atomic_to_parallel(void)
1180 : : {
1181 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_ATOMIC,
1182 : : RTE_SCHED_TYPE_PARALLEL);
1183 : : }
1184 : :
1185 : : static int
1186 : 0 : test_multi_port_queue_parallel_to_atomic(void)
1187 : : {
1188 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_PARALLEL,
1189 : : RTE_SCHED_TYPE_ATOMIC);
1190 : : }
1191 : :
1192 : : static int
1193 : 0 : test_multi_port_queue_parallel_to_ordered(void)
1194 : : {
1195 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_PARALLEL,
1196 : : RTE_SCHED_TYPE_ORDERED);
1197 : : }
1198 : :
1199 : : static int
1200 : 0 : test_multi_port_queue_parallel_to_parallel(void)
1201 : : {
1202 : 0 : return test_multiport_queue_sched_type_test(RTE_SCHED_TYPE_PARALLEL,
1203 : : RTE_SCHED_TYPE_PARALLEL);
1204 : : }
1205 : :
1206 : : static int
1207 : 0 : worker_flow_based_pipeline_max_stages_rand_sched_type(void *arg)
1208 : : {
1209 : : struct test_core_param *param = arg;
1210 : 0 : uint32_t __rte_atomic *total_events = param->total_events;
1211 : 0 : uint8_t port = param->port;
1212 : : uint16_t valid_event;
1213 : : struct rte_event ev;
1214 : :
1215 [ # # ]: 0 : while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
1216 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
1217 [ # # ]: 0 : if (!valid_event)
1218 : 0 : continue;
1219 : :
1220 [ # # ]: 0 : if (ev.sub_event_type == MAX_STAGES) { /* last stage */
1221 : 0 : rte_pktmbuf_free(ev.mbuf);
1222 : 0 : rte_atomic_fetch_sub_explicit(total_events, 1, rte_memory_order_relaxed);
1223 : : } else {
1224 : 0 : ev.event_type = RTE_EVENT_TYPE_CPU;
1225 : 0 : ev.sub_event_type++;
1226 : 0 : ev.sched_type =
1227 : 0 : rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1);
1228 : 0 : ev.op = RTE_EVENT_OP_FORWARD;
1229 : 0 : rte_event_enqueue_burst(evdev, port, &ev, 1);
1230 : : }
1231 : : }
1232 : :
1233 : 0 : return 0;
1234 : : }
1235 : :
1236 : : static int
1237 : 0 : launch_multi_port_max_stages_random_sched_type(int (*fn)(void *))
1238 : : {
1239 : : uint32_t nr_ports;
1240 : : int ret;
1241 : :
1242 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
1243 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
1244 : : &nr_ports),
1245 : : "Port count get failed");
1246 : 0 : nr_ports = RTE_MIN(nr_ports, rte_lcore_count() - 1);
1247 : :
1248 [ # # ]: 0 : if (!nr_ports) {
1249 : 0 : plt_err("Not enough ports=%d or workers=%d", nr_ports,
1250 : : rte_lcore_count() - 1);
1251 : 0 : return 0;
1252 : : }
1253 : :
1254 : : /* Injects events with a 0 sequence number to total_events */
1255 : 0 : ret = inject_events(
1256 : : 0x1 /*flow_id */, RTE_EVENT_TYPE_CPU /* event_type */,
1257 : : 0 /* sub_event_type (stage 0) */,
1258 : 0 : rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1) /* sched_type */,
1259 : : 0 /* queue */, 0 /* port */, MAX_EVENTS /* events */);
1260 [ # # ]: 0 : if (ret)
1261 : : return -1;
1262 : :
1263 : 0 : return launch_workers_and_wait(fn, fn, MAX_EVENTS, nr_ports,
1264 : : 0xff /* invalid */);
1265 : : }
1266 : :
1267 : : /* Flow based pipeline with maximum stages with random sched type */
1268 : : static int
1269 : 0 : test_multi_port_flow_max_stages_random_sched_type(void)
1270 : : {
1271 : 0 : return launch_multi_port_max_stages_random_sched_type(
1272 : : worker_flow_based_pipeline_max_stages_rand_sched_type);
1273 : : }
1274 : :
1275 : : static int
1276 : 0 : worker_queue_based_pipeline_max_stages_rand_sched_type(void *arg)
1277 : : {
1278 : : struct test_core_param *param = arg;
1279 : 0 : uint8_t port = param->port;
1280 : : uint32_t queue_count;
1281 : : uint16_t valid_event;
1282 : : struct rte_event ev;
1283 : :
1284 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
1285 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
1286 : : &queue_count),
1287 : : "Queue count get failed");
1288 : 0 : uint8_t nr_queues = queue_count;
1289 : 0 : uint32_t __rte_atomic *total_events = param->total_events;
1290 : :
1291 [ # # ]: 0 : while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
1292 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
1293 [ # # ]: 0 : if (!valid_event)
1294 : 0 : continue;
1295 : :
1296 [ # # ]: 0 : if (ev.queue_id == nr_queues - 1) { /* last stage */
1297 : 0 : rte_pktmbuf_free(ev.mbuf);
1298 : 0 : rte_atomic_fetch_sub_explicit(total_events, 1, rte_memory_order_relaxed);
1299 : : } else {
1300 : 0 : ev.event_type = RTE_EVENT_TYPE_CPU;
1301 : 0 : ev.queue_id++;
1302 : 0 : ev.sched_type =
1303 : 0 : rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1);
1304 : 0 : ev.op = RTE_EVENT_OP_FORWARD;
1305 : 0 : rte_event_enqueue_burst(evdev, port, &ev, 1);
1306 : : }
1307 : : }
1308 : :
1309 : : return 0;
1310 : : }
1311 : :
1312 : : /* Queue based pipeline with maximum stages with random sched type */
1313 : : static int
1314 : 0 : test_multi_port_queue_max_stages_random_sched_type(void)
1315 : : {
1316 : 0 : return launch_multi_port_max_stages_random_sched_type(
1317 : : worker_queue_based_pipeline_max_stages_rand_sched_type);
1318 : : }
1319 : :
1320 : : static int
1321 : 0 : worker_mixed_pipeline_max_stages_rand_sched_type(void *arg)
1322 : : {
1323 : : struct test_core_param *param = arg;
1324 : 0 : uint8_t port = param->port;
1325 : : uint32_t queue_count;
1326 : : uint16_t valid_event;
1327 : : struct rte_event ev;
1328 : :
1329 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
1330 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
1331 : : &queue_count),
1332 : : "Queue count get failed");
1333 : 0 : uint8_t nr_queues = queue_count;
1334 : 0 : uint32_t __rte_atomic *total_events = param->total_events;
1335 : :
1336 [ # # ]: 0 : while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
1337 : 0 : valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
1338 [ # # ]: 0 : if (!valid_event)
1339 : 0 : continue;
1340 : :
1341 [ # # ]: 0 : if (ev.queue_id == nr_queues - 1) { /* Last stage */
1342 : 0 : rte_pktmbuf_free(ev.mbuf);
1343 : 0 : rte_atomic_fetch_sub_explicit(total_events, 1, rte_memory_order_relaxed);
1344 : : } else {
1345 : 0 : ev.event_type = RTE_EVENT_TYPE_CPU;
1346 : 0 : ev.queue_id++;
1347 : 0 : ev.sub_event_type = rte_rand() % 256;
1348 : 0 : ev.sched_type =
1349 : 0 : rte_rand() % (RTE_SCHED_TYPE_PARALLEL + 1);
1350 : 0 : ev.op = RTE_EVENT_OP_FORWARD;
1351 : 0 : rte_event_enqueue_burst(evdev, port, &ev, 1);
1352 : : }
1353 : : }
1354 : :
1355 : : return 0;
1356 : : }
1357 : :
1358 : : /* Queue and flow based pipeline with maximum stages with random sched type */
1359 : : static int
1360 : 0 : test_multi_port_mixed_max_stages_random_sched_type(void)
1361 : : {
1362 : 0 : return launch_multi_port_max_stages_random_sched_type(
1363 : : worker_mixed_pipeline_max_stages_rand_sched_type);
1364 : : }
1365 : :
1366 : : static int
1367 : 0 : worker_ordered_flow_producer(void *arg)
1368 : : {
1369 : : struct test_core_param *param = arg;
1370 : 0 : uint8_t port = param->port;
1371 : : struct rte_mbuf *m;
1372 : : int counter = 0;
1373 : :
1374 [ # # ]: 0 : while (counter < NUM_PACKETS) {
1375 : 0 : m = rte_pktmbuf_alloc(eventdev_test_mempool);
1376 [ # # ]: 0 : if (m == NULL)
1377 : 0 : continue;
1378 : :
1379 : 0 : *rte_event_pmd_selftest_seqn(m) = counter++;
1380 : :
1381 : 0 : struct rte_event ev = {.event = 0, .u64 = 0};
1382 : :
1383 : 0 : ev.flow_id = 0x1; /* Generate a fat flow */
1384 : : ev.sub_event_type = 0;
1385 : : /* Inject the new event */
1386 : : ev.op = RTE_EVENT_OP_NEW;
1387 : 0 : ev.event_type = RTE_EVENT_TYPE_CPU;
1388 : : ev.sched_type = RTE_SCHED_TYPE_ORDERED;
1389 : : ev.queue_id = 0;
1390 : 0 : ev.mbuf = m;
1391 : 0 : rte_event_enqueue_burst(evdev, port, &ev, 1);
1392 : : }
1393 : :
1394 : 0 : return 0;
1395 : : }
1396 : :
1397 : : static inline int
1398 : 0 : test_producer_consumer_ingress_order_test(int (*fn)(void *))
1399 : : {
1400 : : uint32_t nr_ports;
1401 : :
1402 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(
1403 : : rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
1404 : : &nr_ports),
1405 : : "Port count get failed");
1406 : 0 : nr_ports = RTE_MIN(nr_ports, rte_lcore_count() - 1);
1407 : :
1408 [ # # # # ]: 0 : if (rte_lcore_count() < 3 || nr_ports < 2) {
1409 : 0 : plt_err("### Not enough cores for test.");
1410 : 0 : return 0;
1411 : : }
1412 : :
1413 : 0 : launch_workers_and_wait(worker_ordered_flow_producer, fn, NUM_PACKETS,
1414 : : nr_ports, RTE_SCHED_TYPE_ATOMIC);
1415 : : /* Check the events order maintained or not */
1416 : 0 : return seqn_list_check(NUM_PACKETS);
1417 : : }
1418 : :
1419 : : /* Flow based producer consumer ingress order test */
1420 : : static int
1421 : 0 : test_flow_producer_consumer_ingress_order_test(void)
1422 : : {
1423 : 0 : return test_producer_consumer_ingress_order_test(
1424 : : worker_flow_based_pipeline);
1425 : : }
1426 : :
1427 : : /* Queue based producer consumer ingress order test */
1428 : : static int
1429 : 0 : test_queue_producer_consumer_ingress_order_test(void)
1430 : : {
1431 : 0 : return test_producer_consumer_ingress_order_test(
1432 : : worker_group_based_pipeline);
1433 : : }
1434 : :
1435 : : static void
1436 : 0 : cnxk_test_run(int (*setup)(void), void (*tdown)(void), int (*test)(void),
1437 : : const char *name)
1438 : : {
1439 [ # # ]: 0 : if (setup() < 0) {
1440 : : printf("Error setting up test %s", name);
1441 : 0 : unsupported++;
1442 : : } else {
1443 [ # # ]: 0 : if (test() < 0) {
1444 : 0 : failed++;
1445 : 0 : printf("+ TestCase [%2d] : %s failed\n", total, name);
1446 : : } else {
1447 : 0 : passed++;
1448 : 0 : printf("+ TestCase [%2d] : %s succeeded\n", total,
1449 : : name);
1450 : : }
1451 : : }
1452 : :
1453 : 0 : total++;
1454 : 0 : tdown();
1455 : 0 : }
1456 : :
1457 : : static int
1458 : 0 : cnxk_sso_testsuite_run(const char *dev_name)
1459 : : {
1460 : : int rc;
1461 : :
1462 : 0 : testsuite_setup(dev_name);
1463 : :
1464 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1465 : : test_simple_enqdeq_ordered);
1466 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1467 : : test_simple_enqdeq_atomic);
1468 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1469 : : test_simple_enqdeq_parallel);
1470 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1471 : : test_multi_queue_enq_single_port_deq);
1472 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown, test_dev_stop_flush);
1473 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1474 : : test_multi_queue_enq_multi_port_deq);
1475 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1476 : : test_queue_to_port_single_link);
1477 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1478 : : test_queue_to_port_multi_link);
1479 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1480 : : test_multi_port_flow_ordered_to_atomic);
1481 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1482 : : test_multi_port_flow_ordered_to_ordered);
1483 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1484 : : test_multi_port_flow_ordered_to_parallel);
1485 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1486 : : test_multi_port_flow_atomic_to_atomic);
1487 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1488 : : test_multi_port_flow_atomic_to_ordered);
1489 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1490 : : test_multi_port_flow_atomic_to_parallel);
1491 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1492 : : test_multi_port_flow_parallel_to_atomic);
1493 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1494 : : test_multi_port_flow_parallel_to_ordered);
1495 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1496 : : test_multi_port_flow_parallel_to_parallel);
1497 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1498 : : test_multi_port_queue_ordered_to_atomic);
1499 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1500 : : test_multi_port_queue_ordered_to_ordered);
1501 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1502 : : test_multi_port_queue_ordered_to_parallel);
1503 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1504 : : test_multi_port_queue_atomic_to_atomic);
1505 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1506 : : test_multi_port_queue_atomic_to_ordered);
1507 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1508 : : test_multi_port_queue_atomic_to_parallel);
1509 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1510 : : test_multi_port_queue_parallel_to_atomic);
1511 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1512 : : test_multi_port_queue_parallel_to_ordered);
1513 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1514 : : test_multi_port_queue_parallel_to_parallel);
1515 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1516 : : test_multi_port_flow_max_stages_random_sched_type);
1517 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1518 : : test_multi_port_queue_max_stages_random_sched_type);
1519 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1520 : : test_multi_port_mixed_max_stages_random_sched_type);
1521 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1522 : : test_flow_producer_consumer_ingress_order_test);
1523 : 0 : CNXK_TEST_RUN(eventdev_setup, eventdev_teardown,
1524 : : test_queue_producer_consumer_ingress_order_test);
1525 : 0 : CNXK_TEST_RUN(eventdev_setup_priority, eventdev_teardown,
1526 : : test_multi_queue_priority);
1527 : 0 : CNXK_TEST_RUN(eventdev_setup_dequeue_timeout, eventdev_teardown,
1528 : : test_multi_port_flow_ordered_to_atomic);
1529 : 0 : CNXK_TEST_RUN(eventdev_setup_dequeue_timeout, eventdev_teardown,
1530 : : test_multi_port_queue_ordered_to_atomic);
1531 : 0 : printf("Total tests : %d\n", total);
1532 : 0 : printf("Passed : %d\n", passed);
1533 : 0 : printf("Failed : %d\n", failed);
1534 : 0 : printf("Not supported : %d\n", unsupported);
1535 : :
1536 : 0 : rc = failed;
1537 : : testsuite_teardown();
1538 : :
1539 : 0 : return rc;
1540 : : }
1541 : :
1542 : : int
1543 : 0 : cnxk_sso_selftest(const char *dev_name)
1544 : : {
1545 : : const struct rte_memzone *mz;
1546 : : struct cnxk_sso_evdev *dev;
1547 : : int rc = -1;
1548 : :
1549 : 0 : mz = rte_memzone_lookup(CNXK_SSO_MZ_NAME);
1550 [ # # ]: 0 : if (mz == NULL)
1551 : : return rc;
1552 : :
1553 [ # # ]: 0 : dev = (void *)*((uint64_t *)mz->addr);
1554 [ # # ]: 0 : if (roc_model_runtime_is_cn9k()) {
1555 : : /* Verify single ws mode. */
1556 : : printf("Verifying CN9K Single workslot mode\n");
1557 : 0 : dev->dual_ws = 0;
1558 : 0 : cn9k_sso_set_rsrc(dev);
1559 [ # # ]: 0 : if (cnxk_sso_testsuite_run(dev_name))
1560 : : return rc;
1561 : : /* Verify dual ws mode. */
1562 : : printf("Verifying CN9K Dual workslot mode\n");
1563 : 0 : dev->dual_ws = 1;
1564 : 0 : cn9k_sso_set_rsrc(dev);
1565 [ # # ]: 0 : if (cnxk_sso_testsuite_run(dev_name))
1566 : : return rc;
1567 : : }
1568 : :
1569 [ # # # # ]: 0 : if (roc_model_runtime_is_cn10k() || roc_model_runtime_is_cn20k()) {
1570 : : printf("Verifying %s workslot getwork mode none\n", dev_name);
1571 : 0 : dev->gw_mode = CNXK_GW_MODE_NONE;
1572 [ # # ]: 0 : if (cnxk_sso_testsuite_run(dev_name))
1573 : : return rc;
1574 : : printf("Verifying %s workslot getwork mode prefetch\n", dev_name);
1575 : 0 : dev->gw_mode = CNXK_GW_MODE_PREF;
1576 [ # # ]: 0 : if (cnxk_sso_testsuite_run(dev_name))
1577 : : return rc;
1578 : : printf("Verifying %s workslot getwork mode smart prefetch\n", dev_name);
1579 : 0 : dev->gw_mode = CNXK_GW_MODE_PREF_WFE;
1580 [ # # ]: 0 : if (cnxk_sso_testsuite_run(dev_name))
1581 : 0 : return rc;
1582 : : }
1583 : :
1584 : : return 0;
1585 : : }
|