Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2017 Cavium, Inc.
3 : : */
4 : :
5 : : #include "test_pipeline_common.h"
6 : :
7 : : /* See http://doc.dpdk.org/guides/tools/testeventdev.html for test details */
8 : :
9 : : static __rte_always_inline int
10 : : pipeline_atq_nb_event_queues(struct evt_options *opt)
11 : : {
12 : : RTE_SET_USED(opt);
13 : :
14 : 0 : return rte_eth_dev_count_avail();
15 : : }
16 : :
17 : : typedef int (*pipeline_atq_worker_t)(void *arg);
18 : :
19 : : static __rte_noinline int
20 : 0 : pipeline_atq_worker_single_stage_tx(void *arg)
21 : : {
22 : 0 : PIPELINE_WORKER_SINGLE_STAGE_INIT;
23 : : uint8_t enq = 0, deq = 0;
24 : :
25 : 0 : while (t->done == false) {
26 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
27 : :
28 : 0 : if (!deq) {
29 : : rte_pause();
30 : 0 : continue;
31 : : }
32 : :
33 : : deq = pipeline_event_tx(dev, port, &ev, t);
34 : 0 : w->processed_pkts++;
35 : : }
36 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
37 : :
38 : 0 : return 0;
39 : : }
40 : :
41 : : static __rte_noinline int
42 : 0 : pipeline_atq_worker_single_stage_fwd(void *arg)
43 : : {
44 : 0 : PIPELINE_WORKER_SINGLE_STAGE_INIT;
45 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
46 : : uint8_t enq = 0, deq = 0;
47 : :
48 : 0 : while (t->done == false) {
49 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
50 : :
51 : 0 : if (!deq) {
52 : : rte_pause();
53 : 0 : continue;
54 : : }
55 : :
56 : 0 : ev.queue_id = tx_queue[ev.mbuf->port];
57 : : pipeline_fwd_event(&ev, RTE_SCHED_TYPE_ATOMIC);
58 : : enq = pipeline_event_enqueue(dev, port, &ev, t);
59 : 0 : w->processed_pkts++;
60 : : }
61 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
62 : :
63 : 0 : return 0;
64 : : }
65 : :
66 : : static __rte_noinline int
67 : 0 : pipeline_atq_worker_single_stage_burst_tx(void *arg)
68 : : {
69 : 0 : PIPELINE_WORKER_SINGLE_STAGE_BURST_INIT;
70 : : uint16_t nb_rx = 0, nb_tx = 0;
71 : :
72 : 0 : while (t->done == false) {
73 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
74 : :
75 : 0 : if (!nb_rx) {
76 : : rte_pause();
77 : 0 : continue;
78 : : }
79 : :
80 : 0 : for (i = 0; i < nb_rx; i++) {
81 : 0 : rte_prefetch0(ev[i + 1].mbuf);
82 : 0 : rte_event_eth_tx_adapter_txq_set(ev[i].mbuf, 0);
83 : : }
84 : :
85 : : nb_tx = pipeline_event_tx_burst(dev, port, ev, nb_rx, t);
86 : 0 : w->processed_pkts += nb_tx;
87 : : }
88 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
89 : :
90 : 0 : return 0;
91 : : }
92 : :
93 : : static __rte_noinline int
94 : 0 : pipeline_atq_worker_single_stage_burst_fwd(void *arg)
95 : : {
96 : 0 : PIPELINE_WORKER_SINGLE_STAGE_BURST_INIT;
97 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
98 : : uint16_t nb_rx = 0, nb_tx = 0;
99 : :
100 : 0 : while (t->done == false) {
101 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
102 : :
103 : 0 : if (!nb_rx) {
104 : : rte_pause();
105 : 0 : continue;
106 : : }
107 : :
108 : 0 : for (i = 0; i < nb_rx; i++) {
109 : 0 : rte_prefetch0(ev[i + 1].mbuf);
110 : 0 : rte_event_eth_tx_adapter_txq_set(ev[i].mbuf, 0);
111 : 0 : ev[i].queue_id = tx_queue[ev[i].mbuf->port];
112 : : pipeline_fwd_event(&ev[i], RTE_SCHED_TYPE_ATOMIC);
113 : : }
114 : :
115 : : nb_tx = pipeline_event_enqueue_burst(dev, port, ev, nb_rx, t);
116 : 0 : w->processed_pkts += nb_tx;
117 : : }
118 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
119 : :
120 : 0 : return 0;
121 : : }
122 : :
123 : : static __rte_noinline int
124 : 0 : pipeline_atq_worker_single_stage_tx_vector(void *arg)
125 : : {
126 : 0 : PIPELINE_WORKER_SINGLE_STAGE_INIT;
127 : : uint8_t enq = 0, deq = 0;
128 : : uint16_t vector_sz;
129 : :
130 : 0 : while (!t->done) {
131 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
132 : :
133 : 0 : if (!deq) {
134 : : rte_pause();
135 : 0 : continue;
136 : : }
137 : 0 : vector_sz = ev.vec->nb_elem;
138 : : enq = pipeline_event_tx_vector(dev, port, &ev, t);
139 : 0 : w->processed_pkts += vector_sz;
140 : : }
141 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
142 : :
143 : 0 : return 0;
144 : : }
145 : :
146 : : static __rte_noinline int
147 : 0 : pipeline_atq_worker_single_stage_fwd_vector(void *arg)
148 : : {
149 : 0 : PIPELINE_WORKER_SINGLE_STAGE_INIT;
150 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
151 : : uint8_t enq = 0, deq = 0;
152 : : uint16_t vector_sz;
153 : :
154 : 0 : while (!t->done) {
155 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
156 : :
157 : 0 : if (!deq) {
158 : : rte_pause();
159 : 0 : continue;
160 : : }
161 : :
162 : 0 : vector_sz = ev.vec->nb_elem;
163 : 0 : ev.queue_id = tx_queue[ev.vec->port];
164 : 0 : ev.vec->queue = 0;
165 : : pipeline_fwd_event_vector(&ev, RTE_SCHED_TYPE_ATOMIC);
166 : : enq = pipeline_event_enqueue(dev, port, &ev, t);
167 : 0 : w->processed_pkts += vector_sz;
168 : : }
169 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
170 : :
171 : 0 : return 0;
172 : : }
173 : :
174 : : static __rte_noinline int
175 : 0 : pipeline_atq_worker_single_stage_burst_tx_vector(void *arg)
176 : : {
177 : 0 : PIPELINE_WORKER_SINGLE_STAGE_BURST_INIT;
178 : : uint16_t nb_rx = 0, nb_tx = 0;
179 : : uint16_t vector_sz;
180 : :
181 : 0 : while (!t->done) {
182 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
183 : :
184 : 0 : if (!nb_rx) {
185 : : rte_pause();
186 : 0 : continue;
187 : : }
188 : : vector_sz = 0;
189 : 0 : for (i = 0; i < nb_rx; i++) {
190 : 0 : vector_sz += ev[i].vec->nb_elem;
191 : 0 : ev[i].vec->queue = 0;
192 : : }
193 : :
194 : : nb_tx = pipeline_event_tx_burst(dev, port, ev, nb_rx, t);
195 : 0 : w->processed_pkts += vector_sz;
196 : : }
197 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
198 : :
199 : 0 : return 0;
200 : : }
201 : :
202 : : static __rte_noinline int
203 : 0 : pipeline_atq_worker_single_stage_burst_fwd_vector(void *arg)
204 : : {
205 : 0 : PIPELINE_WORKER_SINGLE_STAGE_BURST_INIT;
206 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
207 : : uint16_t nb_rx = 0, nb_tx = 0;
208 : : uint16_t vector_sz;
209 : :
210 : 0 : while (!t->done) {
211 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
212 : :
213 : 0 : if (!nb_rx) {
214 : : rte_pause();
215 : 0 : continue;
216 : : }
217 : :
218 : : vector_sz = 0;
219 : 0 : for (i = 0; i < nb_rx; i++) {
220 : 0 : ev[i].queue_id = tx_queue[ev[i].vec->port];
221 : 0 : ev[i].vec->queue = 0;
222 : 0 : vector_sz += ev[i].vec->nb_elem;
223 : : pipeline_fwd_event_vector(&ev[i],
224 : : RTE_SCHED_TYPE_ATOMIC);
225 : : }
226 : :
227 : : nb_tx = pipeline_event_enqueue_burst(dev, port, ev, nb_rx, t);
228 : 0 : w->processed_pkts += vector_sz;
229 : : }
230 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
231 : :
232 : 0 : return 0;
233 : : }
234 : :
235 : : static __rte_noinline int
236 : 0 : pipeline_atq_worker_multi_stage_tx(void *arg)
237 : : {
238 : 0 : PIPELINE_WORKER_MULTI_STAGE_INIT;
239 : : uint8_t enq = 0, deq = 0;
240 : :
241 : 0 : while (t->done == false) {
242 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
243 : :
244 : 0 : if (!deq) {
245 : : rte_pause();
246 : 0 : continue;
247 : : }
248 : :
249 : 0 : cq_id = ev.sub_event_type % nb_stages;
250 : :
251 : 0 : if (cq_id == last_queue) {
252 : : enq = pipeline_event_tx(dev, port, &ev, t);
253 : 0 : w->processed_pkts++;
254 : 0 : continue;
255 : : }
256 : :
257 : 0 : ev.sub_event_type++;
258 : 0 : pipeline_fwd_event(&ev, sched_type_list[cq_id]);
259 : : enq = pipeline_event_enqueue(dev, port, &ev, t);
260 : : }
261 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
262 : :
263 : 0 : return 0;
264 : : }
265 : :
266 : : static __rte_noinline int
267 : 0 : pipeline_atq_worker_multi_stage_fwd(void *arg)
268 : : {
269 : 0 : PIPELINE_WORKER_MULTI_STAGE_INIT;
270 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
271 : : uint8_t enq = 0, deq = 0;
272 : :
273 : 0 : while (t->done == false) {
274 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
275 : :
276 : 0 : if (!deq) {
277 : : rte_pause();
278 : 0 : continue;
279 : : }
280 : :
281 : 0 : cq_id = ev.sub_event_type % nb_stages;
282 : :
283 : 0 : if (cq_id == last_queue) {
284 : 0 : ev.queue_id = tx_queue[ev.mbuf->port];
285 : : pipeline_fwd_event(&ev, RTE_SCHED_TYPE_ATOMIC);
286 : 0 : w->processed_pkts++;
287 : : } else {
288 : 0 : ev.sub_event_type++;
289 : 0 : pipeline_fwd_event(&ev, sched_type_list[cq_id]);
290 : : }
291 : :
292 : : enq = pipeline_event_enqueue(dev, port, &ev, t);
293 : : }
294 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
295 : :
296 : 0 : return 0;
297 : : }
298 : :
299 : : static __rte_noinline int
300 : 0 : pipeline_atq_worker_multi_stage_burst_tx(void *arg)
301 : : {
302 : 0 : PIPELINE_WORKER_MULTI_STAGE_BURST_INIT;
303 : : uint16_t nb_rx = 0, nb_tx = 0;
304 : :
305 : 0 : while (t->done == false) {
306 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
307 : :
308 : 0 : if (!nb_rx) {
309 : : rte_pause();
310 : 0 : continue;
311 : : }
312 : :
313 : 0 : for (i = 0; i < nb_rx; i++) {
314 : 0 : rte_prefetch0(ev[i + 1].mbuf);
315 : 0 : cq_id = ev[i].sub_event_type % nb_stages;
316 : :
317 : 0 : if (cq_id == last_queue) {
318 : 0 : pipeline_event_tx(dev, port, &ev[i], t);
319 : 0 : ev[i].op = RTE_EVENT_OP_RELEASE;
320 : 0 : w->processed_pkts++;
321 : 0 : continue;
322 : : }
323 : :
324 : 0 : ev[i].sub_event_type++;
325 : 0 : pipeline_fwd_event(&ev[i], sched_type_list[cq_id]);
326 : : }
327 : :
328 : : nb_tx = pipeline_event_enqueue_burst(dev, port, ev, nb_rx, t);
329 : : }
330 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
331 : :
332 : 0 : return 0;
333 : : }
334 : :
335 : : static __rte_noinline int
336 : 0 : pipeline_atq_worker_multi_stage_burst_fwd(void *arg)
337 : : {
338 : 0 : PIPELINE_WORKER_MULTI_STAGE_BURST_INIT;
339 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
340 : : uint16_t nb_rx = 0, nb_tx = 0;
341 : :
342 : 0 : while (t->done == false) {
343 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
344 : :
345 : 0 : if (!nb_rx) {
346 : : rte_pause();
347 : 0 : continue;
348 : : }
349 : :
350 : 0 : for (i = 0; i < nb_rx; i++) {
351 : 0 : rte_prefetch0(ev[i + 1].mbuf);
352 : 0 : cq_id = ev[i].sub_event_type % nb_stages;
353 : :
354 : 0 : if (cq_id == last_queue) {
355 : 0 : w->processed_pkts++;
356 : 0 : ev[i].queue_id = tx_queue[ev[i].mbuf->port];
357 : : pipeline_fwd_event(&ev[i],
358 : : RTE_SCHED_TYPE_ATOMIC);
359 : : } else {
360 : 0 : ev[i].sub_event_type++;
361 : : pipeline_fwd_event(&ev[i],
362 : 0 : sched_type_list[cq_id]);
363 : : }
364 : : }
365 : :
366 : : nb_tx = pipeline_event_enqueue_burst(dev, port, ev, nb_rx, t);
367 : : }
368 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
369 : :
370 : 0 : return 0;
371 : : }
372 : :
373 : : static __rte_noinline int
374 : 0 : pipeline_atq_worker_multi_stage_tx_vector(void *arg)
375 : : {
376 : 0 : PIPELINE_WORKER_MULTI_STAGE_INIT;
377 : : uint8_t enq = 0, deq = 0;
378 : : uint16_t vector_sz;
379 : :
380 : 0 : while (!t->done) {
381 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
382 : :
383 : 0 : if (!deq) {
384 : : rte_pause();
385 : 0 : continue;
386 : : }
387 : :
388 : 0 : cq_id = ev.sub_event_type % nb_stages;
389 : :
390 : 0 : if (cq_id == last_queue) {
391 : 0 : vector_sz = ev.vec->nb_elem;
392 : : enq = pipeline_event_tx_vector(dev, port, &ev, t);
393 : 0 : w->processed_pkts += vector_sz;
394 : 0 : continue;
395 : : }
396 : :
397 : 0 : ev.sub_event_type++;
398 : 0 : pipeline_fwd_event_vector(&ev, sched_type_list[cq_id]);
399 : : enq = pipeline_event_enqueue(dev, port, &ev, t);
400 : : }
401 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
402 : :
403 : 0 : return 0;
404 : : }
405 : :
406 : : static __rte_noinline int
407 : 0 : pipeline_atq_worker_multi_stage_fwd_vector(void *arg)
408 : : {
409 : 0 : PIPELINE_WORKER_MULTI_STAGE_INIT;
410 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
411 : : uint8_t enq = 0, deq = 0;
412 : : uint16_t vector_sz;
413 : :
414 : 0 : while (!t->done) {
415 : 0 : deq = rte_event_dequeue_burst(dev, port, &ev, 1, 0);
416 : :
417 : 0 : if (!deq) {
418 : : rte_pause();
419 : 0 : continue;
420 : : }
421 : :
422 : 0 : cq_id = ev.sub_event_type % nb_stages;
423 : :
424 : 0 : if (cq_id == last_queue) {
425 : 0 : ev.queue_id = tx_queue[ev.vec->port];
426 : 0 : ev.vec->queue = 0;
427 : 0 : vector_sz = ev.vec->nb_elem;
428 : : pipeline_fwd_event_vector(&ev, RTE_SCHED_TYPE_ATOMIC);
429 : : enq = pipeline_event_enqueue(dev, port, &ev, t);
430 : 0 : w->processed_pkts += vector_sz;
431 : : } else {
432 : 0 : ev.sub_event_type++;
433 : 0 : pipeline_fwd_event_vector(&ev, sched_type_list[cq_id]);
434 : : enq = pipeline_event_enqueue(dev, port, &ev, t);
435 : : }
436 : : }
437 : 0 : pipeline_worker_cleanup(dev, port, &ev, enq, deq);
438 : :
439 : 0 : return 0;
440 : : }
441 : :
442 : : static __rte_noinline int
443 : 0 : pipeline_atq_worker_multi_stage_burst_tx_vector(void *arg)
444 : : {
445 : 0 : PIPELINE_WORKER_MULTI_STAGE_BURST_INIT;
446 : : uint16_t nb_rx = 0, nb_tx = 0;
447 : : uint16_t vector_sz;
448 : :
449 : 0 : while (!t->done) {
450 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
451 : :
452 : 0 : if (!nb_rx) {
453 : : rte_pause();
454 : 0 : continue;
455 : : }
456 : :
457 : 0 : for (i = 0; i < nb_rx; i++) {
458 : 0 : cq_id = ev[i].sub_event_type % nb_stages;
459 : :
460 : 0 : if (cq_id == last_queue) {
461 : 0 : vector_sz = ev[i].vec->nb_elem;
462 : 0 : pipeline_event_tx_vector(dev, port, &ev[i], t);
463 : 0 : ev[i].op = RTE_EVENT_OP_RELEASE;
464 : 0 : w->processed_pkts += vector_sz;
465 : 0 : continue;
466 : : }
467 : :
468 : 0 : ev[i].sub_event_type++;
469 : : pipeline_fwd_event_vector(&ev[i],
470 : 0 : sched_type_list[cq_id]);
471 : : }
472 : :
473 : : nb_tx = pipeline_event_enqueue_burst(dev, port, ev, nb_rx, t);
474 : : }
475 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
476 : :
477 : 0 : return 0;
478 : : }
479 : :
480 : : static __rte_noinline int
481 : 0 : pipeline_atq_worker_multi_stage_burst_fwd_vector(void *arg)
482 : : {
483 : 0 : PIPELINE_WORKER_MULTI_STAGE_BURST_INIT;
484 : 0 : const uint8_t *tx_queue = t->tx_evqueue_id;
485 : : uint16_t nb_rx = 0, nb_tx = 0;
486 : : uint16_t vector_sz;
487 : :
488 : 0 : while (!t->done) {
489 : 0 : nb_rx = rte_event_dequeue_burst(dev, port, ev, BURST_SIZE, 0);
490 : :
491 : 0 : if (!nb_rx) {
492 : : rte_pause();
493 : 0 : continue;
494 : : }
495 : :
496 : 0 : for (i = 0; i < nb_rx; i++) {
497 : 0 : cq_id = ev[i].sub_event_type % nb_stages;
498 : :
499 : 0 : if (cq_id == last_queue) {
500 : 0 : vector_sz = ev[i].vec->nb_elem;
501 : 0 : ev[i].queue_id = tx_queue[ev[i].vec->port];
502 : 0 : ev[i].vec->queue = 0;
503 : : pipeline_fwd_event_vector(
504 : : &ev[i], RTE_SCHED_TYPE_ATOMIC);
505 : 0 : w->processed_pkts += vector_sz;
506 : : } else {
507 : 0 : ev[i].sub_event_type++;
508 : : pipeline_fwd_event_vector(
509 : 0 : &ev[i], sched_type_list[cq_id]);
510 : : }
511 : : }
512 : :
513 : : nb_tx = pipeline_event_enqueue_burst(dev, port, ev, nb_rx, t);
514 : : }
515 : 0 : pipeline_worker_cleanup(dev, port, ev, nb_tx, nb_rx);
516 : :
517 : 0 : return 0;
518 : : }
519 : :
520 : : static int
521 : 0 : worker_wrapper(void *arg)
522 : : {
523 : : struct worker_data *w = arg;
524 : 0 : struct evt_options *opt = w->t->opt;
525 : 0 : const bool burst = evt_has_burst_mode(w->dev_id);
526 : 0 : const bool internal_port = w->t->internal_port;
527 : 0 : const uint8_t nb_stages = opt->nb_stages;
528 : : /*vector/burst/internal_port*/
529 : : const pipeline_atq_worker_t
530 : 0 : pipeline_atq_worker_single_stage[2][2][2] = {
531 : : [0][0][0] = pipeline_atq_worker_single_stage_fwd,
532 : : [0][0][1] = pipeline_atq_worker_single_stage_tx,
533 : : [0][1][0] = pipeline_atq_worker_single_stage_burst_fwd,
534 : : [0][1][1] = pipeline_atq_worker_single_stage_burst_tx,
535 : : [1][0][0] = pipeline_atq_worker_single_stage_fwd_vector,
536 : : [1][0][1] = pipeline_atq_worker_single_stage_tx_vector,
537 : : [1][1][0] = pipeline_atq_worker_single_stage_burst_fwd_vector,
538 : : [1][1][1] = pipeline_atq_worker_single_stage_burst_tx_vector,
539 : : };
540 : : const pipeline_atq_worker_t
541 : 0 : pipeline_atq_worker_multi_stage[2][2][2] = {
542 : : [0][0][0] = pipeline_atq_worker_multi_stage_fwd,
543 : : [0][0][1] = pipeline_atq_worker_multi_stage_tx,
544 : : [0][1][0] = pipeline_atq_worker_multi_stage_burst_fwd,
545 : : [0][1][1] = pipeline_atq_worker_multi_stage_burst_tx,
546 : : [1][0][0] = pipeline_atq_worker_multi_stage_fwd_vector,
547 : : [1][0][1] = pipeline_atq_worker_multi_stage_tx_vector,
548 : : [1][1][0] = pipeline_atq_worker_multi_stage_burst_fwd_vector,
549 : : [1][1][1] = pipeline_atq_worker_multi_stage_burst_tx_vector,
550 : : };
551 : :
552 : 0 : if (nb_stages == 1)
553 : 0 : return (pipeline_atq_worker_single_stage[opt->ena_vector][burst]
554 : 0 : [internal_port])(arg);
555 : : else
556 : 0 : return (pipeline_atq_worker_multi_stage[opt->ena_vector][burst]
557 : 0 : [internal_port])(arg);
558 : :
559 : : rte_panic("invalid worker\n");
560 : : }
561 : :
562 : : static int
563 : 0 : pipeline_atq_launch_lcores(struct evt_test *test, struct evt_options *opt)
564 : : {
565 : 0 : return pipeline_launch_lcores(test, opt, worker_wrapper);
566 : : }
567 : :
568 : : static int
569 : 0 : pipeline_atq_eventdev_setup(struct evt_test *test, struct evt_options *opt)
570 : : {
571 : : int ret;
572 : : int nb_ports;
573 : : int nb_queues;
574 : : uint8_t queue, is_prod;
575 : : uint8_t tx_evqueue_id[RTE_MAX_ETHPORTS];
576 : : uint8_t queue_arr[RTE_EVENT_MAX_QUEUES_PER_DEV];
577 : : uint8_t nb_worker_queues = 0;
578 : 0 : uint8_t tx_evport_id = 0;
579 : : uint16_t prod = 0;
580 : : struct rte_event_dev_info info;
581 : : struct test_pipeline *t = evt_test_priv(test);
582 : :
583 : 0 : nb_ports = evt_nr_active_lcores(opt->wlcores);
584 : 0 : nb_queues = rte_eth_dev_count_avail();
585 : :
586 : : memset(tx_evqueue_id, 0, sizeof(uint8_t) * RTE_MAX_ETHPORTS);
587 : : memset(queue_arr, 0, sizeof(uint8_t) * RTE_EVENT_MAX_QUEUES_PER_DEV);
588 : : /* One queue for Tx adapter per port */
589 : 0 : if (!t->internal_port) {
590 : 0 : RTE_ETH_FOREACH_DEV(prod) {
591 : 0 : tx_evqueue_id[prod] = nb_queues;
592 : 0 : nb_queues++;
593 : : }
594 : : }
595 : :
596 : 0 : rte_event_dev_info_get(opt->dev_id, &info);
597 : :
598 : 0 : ret = evt_configure_eventdev(opt, nb_queues, nb_ports);
599 : 0 : if (ret) {
600 : 0 : evt_err("failed to configure eventdev %d", opt->dev_id);
601 : 0 : return ret;
602 : : }
603 : :
604 : 0 : struct rte_event_queue_conf q_conf = {
605 : : .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
606 : 0 : .nb_atomic_flows = opt->nb_flows,
607 : : .nb_atomic_order_sequences = opt->nb_flows,
608 : : };
609 : : /* queue configurations */
610 : 0 : for (queue = 0; queue < nb_queues; queue++) {
611 : 0 : q_conf.event_queue_cfg = RTE_EVENT_QUEUE_CFG_ALL_TYPES;
612 : :
613 : 0 : if (!t->internal_port) {
614 : : is_prod = false;
615 : 0 : RTE_ETH_FOREACH_DEV(prod) {
616 : 0 : if (queue == tx_evqueue_id[prod]) {
617 : 0 : q_conf.event_queue_cfg =
618 : : RTE_EVENT_QUEUE_CFG_SINGLE_LINK;
619 : : is_prod = true;
620 : : break;
621 : : }
622 : : }
623 : : if (!is_prod) {
624 : 0 : queue_arr[nb_worker_queues] = queue;
625 : 0 : nb_worker_queues++;
626 : : }
627 : : }
628 : :
629 : 0 : ret = rte_event_queue_setup(opt->dev_id, queue, &q_conf);
630 : 0 : if (ret) {
631 : 0 : evt_err("failed to setup queue=%d", queue);
632 : 0 : return ret;
633 : : }
634 : : }
635 : :
636 : 0 : if (opt->wkr_deq_dep > info.max_event_port_dequeue_depth)
637 : 0 : opt->wkr_deq_dep = info.max_event_port_dequeue_depth;
638 : :
639 : : /* port configuration */
640 : 0 : const struct rte_event_port_conf p_conf = {
641 : 0 : .dequeue_depth = opt->wkr_deq_dep,
642 : : .enqueue_depth = info.max_event_port_dequeue_depth,
643 : 0 : .new_event_threshold = info.max_num_events,
644 : : };
645 : :
646 : 0 : if (!t->internal_port)
647 : 0 : ret = pipeline_event_port_setup(test, opt, queue_arr,
648 : : nb_worker_queues, p_conf);
649 : : else
650 : 0 : ret = pipeline_event_port_setup(test, opt, NULL, nb_queues,
651 : : p_conf);
652 : :
653 : 0 : if (ret)
654 : : return ret;
655 : :
656 : : /*
657 : : * The pipelines are setup in the following manner:
658 : : *
659 : : * eth_dev_count = 2, nb_stages = 2, atq mode
660 : : *
661 : : * eth0, eth1 have Internal port capability :
662 : : * queues = 2
663 : : * stride = 1
664 : : *
665 : : * event queue pipelines:
666 : : * eth0 -> q0 ->Tx
667 : : * eth1 -> q1 ->Tx
668 : : *
669 : : * q0, q1 are configured as ATQ so, all the different stages can
670 : : * be enqueued on the same queue.
671 : : *
672 : : * eth0, eth1 use Tx adapters service core :
673 : : * queues = 4
674 : : * stride = 1
675 : : *
676 : : * event queue pipelines:
677 : : * eth0 -> q0 -> q2 -> Tx
678 : : * eth1 -> q1 -> q3 -> Tx
679 : : *
680 : : * q0, q1 are configured as stated above.
681 : : * q2, q3 configured as SINGLE_LINK.
682 : : */
683 : 0 : ret = pipeline_event_rx_adapter_setup(opt, 1, p_conf);
684 : 0 : if (ret)
685 : : return ret;
686 : 0 : ret = pipeline_event_tx_adapter_setup(opt, p_conf);
687 : 0 : if (ret)
688 : : return ret;
689 : :
690 : 0 : if (!evt_has_distributed_sched(opt->dev_id)) {
691 : : uint32_t service_id;
692 : 0 : rte_event_dev_service_id_get(opt->dev_id, &service_id);
693 : 0 : ret = evt_service_setup(service_id);
694 : 0 : if (ret) {
695 : 0 : evt_err("No service lcore found to run event dev.");
696 : 0 : return ret;
697 : : }
698 : : }
699 : :
700 : : /* Connect the tx_evqueue_id to the Tx adapter port */
701 : 0 : if (!t->internal_port) {
702 : 0 : RTE_ETH_FOREACH_DEV(prod) {
703 : 0 : ret = rte_event_eth_tx_adapter_event_port_get(prod,
704 : : &tx_evport_id);
705 : 0 : if (ret) {
706 : 0 : evt_err("Unable to get Tx adapter[%d]", prod);
707 : 0 : return ret;
708 : : }
709 : :
710 : 0 : if (rte_event_port_link(opt->dev_id, tx_evport_id,
711 : 0 : &tx_evqueue_id[prod],
712 : : NULL, 1) != 1) {
713 : 0 : evt_err("Unable to link Tx adptr[%d] evprt[%d]",
714 : : prod, tx_evport_id);
715 : 0 : return ret;
716 : : }
717 : : }
718 : : }
719 : :
720 : 0 : ret = rte_event_dev_start(opt->dev_id);
721 : 0 : if (ret) {
722 : 0 : evt_err("failed to start eventdev %d", opt->dev_id);
723 : 0 : return ret;
724 : : }
725 : :
726 : :
727 : 0 : RTE_ETH_FOREACH_DEV(prod) {
728 : 0 : ret = rte_eth_dev_start(prod);
729 : 0 : if (ret) {
730 : 0 : evt_err("Ethernet dev [%d] failed to start."
731 : : " Using synthetic producer", prod);
732 : 0 : return ret;
733 : : }
734 : : }
735 : :
736 : 0 : RTE_ETH_FOREACH_DEV(prod) {
737 : 0 : ret = rte_event_eth_rx_adapter_start(prod);
738 : 0 : if (ret) {
739 : 0 : evt_err("Rx adapter[%d] start failed", prod);
740 : 0 : return ret;
741 : : }
742 : :
743 : 0 : ret = rte_event_eth_tx_adapter_start(prod);
744 : 0 : if (ret) {
745 : 0 : evt_err("Tx adapter[%d] start failed", prod);
746 : 0 : return ret;
747 : : }
748 : : }
749 : :
750 : 0 : memcpy(t->tx_evqueue_id, tx_evqueue_id, sizeof(uint8_t) *
751 : : RTE_MAX_ETHPORTS);
752 : :
753 : 0 : return 0;
754 : : }
755 : :
756 : : static void
757 : 0 : pipeline_atq_opt_dump(struct evt_options *opt)
758 : : {
759 : 0 : pipeline_opt_dump(opt, pipeline_atq_nb_event_queues(opt));
760 : 0 : }
761 : :
762 : : static int
763 : 0 : pipeline_atq_opt_check(struct evt_options *opt)
764 : : {
765 : 0 : return pipeline_opt_check(opt, pipeline_atq_nb_event_queues(opt));
766 : : }
767 : :
768 : : static bool
769 : 0 : pipeline_atq_capability_check(struct evt_options *opt)
770 : : {
771 : : struct rte_event_dev_info dev_info;
772 : :
773 : 0 : rte_event_dev_info_get(opt->dev_id, &dev_info);
774 : 0 : if (dev_info.max_event_queues < pipeline_atq_nb_event_queues(opt) ||
775 : 0 : dev_info.max_event_ports <
776 : 0 : evt_nr_active_lcores(opt->wlcores)) {
777 : 0 : evt_err("not enough eventdev queues=%d/%d or ports=%d/%d",
778 : : pipeline_atq_nb_event_queues(opt),
779 : : dev_info.max_event_queues,
780 : : evt_nr_active_lcores(opt->wlcores),
781 : : dev_info.max_event_ports);
782 : : }
783 : 0 : if (!evt_has_all_types_queue(opt->dev_id))
784 : 0 : return false;
785 : :
786 : : return true;
787 : : }
788 : :
789 : : static const struct evt_test_ops pipeline_atq = {
790 : : .cap_check = pipeline_atq_capability_check,
791 : : .opt_check = pipeline_atq_opt_check,
792 : : .opt_dump = pipeline_atq_opt_dump,
793 : : .test_setup = pipeline_test_setup,
794 : : .mempool_setup = pipeline_mempool_setup,
795 : : .ethdev_setup = pipeline_ethdev_setup,
796 : : .eventdev_setup = pipeline_atq_eventdev_setup,
797 : : .launch_lcores = pipeline_atq_launch_lcores,
798 : : .ethdev_rx_stop = pipeline_ethdev_rx_stop,
799 : : .eventdev_destroy = pipeline_eventdev_destroy,
800 : : .mempool_destroy = pipeline_mempool_destroy,
801 : : .ethdev_destroy = pipeline_ethdev_destroy,
802 : : .test_result = pipeline_test_result,
803 : : .test_destroy = pipeline_test_destroy,
804 : : };
805 : :
806 : 0 : EVT_TEST_REGISTER(pipeline_atq);
|