Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2017 Cavium, Inc.
3 : : */
4 : :
5 : : #ifndef _TEST_PIPELINE_COMMON_
6 : : #define _TEST_PIPELINE_COMMON_
7 : :
8 : : #include <stdio.h>
9 : : #include <stdbool.h>
10 : : #include <unistd.h>
11 : :
12 : : #include <rte_cycles.h>
13 : : #include <rte_ethdev.h>
14 : : #include <rte_ether.h>
15 : : #include <rte_event_eth_rx_adapter.h>
16 : : #include <rte_event_eth_tx_adapter.h>
17 : : #include <rte_eventdev.h>
18 : : #include <rte_lcore.h>
19 : : #include <rte_malloc.h>
20 : : #include <rte_mempool.h>
21 : : #include <rte_prefetch.h>
22 : : #include <rte_service.h>
23 : : #include <rte_service_component.h>
24 : : #include <rte_spinlock.h>
25 : : #include <rte_udp.h>
26 : :
27 : : #include "evt_common.h"
28 : : #include "evt_options.h"
29 : : #include "evt_test.h"
30 : :
31 : : struct test_pipeline;
32 : :
33 : : struct __rte_cache_aligned worker_data {
34 : : uint64_t processed_pkts;
35 : : uint8_t dev_id;
36 : : uint8_t port_id;
37 : : struct test_pipeline *t;
38 : : };
39 : :
40 : : struct __rte_cache_aligned test_pipeline {
41 : : /* Don't change the offset of "done". Signal handler use this memory
42 : : * to terminate all lcores work.
43 : : */
44 : : int done;
45 : : uint8_t nb_workers;
46 : : uint8_t internal_port;
47 : : uint8_t tx_evqueue_id[RTE_MAX_ETHPORTS];
48 : : enum evt_test_result result;
49 : : uint32_t nb_flows;
50 : : uint64_t outstand_pkts;
51 : : struct rte_mempool *pool[RTE_MAX_ETHPORTS];
52 : : struct worker_data worker[EVT_MAX_PORTS];
53 : : struct evt_options *opt;
54 : : alignas(RTE_CACHE_LINE_SIZE) uint8_t sched_type_list[EVT_MAX_STAGES];
55 : : };
56 : :
57 : : #define BURST_SIZE 16
58 : :
59 : : #define PIPELINE_WORKER_SINGLE_STAGE_INIT \
60 : : struct worker_data *w = arg; \
61 : : struct test_pipeline *t = w->t; \
62 : : const uint8_t dev = w->dev_id; \
63 : : const uint8_t port = w->port_id; \
64 : : alignas(RTE_CACHE_LINE_SIZE) struct rte_event ev
65 : :
66 : : #define PIPELINE_WORKER_SINGLE_STAGE_BURST_INIT \
67 : : int i; \
68 : : struct worker_data *w = arg; \
69 : : struct test_pipeline *t = w->t; \
70 : : const uint8_t dev = w->dev_id; \
71 : : const uint8_t port = w->port_id; \
72 : : alignas(RTE_CACHE_LINE_SIZE) struct rte_event ev[BURST_SIZE + 1]
73 : :
74 : : #define PIPELINE_WORKER_MULTI_STAGE_INIT \
75 : : struct worker_data *w = arg; \
76 : : struct test_pipeline *t = w->t; \
77 : : uint8_t cq_id; \
78 : : const uint8_t dev = w->dev_id; \
79 : : const uint8_t port = w->port_id; \
80 : : const uint8_t last_queue = t->opt->nb_stages - 1; \
81 : : uint8_t *const sched_type_list = &t->sched_type_list[0]; \
82 : : const uint8_t nb_stages = t->opt->nb_stages + 1; \
83 : : alignas(RTE_CACHE_LINE_SIZE) struct rte_event ev
84 : :
85 : : #define PIPELINE_WORKER_MULTI_STAGE_BURST_INIT \
86 : : int i; \
87 : : struct worker_data *w = arg; \
88 : : struct test_pipeline *t = w->t; \
89 : : uint8_t cq_id; \
90 : : const uint8_t dev = w->dev_id; \
91 : : const uint8_t port = w->port_id; \
92 : : const uint8_t last_queue = t->opt->nb_stages - 1; \
93 : : uint8_t *const sched_type_list = &t->sched_type_list[0]; \
94 : : const uint8_t nb_stages = t->opt->nb_stages + 1; \
95 : : alignas(RTE_CACHE_LINE_SIZE) struct rte_event ev[BURST_SIZE + 1]
96 : :
97 : : static __rte_always_inline void
98 : : pipeline_fwd_event(struct rte_event *ev, uint8_t sched)
99 : : {
100 : 0 : ev->event_type = RTE_EVENT_TYPE_CPU;
101 : 0 : ev->op = RTE_EVENT_OP_FORWARD;
102 : 0 : ev->sched_type = sched;
103 : 0 : }
104 : :
105 : : static __rte_always_inline void
106 : : pipeline_fwd_event_vector(struct rte_event *ev, uint8_t sched)
107 : : {
108 : 0 : ev->event_type = RTE_EVENT_TYPE_CPU_VECTOR;
109 : 0 : ev->op = RTE_EVENT_OP_FORWARD;
110 : 0 : ev->sched_type = sched;
111 : 0 : }
112 : :
113 : : static __rte_always_inline uint8_t
114 : : pipeline_event_tx(const uint8_t dev, const uint8_t port,
115 : : struct rte_event *const ev, struct test_pipeline *t)
116 : : {
117 : : uint8_t enq;
118 : :
119 : 0 : rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
120 : : do {
121 : 0 : enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0);
122 : 0 : } while (!enq && !t->done);
123 : :
124 : : return enq;
125 : : }
126 : :
127 : : static __rte_always_inline uint8_t
128 : : pipeline_event_tx_vector(const uint8_t dev, const uint8_t port,
129 : : struct rte_event *const ev, struct test_pipeline *t)
130 : : {
131 : : uint8_t enq;
132 : :
133 : 0 : ev->vec->queue = 0;
134 : : do {
135 : 0 : enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0);
136 : 0 : } while (!enq && !t->done);
137 : :
138 : : return enq;
139 : : }
140 : :
141 : : static __rte_always_inline uint16_t
142 : : pipeline_event_tx_burst(const uint8_t dev, const uint8_t port,
143 : : struct rte_event *ev, const uint16_t nb_rx,
144 : : struct test_pipeline *t)
145 : : {
146 : : uint16_t enq;
147 : :
148 : 0 : enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
149 : 0 : while (enq < nb_rx && !t->done) {
150 : 0 : enq += rte_event_eth_tx_adapter_enqueue(dev, port,
151 : 0 : ev + enq, nb_rx - enq, 0);
152 : : }
153 : :
154 : : return enq;
155 : : }
156 : :
157 : : static __rte_always_inline uint8_t
158 : : pipeline_event_enqueue(const uint8_t dev, const uint8_t port,
159 : : struct rte_event *ev, struct test_pipeline *t)
160 : : {
161 : : uint8_t enq;
162 : :
163 : : do {
164 : 0 : enq = rte_event_enqueue_burst(dev, port, ev, 1);
165 : 0 : } while (!enq && !t->done);
166 : :
167 : : return enq;
168 : : }
169 : :
170 : : static __rte_always_inline uint16_t
171 : : pipeline_event_enqueue_burst(const uint8_t dev, const uint8_t port,
172 : : struct rte_event *ev, const uint16_t nb_rx,
173 : : struct test_pipeline *t)
174 : : {
175 : : uint16_t enq;
176 : :
177 : : enq = rte_event_enqueue_burst(dev, port, ev, nb_rx);
178 : 0 : while (enq < nb_rx && !t->done) {
179 : 0 : enq += rte_event_enqueue_burst(dev, port,
180 : 0 : ev + enq, nb_rx - enq);
181 : : }
182 : :
183 : : return enq;
184 : : }
185 : :
186 : :
187 : : static inline int
188 : : pipeline_nb_event_ports(struct evt_options *opt)
189 : : {
190 : : return evt_nr_active_lcores(opt->wlcores);
191 : : }
192 : :
193 : : int pipeline_test_result(struct evt_test *test, struct evt_options *opt);
194 : : int pipeline_opt_check(struct evt_options *opt, uint64_t nb_queues);
195 : : int pipeline_test_setup(struct evt_test *test, struct evt_options *opt);
196 : : int pipeline_ethdev_setup(struct evt_test *test, struct evt_options *opt);
197 : : int pipeline_event_rx_adapter_setup(struct evt_options *opt, uint8_t stride,
198 : : struct rte_event_port_conf prod_conf);
199 : : int pipeline_event_tx_adapter_setup(struct evt_options *opt,
200 : : struct rte_event_port_conf prod_conf);
201 : : int pipeline_mempool_setup(struct evt_test *test, struct evt_options *opt);
202 : : int pipeline_event_port_setup(struct evt_test *test, struct evt_options *opt,
203 : : uint8_t *queue_arr, uint8_t nb_queues,
204 : : const struct rte_event_port_conf p_conf);
205 : : int pipeline_launch_lcores(struct evt_test *test, struct evt_options *opt,
206 : : int (*worker)(void *));
207 : : void pipeline_opt_dump(struct evt_options *opt, uint8_t nb_queues);
208 : : void pipeline_test_destroy(struct evt_test *test, struct evt_options *opt);
209 : : void pipeline_eventdev_destroy(struct evt_test *test, struct evt_options *opt);
210 : : void pipeline_ethdev_destroy(struct evt_test *test, struct evt_options *opt);
211 : : void pipeline_ethdev_rx_stop(struct evt_test *test, struct evt_options *opt);
212 : : void pipeline_mempool_destroy(struct evt_test *test, struct evt_options *opt);
213 : : void pipeline_worker_cleanup(uint8_t dev, uint8_t port, struct rte_event ev[],
214 : : uint16_t enq, uint16_t deq);
215 : :
216 : : #endif /* _TEST_PIPELINE_COMMON_ */
|