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