1*ecca8a0bSMattias Rönnblom /* SPDX-License-Identifier: BSD-3-Clause
2*ecca8a0bSMattias Rönnblom * Copyright(c) 2023 Ericsson AB
3*ecca8a0bSMattias Rönnblom */
4*ecca8a0bSMattias Rönnblom
5*ecca8a0bSMattias Rönnblom #include <rte_bus_vdev.h>
6*ecca8a0bSMattias Rönnblom #include <rte_dispatcher.h>
7*ecca8a0bSMattias Rönnblom #include <rte_eventdev.h>
8*ecca8a0bSMattias Rönnblom #include <rte_random.h>
9*ecca8a0bSMattias Rönnblom #include <rte_service.h>
10*ecca8a0bSMattias Rönnblom #include <rte_stdatomic.h>
11*ecca8a0bSMattias Rönnblom
12*ecca8a0bSMattias Rönnblom #include "test.h"
13*ecca8a0bSMattias Rönnblom
14*ecca8a0bSMattias Rönnblom #define NUM_WORKERS 3
15*ecca8a0bSMattias Rönnblom #define NUM_PORTS (NUM_WORKERS + 1)
16*ecca8a0bSMattias Rönnblom #define WORKER_PORT_ID(worker_idx) (worker_idx)
17*ecca8a0bSMattias Rönnblom #define DRIVER_PORT_ID (NUM_PORTS - 1)
18*ecca8a0bSMattias Rönnblom
19*ecca8a0bSMattias Rönnblom #define NUM_SERVICE_CORES NUM_WORKERS
20*ecca8a0bSMattias Rönnblom #define MIN_LCORES (NUM_SERVICE_CORES + 1)
21*ecca8a0bSMattias Rönnblom
22*ecca8a0bSMattias Rönnblom /* Eventdev */
23*ecca8a0bSMattias Rönnblom #define NUM_QUEUES 8
24*ecca8a0bSMattias Rönnblom #define LAST_QUEUE_ID (NUM_QUEUES - 1)
25*ecca8a0bSMattias Rönnblom #define MAX_EVENTS 4096
26*ecca8a0bSMattias Rönnblom #define NEW_EVENT_THRESHOLD (MAX_EVENTS / 2)
27*ecca8a0bSMattias Rönnblom #define DEQUEUE_BURST_SIZE 32
28*ecca8a0bSMattias Rönnblom #define ENQUEUE_BURST_SIZE 32
29*ecca8a0bSMattias Rönnblom
30*ecca8a0bSMattias Rönnblom #define NUM_EVENTS 10000000
31*ecca8a0bSMattias Rönnblom #define NUM_FLOWS 16
32*ecca8a0bSMattias Rönnblom
33*ecca8a0bSMattias Rönnblom #define DSW_VDEV "event_dsw0"
34*ecca8a0bSMattias Rönnblom
35*ecca8a0bSMattias Rönnblom struct app_queue {
36*ecca8a0bSMattias Rönnblom uint8_t queue_id;
37*ecca8a0bSMattias Rönnblom uint64_t sn[NUM_FLOWS];
38*ecca8a0bSMattias Rönnblom int dispatcher_reg_id;
39*ecca8a0bSMattias Rönnblom };
40*ecca8a0bSMattias Rönnblom
41*ecca8a0bSMattias Rönnblom struct cb_count {
42*ecca8a0bSMattias Rönnblom uint8_t expected_event_dev_id;
43*ecca8a0bSMattias Rönnblom uint8_t expected_event_port_id[RTE_MAX_LCORE];
44*ecca8a0bSMattias Rönnblom RTE_ATOMIC(int) count;
45*ecca8a0bSMattias Rönnblom };
46*ecca8a0bSMattias Rönnblom
47*ecca8a0bSMattias Rönnblom struct test_app {
48*ecca8a0bSMattias Rönnblom uint8_t event_dev_id;
49*ecca8a0bSMattias Rönnblom struct rte_dispatcher *dispatcher;
50*ecca8a0bSMattias Rönnblom uint32_t dispatcher_service_id;
51*ecca8a0bSMattias Rönnblom
52*ecca8a0bSMattias Rönnblom unsigned int service_lcores[NUM_SERVICE_CORES];
53*ecca8a0bSMattias Rönnblom
54*ecca8a0bSMattias Rönnblom int never_match_reg_id;
55*ecca8a0bSMattias Rönnblom uint64_t never_match_count;
56*ecca8a0bSMattias Rönnblom struct cb_count never_process_count;
57*ecca8a0bSMattias Rönnblom
58*ecca8a0bSMattias Rönnblom struct app_queue queues[NUM_QUEUES];
59*ecca8a0bSMattias Rönnblom
60*ecca8a0bSMattias Rönnblom int finalize_reg_id;
61*ecca8a0bSMattias Rönnblom struct cb_count finalize_count;
62*ecca8a0bSMattias Rönnblom
63*ecca8a0bSMattias Rönnblom bool running;
64*ecca8a0bSMattias Rönnblom
65*ecca8a0bSMattias Rönnblom RTE_ATOMIC(int) completed_events;
66*ecca8a0bSMattias Rönnblom RTE_ATOMIC(int) errors;
67*ecca8a0bSMattias Rönnblom };
68*ecca8a0bSMattias Rönnblom
69*ecca8a0bSMattias Rönnblom static struct test_app *
test_app_create(void)70*ecca8a0bSMattias Rönnblom test_app_create(void)
71*ecca8a0bSMattias Rönnblom {
72*ecca8a0bSMattias Rönnblom int i;
73*ecca8a0bSMattias Rönnblom struct test_app *app;
74*ecca8a0bSMattias Rönnblom
75*ecca8a0bSMattias Rönnblom app = calloc(1, sizeof(struct test_app));
76*ecca8a0bSMattias Rönnblom
77*ecca8a0bSMattias Rönnblom if (app == NULL)
78*ecca8a0bSMattias Rönnblom return NULL;
79*ecca8a0bSMattias Rönnblom
80*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_QUEUES; i++)
81*ecca8a0bSMattias Rönnblom app->queues[i].queue_id = i;
82*ecca8a0bSMattias Rönnblom
83*ecca8a0bSMattias Rönnblom return app;
84*ecca8a0bSMattias Rönnblom }
85*ecca8a0bSMattias Rönnblom
86*ecca8a0bSMattias Rönnblom static void
test_app_free(struct test_app * app)87*ecca8a0bSMattias Rönnblom test_app_free(struct test_app *app)
88*ecca8a0bSMattias Rönnblom {
89*ecca8a0bSMattias Rönnblom free(app);
90*ecca8a0bSMattias Rönnblom }
91*ecca8a0bSMattias Rönnblom
92*ecca8a0bSMattias Rönnblom static int
test_app_create_vdev(struct test_app * app)93*ecca8a0bSMattias Rönnblom test_app_create_vdev(struct test_app *app)
94*ecca8a0bSMattias Rönnblom {
95*ecca8a0bSMattias Rönnblom int rc;
96*ecca8a0bSMattias Rönnblom
97*ecca8a0bSMattias Rönnblom rc = rte_vdev_init(DSW_VDEV, NULL);
98*ecca8a0bSMattias Rönnblom if (rc < 0)
99*ecca8a0bSMattias Rönnblom return TEST_SKIPPED;
100*ecca8a0bSMattias Rönnblom
101*ecca8a0bSMattias Rönnblom rc = rte_event_dev_get_dev_id(DSW_VDEV);
102*ecca8a0bSMattias Rönnblom
103*ecca8a0bSMattias Rönnblom app->event_dev_id = (uint8_t)rc;
104*ecca8a0bSMattias Rönnblom
105*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
106*ecca8a0bSMattias Rönnblom }
107*ecca8a0bSMattias Rönnblom
108*ecca8a0bSMattias Rönnblom static int
test_app_destroy_vdev(struct test_app * app)109*ecca8a0bSMattias Rönnblom test_app_destroy_vdev(struct test_app *app)
110*ecca8a0bSMattias Rönnblom {
111*ecca8a0bSMattias Rönnblom int rc;
112*ecca8a0bSMattias Rönnblom
113*ecca8a0bSMattias Rönnblom rc = rte_event_dev_close(app->event_dev_id);
114*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Error while closing event device");
115*ecca8a0bSMattias Rönnblom
116*ecca8a0bSMattias Rönnblom rc = rte_vdev_uninit(DSW_VDEV);
117*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Error while uninitializing virtual device");
118*ecca8a0bSMattias Rönnblom
119*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
120*ecca8a0bSMattias Rönnblom }
121*ecca8a0bSMattias Rönnblom
122*ecca8a0bSMattias Rönnblom static int
test_app_setup_event_dev(struct test_app * app)123*ecca8a0bSMattias Rönnblom test_app_setup_event_dev(struct test_app *app)
124*ecca8a0bSMattias Rönnblom {
125*ecca8a0bSMattias Rönnblom int rc;
126*ecca8a0bSMattias Rönnblom int i;
127*ecca8a0bSMattias Rönnblom
128*ecca8a0bSMattias Rönnblom rc = test_app_create_vdev(app);
129*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
130*ecca8a0bSMattias Rönnblom return rc;
131*ecca8a0bSMattias Rönnblom
132*ecca8a0bSMattias Rönnblom struct rte_event_dev_config config = {
133*ecca8a0bSMattias Rönnblom .nb_event_queues = NUM_QUEUES,
134*ecca8a0bSMattias Rönnblom .nb_event_ports = NUM_PORTS,
135*ecca8a0bSMattias Rönnblom .nb_events_limit = MAX_EVENTS,
136*ecca8a0bSMattias Rönnblom .nb_event_queue_flows = 64,
137*ecca8a0bSMattias Rönnblom .nb_event_port_dequeue_depth = DEQUEUE_BURST_SIZE,
138*ecca8a0bSMattias Rönnblom .nb_event_port_enqueue_depth = ENQUEUE_BURST_SIZE
139*ecca8a0bSMattias Rönnblom };
140*ecca8a0bSMattias Rönnblom
141*ecca8a0bSMattias Rönnblom rc = rte_event_dev_configure(app->event_dev_id, &config);
142*ecca8a0bSMattias Rönnblom
143*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to configure event device");
144*ecca8a0bSMattias Rönnblom
145*ecca8a0bSMattias Rönnblom struct rte_event_queue_conf queue_config = {
146*ecca8a0bSMattias Rönnblom .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
147*ecca8a0bSMattias Rönnblom .schedule_type = RTE_SCHED_TYPE_ATOMIC,
148*ecca8a0bSMattias Rönnblom .nb_atomic_flows = 64
149*ecca8a0bSMattias Rönnblom };
150*ecca8a0bSMattias Rönnblom
151*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_QUEUES; i++) {
152*ecca8a0bSMattias Rönnblom uint8_t queue_id = i;
153*ecca8a0bSMattias Rönnblom
154*ecca8a0bSMattias Rönnblom rc = rte_event_queue_setup(app->event_dev_id, queue_id,
155*ecca8a0bSMattias Rönnblom &queue_config);
156*ecca8a0bSMattias Rönnblom
157*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to setup queue %d", queue_id);
158*ecca8a0bSMattias Rönnblom }
159*ecca8a0bSMattias Rönnblom
160*ecca8a0bSMattias Rönnblom struct rte_event_port_conf port_config = {
161*ecca8a0bSMattias Rönnblom .new_event_threshold = NEW_EVENT_THRESHOLD,
162*ecca8a0bSMattias Rönnblom .dequeue_depth = DEQUEUE_BURST_SIZE,
163*ecca8a0bSMattias Rönnblom .enqueue_depth = ENQUEUE_BURST_SIZE
164*ecca8a0bSMattias Rönnblom };
165*ecca8a0bSMattias Rönnblom
166*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_PORTS; i++) {
167*ecca8a0bSMattias Rönnblom uint8_t event_port_id = i;
168*ecca8a0bSMattias Rönnblom
169*ecca8a0bSMattias Rönnblom rc = rte_event_port_setup(app->event_dev_id, event_port_id,
170*ecca8a0bSMattias Rönnblom &port_config);
171*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Failed to create event port %d",
172*ecca8a0bSMattias Rönnblom event_port_id);
173*ecca8a0bSMattias Rönnblom
174*ecca8a0bSMattias Rönnblom if (event_port_id == DRIVER_PORT_ID)
175*ecca8a0bSMattias Rönnblom continue;
176*ecca8a0bSMattias Rönnblom
177*ecca8a0bSMattias Rönnblom rc = rte_event_port_link(app->event_dev_id, event_port_id,
178*ecca8a0bSMattias Rönnblom NULL, NULL, 0);
179*ecca8a0bSMattias Rönnblom
180*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(rc, NUM_QUEUES, "Failed to link port %d",
181*ecca8a0bSMattias Rönnblom event_port_id);
182*ecca8a0bSMattias Rönnblom }
183*ecca8a0bSMattias Rönnblom
184*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
185*ecca8a0bSMattias Rönnblom }
186*ecca8a0bSMattias Rönnblom
187*ecca8a0bSMattias Rönnblom static int
test_app_teardown_event_dev(struct test_app * app)188*ecca8a0bSMattias Rönnblom test_app_teardown_event_dev(struct test_app *app)
189*ecca8a0bSMattias Rönnblom {
190*ecca8a0bSMattias Rönnblom return test_app_destroy_vdev(app);
191*ecca8a0bSMattias Rönnblom }
192*ecca8a0bSMattias Rönnblom
193*ecca8a0bSMattias Rönnblom static int
test_app_start_event_dev(struct test_app * app)194*ecca8a0bSMattias Rönnblom test_app_start_event_dev(struct test_app *app)
195*ecca8a0bSMattias Rönnblom {
196*ecca8a0bSMattias Rönnblom int rc;
197*ecca8a0bSMattias Rönnblom
198*ecca8a0bSMattias Rönnblom rc = rte_event_dev_start(app->event_dev_id);
199*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to start event device");
200*ecca8a0bSMattias Rönnblom
201*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
202*ecca8a0bSMattias Rönnblom }
203*ecca8a0bSMattias Rönnblom
204*ecca8a0bSMattias Rönnblom static void
test_app_stop_event_dev(struct test_app * app)205*ecca8a0bSMattias Rönnblom test_app_stop_event_dev(struct test_app *app)
206*ecca8a0bSMattias Rönnblom {
207*ecca8a0bSMattias Rönnblom rte_event_dev_stop(app->event_dev_id);
208*ecca8a0bSMattias Rönnblom }
209*ecca8a0bSMattias Rönnblom
210*ecca8a0bSMattias Rönnblom static int
test_app_create_dispatcher(struct test_app * app)211*ecca8a0bSMattias Rönnblom test_app_create_dispatcher(struct test_app *app)
212*ecca8a0bSMattias Rönnblom {
213*ecca8a0bSMattias Rönnblom int rc;
214*ecca8a0bSMattias Rönnblom
215*ecca8a0bSMattias Rönnblom app->dispatcher = rte_dispatcher_create(app->event_dev_id);
216*ecca8a0bSMattias Rönnblom
217*ecca8a0bSMattias Rönnblom TEST_ASSERT(app->dispatcher != NULL, "Unable to create event "
218*ecca8a0bSMattias Rönnblom "dispatcher");
219*ecca8a0bSMattias Rönnblom
220*ecca8a0bSMattias Rönnblom app->dispatcher_service_id =
221*ecca8a0bSMattias Rönnblom rte_dispatcher_service_id_get(app->dispatcher);
222*ecca8a0bSMattias Rönnblom
223*ecca8a0bSMattias Rönnblom rc = rte_service_set_stats_enable(app->dispatcher_service_id, 1);
224*ecca8a0bSMattias Rönnblom
225*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to enable event dispatcher service "
226*ecca8a0bSMattias Rönnblom "stats");
227*ecca8a0bSMattias Rönnblom
228*ecca8a0bSMattias Rönnblom rc = rte_service_runstate_set(app->dispatcher_service_id, 1);
229*ecca8a0bSMattias Rönnblom
230*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to set dispatcher service runstate");
231*ecca8a0bSMattias Rönnblom
232*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
233*ecca8a0bSMattias Rönnblom }
234*ecca8a0bSMattias Rönnblom
235*ecca8a0bSMattias Rönnblom static int
test_app_free_dispatcher(struct test_app * app)236*ecca8a0bSMattias Rönnblom test_app_free_dispatcher(struct test_app *app)
237*ecca8a0bSMattias Rönnblom {
238*ecca8a0bSMattias Rönnblom int rc;
239*ecca8a0bSMattias Rönnblom
240*ecca8a0bSMattias Rönnblom rc = rte_service_runstate_set(app->dispatcher_service_id, 0);
241*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Error disabling dispatcher service");
242*ecca8a0bSMattias Rönnblom
243*ecca8a0bSMattias Rönnblom rc = rte_dispatcher_free(app->dispatcher);
244*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Error freeing dispatcher");
245*ecca8a0bSMattias Rönnblom
246*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
247*ecca8a0bSMattias Rönnblom }
248*ecca8a0bSMattias Rönnblom
249*ecca8a0bSMattias Rönnblom static int
test_app_bind_ports(struct test_app * app)250*ecca8a0bSMattias Rönnblom test_app_bind_ports(struct test_app *app)
251*ecca8a0bSMattias Rönnblom {
252*ecca8a0bSMattias Rönnblom int i;
253*ecca8a0bSMattias Rönnblom
254*ecca8a0bSMattias Rönnblom app->never_process_count.expected_event_dev_id =
255*ecca8a0bSMattias Rönnblom app->event_dev_id;
256*ecca8a0bSMattias Rönnblom app->finalize_count.expected_event_dev_id =
257*ecca8a0bSMattias Rönnblom app->event_dev_id;
258*ecca8a0bSMattias Rönnblom
259*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_WORKERS; i++) {
260*ecca8a0bSMattias Rönnblom unsigned int lcore_id = app->service_lcores[i];
261*ecca8a0bSMattias Rönnblom uint8_t port_id = WORKER_PORT_ID(i);
262*ecca8a0bSMattias Rönnblom
263*ecca8a0bSMattias Rönnblom int rc = rte_dispatcher_bind_port_to_lcore(
264*ecca8a0bSMattias Rönnblom app->dispatcher, port_id, DEQUEUE_BURST_SIZE, 0,
265*ecca8a0bSMattias Rönnblom lcore_id
266*ecca8a0bSMattias Rönnblom );
267*ecca8a0bSMattias Rönnblom
268*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to bind event device port %d "
269*ecca8a0bSMattias Rönnblom "to lcore %d", port_id, lcore_id);
270*ecca8a0bSMattias Rönnblom
271*ecca8a0bSMattias Rönnblom app->never_process_count.expected_event_port_id[lcore_id] =
272*ecca8a0bSMattias Rönnblom port_id;
273*ecca8a0bSMattias Rönnblom app->finalize_count.expected_event_port_id[lcore_id] = port_id;
274*ecca8a0bSMattias Rönnblom }
275*ecca8a0bSMattias Rönnblom
276*ecca8a0bSMattias Rönnblom
277*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
278*ecca8a0bSMattias Rönnblom }
279*ecca8a0bSMattias Rönnblom
280*ecca8a0bSMattias Rönnblom static int
test_app_unbind_ports(struct test_app * app)281*ecca8a0bSMattias Rönnblom test_app_unbind_ports(struct test_app *app)
282*ecca8a0bSMattias Rönnblom {
283*ecca8a0bSMattias Rönnblom int i;
284*ecca8a0bSMattias Rönnblom
285*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_WORKERS; i++) {
286*ecca8a0bSMattias Rönnblom unsigned int lcore_id = app->service_lcores[i];
287*ecca8a0bSMattias Rönnblom
288*ecca8a0bSMattias Rönnblom int rc = rte_dispatcher_unbind_port_from_lcore(
289*ecca8a0bSMattias Rönnblom app->dispatcher,
290*ecca8a0bSMattias Rönnblom WORKER_PORT_ID(i),
291*ecca8a0bSMattias Rönnblom lcore_id
292*ecca8a0bSMattias Rönnblom );
293*ecca8a0bSMattias Rönnblom
294*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to unbind event device port %d "
295*ecca8a0bSMattias Rönnblom "from lcore %d", WORKER_PORT_ID(i),
296*ecca8a0bSMattias Rönnblom lcore_id);
297*ecca8a0bSMattias Rönnblom }
298*ecca8a0bSMattias Rönnblom
299*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
300*ecca8a0bSMattias Rönnblom }
301*ecca8a0bSMattias Rönnblom
302*ecca8a0bSMattias Rönnblom static bool
match_queue(const struct rte_event * event,void * cb_data)303*ecca8a0bSMattias Rönnblom match_queue(const struct rte_event *event, void *cb_data)
304*ecca8a0bSMattias Rönnblom {
305*ecca8a0bSMattias Rönnblom uintptr_t queue_id = (uintptr_t)cb_data;
306*ecca8a0bSMattias Rönnblom
307*ecca8a0bSMattias Rönnblom return event->queue_id == queue_id;
308*ecca8a0bSMattias Rönnblom }
309*ecca8a0bSMattias Rönnblom
310*ecca8a0bSMattias Rönnblom static int
test_app_get_worker_index(struct test_app * app,unsigned int lcore_id)311*ecca8a0bSMattias Rönnblom test_app_get_worker_index(struct test_app *app, unsigned int lcore_id)
312*ecca8a0bSMattias Rönnblom {
313*ecca8a0bSMattias Rönnblom int i;
314*ecca8a0bSMattias Rönnblom
315*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_SERVICE_CORES; i++)
316*ecca8a0bSMattias Rönnblom if (app->service_lcores[i] == lcore_id)
317*ecca8a0bSMattias Rönnblom return i;
318*ecca8a0bSMattias Rönnblom
319*ecca8a0bSMattias Rönnblom return -1;
320*ecca8a0bSMattias Rönnblom }
321*ecca8a0bSMattias Rönnblom
322*ecca8a0bSMattias Rönnblom static int
test_app_get_worker_port(struct test_app * app,unsigned int lcore_id)323*ecca8a0bSMattias Rönnblom test_app_get_worker_port(struct test_app *app, unsigned int lcore_id)
324*ecca8a0bSMattias Rönnblom {
325*ecca8a0bSMattias Rönnblom int worker;
326*ecca8a0bSMattias Rönnblom
327*ecca8a0bSMattias Rönnblom worker = test_app_get_worker_index(app, lcore_id);
328*ecca8a0bSMattias Rönnblom
329*ecca8a0bSMattias Rönnblom if (worker < 0)
330*ecca8a0bSMattias Rönnblom return -1;
331*ecca8a0bSMattias Rönnblom
332*ecca8a0bSMattias Rönnblom return WORKER_PORT_ID(worker);
333*ecca8a0bSMattias Rönnblom }
334*ecca8a0bSMattias Rönnblom
335*ecca8a0bSMattias Rönnblom static void
test_app_queue_note_error(struct test_app * app)336*ecca8a0bSMattias Rönnblom test_app_queue_note_error(struct test_app *app)
337*ecca8a0bSMattias Rönnblom {
338*ecca8a0bSMattias Rönnblom rte_atomic_fetch_add_explicit(&app->errors, 1, rte_memory_order_relaxed);
339*ecca8a0bSMattias Rönnblom }
340*ecca8a0bSMattias Rönnblom
341*ecca8a0bSMattias Rönnblom static void
test_app_process_queue(uint8_t p_event_dev_id,uint8_t p_event_port_id,struct rte_event * in_events,uint16_t num,void * cb_data)342*ecca8a0bSMattias Rönnblom test_app_process_queue(uint8_t p_event_dev_id, uint8_t p_event_port_id,
343*ecca8a0bSMattias Rönnblom struct rte_event *in_events, uint16_t num,
344*ecca8a0bSMattias Rönnblom void *cb_data)
345*ecca8a0bSMattias Rönnblom {
346*ecca8a0bSMattias Rönnblom struct app_queue *app_queue = cb_data;
347*ecca8a0bSMattias Rönnblom struct test_app *app = container_of(app_queue, struct test_app,
348*ecca8a0bSMattias Rönnblom queues[app_queue->queue_id]);
349*ecca8a0bSMattias Rönnblom unsigned int lcore_id = rte_lcore_id();
350*ecca8a0bSMattias Rönnblom bool intermediate_queue = app_queue->queue_id != LAST_QUEUE_ID;
351*ecca8a0bSMattias Rönnblom int event_port_id;
352*ecca8a0bSMattias Rönnblom uint16_t i;
353*ecca8a0bSMattias Rönnblom struct rte_event out_events[num];
354*ecca8a0bSMattias Rönnblom
355*ecca8a0bSMattias Rönnblom event_port_id = test_app_get_worker_port(app, lcore_id);
356*ecca8a0bSMattias Rönnblom
357*ecca8a0bSMattias Rönnblom if (event_port_id < 0 || p_event_dev_id != app->event_dev_id ||
358*ecca8a0bSMattias Rönnblom p_event_port_id != event_port_id) {
359*ecca8a0bSMattias Rönnblom test_app_queue_note_error(app);
360*ecca8a0bSMattias Rönnblom return;
361*ecca8a0bSMattias Rönnblom }
362*ecca8a0bSMattias Rönnblom
363*ecca8a0bSMattias Rönnblom for (i = 0; i < num; i++) {
364*ecca8a0bSMattias Rönnblom const struct rte_event *in_event = &in_events[i];
365*ecca8a0bSMattias Rönnblom struct rte_event *out_event = &out_events[i];
366*ecca8a0bSMattias Rönnblom uint64_t sn = in_event->u64;
367*ecca8a0bSMattias Rönnblom uint64_t expected_sn;
368*ecca8a0bSMattias Rönnblom
369*ecca8a0bSMattias Rönnblom if (in_event->queue_id != app_queue->queue_id) {
370*ecca8a0bSMattias Rönnblom test_app_queue_note_error(app);
371*ecca8a0bSMattias Rönnblom return;
372*ecca8a0bSMattias Rönnblom }
373*ecca8a0bSMattias Rönnblom
374*ecca8a0bSMattias Rönnblom expected_sn = app_queue->sn[in_event->flow_id]++;
375*ecca8a0bSMattias Rönnblom
376*ecca8a0bSMattias Rönnblom if (expected_sn != sn) {
377*ecca8a0bSMattias Rönnblom test_app_queue_note_error(app);
378*ecca8a0bSMattias Rönnblom return;
379*ecca8a0bSMattias Rönnblom }
380*ecca8a0bSMattias Rönnblom
381*ecca8a0bSMattias Rönnblom if (intermediate_queue)
382*ecca8a0bSMattias Rönnblom *out_event = (struct rte_event) {
383*ecca8a0bSMattias Rönnblom .queue_id = in_event->queue_id + 1,
384*ecca8a0bSMattias Rönnblom .flow_id = in_event->flow_id,
385*ecca8a0bSMattias Rönnblom .sched_type = RTE_SCHED_TYPE_ATOMIC,
386*ecca8a0bSMattias Rönnblom .op = RTE_EVENT_OP_FORWARD,
387*ecca8a0bSMattias Rönnblom .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
388*ecca8a0bSMattias Rönnblom .u64 = sn
389*ecca8a0bSMattias Rönnblom };
390*ecca8a0bSMattias Rönnblom }
391*ecca8a0bSMattias Rönnblom
392*ecca8a0bSMattias Rönnblom if (intermediate_queue) {
393*ecca8a0bSMattias Rönnblom uint16_t n = 0;
394*ecca8a0bSMattias Rönnblom
395*ecca8a0bSMattias Rönnblom do {
396*ecca8a0bSMattias Rönnblom n += rte_event_enqueue_forward_burst(p_event_dev_id,
397*ecca8a0bSMattias Rönnblom p_event_port_id,
398*ecca8a0bSMattias Rönnblom out_events + n,
399*ecca8a0bSMattias Rönnblom num - n);
400*ecca8a0bSMattias Rönnblom } while (n != num);
401*ecca8a0bSMattias Rönnblom } else
402*ecca8a0bSMattias Rönnblom rte_atomic_fetch_add_explicit(&app->completed_events, num,
403*ecca8a0bSMattias Rönnblom rte_memory_order_relaxed);
404*ecca8a0bSMattias Rönnblom }
405*ecca8a0bSMattias Rönnblom
406*ecca8a0bSMattias Rönnblom static bool
never_match(const struct rte_event * event __rte_unused,void * cb_data)407*ecca8a0bSMattias Rönnblom never_match(const struct rte_event *event __rte_unused, void *cb_data)
408*ecca8a0bSMattias Rönnblom {
409*ecca8a0bSMattias Rönnblom uint64_t *count = cb_data;
410*ecca8a0bSMattias Rönnblom
411*ecca8a0bSMattias Rönnblom (*count)++;
412*ecca8a0bSMattias Rönnblom
413*ecca8a0bSMattias Rönnblom return false;
414*ecca8a0bSMattias Rönnblom }
415*ecca8a0bSMattias Rönnblom
416*ecca8a0bSMattias Rönnblom static void
test_app_never_process(uint8_t event_dev_id,uint8_t event_port_id,struct rte_event * in_events __rte_unused,uint16_t num,void * cb_data)417*ecca8a0bSMattias Rönnblom test_app_never_process(uint8_t event_dev_id, uint8_t event_port_id,
418*ecca8a0bSMattias Rönnblom struct rte_event *in_events __rte_unused, uint16_t num, void *cb_data)
419*ecca8a0bSMattias Rönnblom {
420*ecca8a0bSMattias Rönnblom struct cb_count *count = cb_data;
421*ecca8a0bSMattias Rönnblom unsigned int lcore_id = rte_lcore_id();
422*ecca8a0bSMattias Rönnblom
423*ecca8a0bSMattias Rönnblom if (event_dev_id == count->expected_event_dev_id &&
424*ecca8a0bSMattias Rönnblom event_port_id == count->expected_event_port_id[lcore_id])
425*ecca8a0bSMattias Rönnblom rte_atomic_fetch_add_explicit(&count->count, num,
426*ecca8a0bSMattias Rönnblom rte_memory_order_relaxed);
427*ecca8a0bSMattias Rönnblom }
428*ecca8a0bSMattias Rönnblom
429*ecca8a0bSMattias Rönnblom static void
finalize(uint8_t event_dev_id,uint8_t event_port_id,void * cb_data)430*ecca8a0bSMattias Rönnblom finalize(uint8_t event_dev_id, uint8_t event_port_id, void *cb_data)
431*ecca8a0bSMattias Rönnblom {
432*ecca8a0bSMattias Rönnblom struct cb_count *count = cb_data;
433*ecca8a0bSMattias Rönnblom unsigned int lcore_id = rte_lcore_id();
434*ecca8a0bSMattias Rönnblom
435*ecca8a0bSMattias Rönnblom if (event_dev_id == count->expected_event_dev_id &&
436*ecca8a0bSMattias Rönnblom event_port_id == count->expected_event_port_id[lcore_id])
437*ecca8a0bSMattias Rönnblom rte_atomic_fetch_add_explicit(&count->count, 1,
438*ecca8a0bSMattias Rönnblom rte_memory_order_relaxed);
439*ecca8a0bSMattias Rönnblom }
440*ecca8a0bSMattias Rönnblom
441*ecca8a0bSMattias Rönnblom static int
test_app_register_callbacks(struct test_app * app)442*ecca8a0bSMattias Rönnblom test_app_register_callbacks(struct test_app *app)
443*ecca8a0bSMattias Rönnblom {
444*ecca8a0bSMattias Rönnblom int i;
445*ecca8a0bSMattias Rönnblom
446*ecca8a0bSMattias Rönnblom app->never_match_reg_id =
447*ecca8a0bSMattias Rönnblom rte_dispatcher_register(app->dispatcher, never_match,
448*ecca8a0bSMattias Rönnblom &app->never_match_count,
449*ecca8a0bSMattias Rönnblom test_app_never_process,
450*ecca8a0bSMattias Rönnblom &app->never_process_count);
451*ecca8a0bSMattias Rönnblom
452*ecca8a0bSMattias Rönnblom TEST_ASSERT(app->never_match_reg_id >= 0, "Unable to register "
453*ecca8a0bSMattias Rönnblom "never-match handler");
454*ecca8a0bSMattias Rönnblom
455*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_QUEUES; i++) {
456*ecca8a0bSMattias Rönnblom struct app_queue *app_queue = &app->queues[i];
457*ecca8a0bSMattias Rönnblom uintptr_t queue_id = app_queue->queue_id;
458*ecca8a0bSMattias Rönnblom int reg_id;
459*ecca8a0bSMattias Rönnblom
460*ecca8a0bSMattias Rönnblom reg_id = rte_dispatcher_register(app->dispatcher,
461*ecca8a0bSMattias Rönnblom match_queue, (void *)queue_id,
462*ecca8a0bSMattias Rönnblom test_app_process_queue,
463*ecca8a0bSMattias Rönnblom app_queue);
464*ecca8a0bSMattias Rönnblom
465*ecca8a0bSMattias Rönnblom TEST_ASSERT(reg_id >= 0, "Unable to register consumer "
466*ecca8a0bSMattias Rönnblom "callback for queue %d", i);
467*ecca8a0bSMattias Rönnblom
468*ecca8a0bSMattias Rönnblom app_queue->dispatcher_reg_id = reg_id;
469*ecca8a0bSMattias Rönnblom }
470*ecca8a0bSMattias Rönnblom
471*ecca8a0bSMattias Rönnblom app->finalize_reg_id =
472*ecca8a0bSMattias Rönnblom rte_dispatcher_finalize_register(app->dispatcher,
473*ecca8a0bSMattias Rönnblom finalize,
474*ecca8a0bSMattias Rönnblom &app->finalize_count);
475*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(app->finalize_reg_id, "Error registering "
476*ecca8a0bSMattias Rönnblom "finalize callback");
477*ecca8a0bSMattias Rönnblom
478*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
479*ecca8a0bSMattias Rönnblom }
480*ecca8a0bSMattias Rönnblom
481*ecca8a0bSMattias Rönnblom static int
test_app_unregister_callback(struct test_app * app,uint8_t queue_id)482*ecca8a0bSMattias Rönnblom test_app_unregister_callback(struct test_app *app, uint8_t queue_id)
483*ecca8a0bSMattias Rönnblom {
484*ecca8a0bSMattias Rönnblom int reg_id = app->queues[queue_id].dispatcher_reg_id;
485*ecca8a0bSMattias Rönnblom int rc;
486*ecca8a0bSMattias Rönnblom
487*ecca8a0bSMattias Rönnblom if (reg_id < 0) /* unregistered already */
488*ecca8a0bSMattias Rönnblom return 0;
489*ecca8a0bSMattias Rönnblom
490*ecca8a0bSMattias Rönnblom rc = rte_dispatcher_unregister(app->dispatcher, reg_id);
491*ecca8a0bSMattias Rönnblom
492*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to unregister consumer "
493*ecca8a0bSMattias Rönnblom "callback for queue %d", queue_id);
494*ecca8a0bSMattias Rönnblom
495*ecca8a0bSMattias Rönnblom app->queues[queue_id].dispatcher_reg_id = -1;
496*ecca8a0bSMattias Rönnblom
497*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
498*ecca8a0bSMattias Rönnblom }
499*ecca8a0bSMattias Rönnblom
500*ecca8a0bSMattias Rönnblom static int
test_app_unregister_callbacks(struct test_app * app)501*ecca8a0bSMattias Rönnblom test_app_unregister_callbacks(struct test_app *app)
502*ecca8a0bSMattias Rönnblom {
503*ecca8a0bSMattias Rönnblom int i;
504*ecca8a0bSMattias Rönnblom int rc;
505*ecca8a0bSMattias Rönnblom
506*ecca8a0bSMattias Rönnblom if (app->never_match_reg_id >= 0) {
507*ecca8a0bSMattias Rönnblom rc = rte_dispatcher_unregister(app->dispatcher,
508*ecca8a0bSMattias Rönnblom app->never_match_reg_id);
509*ecca8a0bSMattias Rönnblom
510*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to unregister never-match "
511*ecca8a0bSMattias Rönnblom "handler");
512*ecca8a0bSMattias Rönnblom app->never_match_reg_id = -1;
513*ecca8a0bSMattias Rönnblom }
514*ecca8a0bSMattias Rönnblom
515*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_QUEUES; i++) {
516*ecca8a0bSMattias Rönnblom rc = test_app_unregister_callback(app, i);
517*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
518*ecca8a0bSMattias Rönnblom return rc;
519*ecca8a0bSMattias Rönnblom }
520*ecca8a0bSMattias Rönnblom
521*ecca8a0bSMattias Rönnblom if (app->finalize_reg_id >= 0) {
522*ecca8a0bSMattias Rönnblom rc = rte_dispatcher_finalize_unregister(
523*ecca8a0bSMattias Rönnblom app->dispatcher, app->finalize_reg_id
524*ecca8a0bSMattias Rönnblom );
525*ecca8a0bSMattias Rönnblom app->finalize_reg_id = -1;
526*ecca8a0bSMattias Rönnblom }
527*ecca8a0bSMattias Rönnblom
528*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
529*ecca8a0bSMattias Rönnblom }
530*ecca8a0bSMattias Rönnblom
531*ecca8a0bSMattias Rönnblom static void
test_app_start_dispatcher(struct test_app * app)532*ecca8a0bSMattias Rönnblom test_app_start_dispatcher(struct test_app *app)
533*ecca8a0bSMattias Rönnblom {
534*ecca8a0bSMattias Rönnblom rte_dispatcher_start(app->dispatcher);
535*ecca8a0bSMattias Rönnblom }
536*ecca8a0bSMattias Rönnblom
537*ecca8a0bSMattias Rönnblom static void
test_app_stop_dispatcher(struct test_app * app)538*ecca8a0bSMattias Rönnblom test_app_stop_dispatcher(struct test_app *app)
539*ecca8a0bSMattias Rönnblom {
540*ecca8a0bSMattias Rönnblom rte_dispatcher_stop(app->dispatcher);
541*ecca8a0bSMattias Rönnblom }
542*ecca8a0bSMattias Rönnblom
543*ecca8a0bSMattias Rönnblom static int
test_app_reset_dispatcher_stats(struct test_app * app)544*ecca8a0bSMattias Rönnblom test_app_reset_dispatcher_stats(struct test_app *app)
545*ecca8a0bSMattias Rönnblom {
546*ecca8a0bSMattias Rönnblom struct rte_dispatcher_stats stats;
547*ecca8a0bSMattias Rönnblom
548*ecca8a0bSMattias Rönnblom rte_dispatcher_stats_reset(app->dispatcher);
549*ecca8a0bSMattias Rönnblom
550*ecca8a0bSMattias Rönnblom memset(&stats, 0xff, sizeof(stats));
551*ecca8a0bSMattias Rönnblom
552*ecca8a0bSMattias Rönnblom rte_dispatcher_stats_get(app->dispatcher, &stats);
553*ecca8a0bSMattias Rönnblom
554*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.poll_count, 0, "Poll count not zero");
555*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.ev_batch_count, 0, "Batch count not zero");
556*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.ev_dispatch_count, 0, "Dispatch count "
557*ecca8a0bSMattias Rönnblom "not zero");
558*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.ev_drop_count, 0, "Drop count not zero");
559*ecca8a0bSMattias Rönnblom
560*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
561*ecca8a0bSMattias Rönnblom }
562*ecca8a0bSMattias Rönnblom
563*ecca8a0bSMattias Rönnblom static int
test_app_setup_service_core(struct test_app * app,unsigned int lcore_id)564*ecca8a0bSMattias Rönnblom test_app_setup_service_core(struct test_app *app, unsigned int lcore_id)
565*ecca8a0bSMattias Rönnblom {
566*ecca8a0bSMattias Rönnblom int rc;
567*ecca8a0bSMattias Rönnblom
568*ecca8a0bSMattias Rönnblom rc = rte_service_lcore_add(lcore_id);
569*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to make lcore %d an event dispatcher "
570*ecca8a0bSMattias Rönnblom "service core", lcore_id);
571*ecca8a0bSMattias Rönnblom
572*ecca8a0bSMattias Rönnblom rc = rte_service_map_lcore_set(app->dispatcher_service_id, lcore_id, 1);
573*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to map event dispatcher service");
574*ecca8a0bSMattias Rönnblom
575*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
576*ecca8a0bSMattias Rönnblom }
577*ecca8a0bSMattias Rönnblom
578*ecca8a0bSMattias Rönnblom static int
test_app_setup_service_cores(struct test_app * app)579*ecca8a0bSMattias Rönnblom test_app_setup_service_cores(struct test_app *app)
580*ecca8a0bSMattias Rönnblom {
581*ecca8a0bSMattias Rönnblom int i;
582*ecca8a0bSMattias Rönnblom int lcore_id = -1;
583*ecca8a0bSMattias Rönnblom
584*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_SERVICE_CORES; i++) {
585*ecca8a0bSMattias Rönnblom lcore_id = rte_get_next_lcore(lcore_id, 1, 0);
586*ecca8a0bSMattias Rönnblom
587*ecca8a0bSMattias Rönnblom app->service_lcores[i] = lcore_id;
588*ecca8a0bSMattias Rönnblom }
589*ecca8a0bSMattias Rönnblom
590*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_SERVICE_CORES; i++) {
591*ecca8a0bSMattias Rönnblom int rc;
592*ecca8a0bSMattias Rönnblom
593*ecca8a0bSMattias Rönnblom rc = test_app_setup_service_core(app, app->service_lcores[i]);
594*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
595*ecca8a0bSMattias Rönnblom return rc;
596*ecca8a0bSMattias Rönnblom }
597*ecca8a0bSMattias Rönnblom
598*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
599*ecca8a0bSMattias Rönnblom }
600*ecca8a0bSMattias Rönnblom
601*ecca8a0bSMattias Rönnblom static int
test_app_teardown_service_core(struct test_app * app,unsigned int lcore_id)602*ecca8a0bSMattias Rönnblom test_app_teardown_service_core(struct test_app *app, unsigned int lcore_id)
603*ecca8a0bSMattias Rönnblom {
604*ecca8a0bSMattias Rönnblom int rc;
605*ecca8a0bSMattias Rönnblom
606*ecca8a0bSMattias Rönnblom rc = rte_service_map_lcore_set(app->dispatcher_service_id, lcore_id, 0);
607*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to unmap event dispatcher service");
608*ecca8a0bSMattias Rönnblom
609*ecca8a0bSMattias Rönnblom rc = rte_service_lcore_del(lcore_id);
610*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable change role of service lcore %d",
611*ecca8a0bSMattias Rönnblom lcore_id);
612*ecca8a0bSMattias Rönnblom
613*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
614*ecca8a0bSMattias Rönnblom }
615*ecca8a0bSMattias Rönnblom
616*ecca8a0bSMattias Rönnblom static int
test_app_teardown_service_cores(struct test_app * app)617*ecca8a0bSMattias Rönnblom test_app_teardown_service_cores(struct test_app *app)
618*ecca8a0bSMattias Rönnblom {
619*ecca8a0bSMattias Rönnblom int i;
620*ecca8a0bSMattias Rönnblom
621*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_SERVICE_CORES; i++) {
622*ecca8a0bSMattias Rönnblom unsigned int lcore_id = app->service_lcores[i];
623*ecca8a0bSMattias Rönnblom int rc;
624*ecca8a0bSMattias Rönnblom
625*ecca8a0bSMattias Rönnblom rc = test_app_teardown_service_core(app, lcore_id);
626*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
627*ecca8a0bSMattias Rönnblom return rc;
628*ecca8a0bSMattias Rönnblom }
629*ecca8a0bSMattias Rönnblom
630*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
631*ecca8a0bSMattias Rönnblom }
632*ecca8a0bSMattias Rönnblom
633*ecca8a0bSMattias Rönnblom static int
test_app_start_service_cores(struct test_app * app)634*ecca8a0bSMattias Rönnblom test_app_start_service_cores(struct test_app *app)
635*ecca8a0bSMattias Rönnblom {
636*ecca8a0bSMattias Rönnblom int i;
637*ecca8a0bSMattias Rönnblom
638*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_SERVICE_CORES; i++) {
639*ecca8a0bSMattias Rönnblom unsigned int lcore_id = app->service_lcores[i];
640*ecca8a0bSMattias Rönnblom int rc;
641*ecca8a0bSMattias Rönnblom
642*ecca8a0bSMattias Rönnblom rc = rte_service_lcore_start(lcore_id);
643*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to start service lcore %d",
644*ecca8a0bSMattias Rönnblom lcore_id);
645*ecca8a0bSMattias Rönnblom }
646*ecca8a0bSMattias Rönnblom
647*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
648*ecca8a0bSMattias Rönnblom }
649*ecca8a0bSMattias Rönnblom
650*ecca8a0bSMattias Rönnblom static int
test_app_stop_service_cores(struct test_app * app)651*ecca8a0bSMattias Rönnblom test_app_stop_service_cores(struct test_app *app)
652*ecca8a0bSMattias Rönnblom {
653*ecca8a0bSMattias Rönnblom int i;
654*ecca8a0bSMattias Rönnblom
655*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_SERVICE_CORES; i++) {
656*ecca8a0bSMattias Rönnblom unsigned int lcore_id = app->service_lcores[i];
657*ecca8a0bSMattias Rönnblom int rc;
658*ecca8a0bSMattias Rönnblom
659*ecca8a0bSMattias Rönnblom rc = rte_service_lcore_stop(lcore_id);
660*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to stop service lcore %d",
661*ecca8a0bSMattias Rönnblom lcore_id);
662*ecca8a0bSMattias Rönnblom }
663*ecca8a0bSMattias Rönnblom
664*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
665*ecca8a0bSMattias Rönnblom }
666*ecca8a0bSMattias Rönnblom
667*ecca8a0bSMattias Rönnblom static int
test_app_start(struct test_app * app)668*ecca8a0bSMattias Rönnblom test_app_start(struct test_app *app)
669*ecca8a0bSMattias Rönnblom {
670*ecca8a0bSMattias Rönnblom int rc;
671*ecca8a0bSMattias Rönnblom
672*ecca8a0bSMattias Rönnblom rc = test_app_start_event_dev(app);
673*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
674*ecca8a0bSMattias Rönnblom return rc;
675*ecca8a0bSMattias Rönnblom
676*ecca8a0bSMattias Rönnblom rc = test_app_start_service_cores(app);
677*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
678*ecca8a0bSMattias Rönnblom return rc;
679*ecca8a0bSMattias Rönnblom
680*ecca8a0bSMattias Rönnblom test_app_start_dispatcher(app);
681*ecca8a0bSMattias Rönnblom
682*ecca8a0bSMattias Rönnblom app->running = true;
683*ecca8a0bSMattias Rönnblom
684*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
685*ecca8a0bSMattias Rönnblom }
686*ecca8a0bSMattias Rönnblom
687*ecca8a0bSMattias Rönnblom static int
test_app_stop(struct test_app * app)688*ecca8a0bSMattias Rönnblom test_app_stop(struct test_app *app)
689*ecca8a0bSMattias Rönnblom {
690*ecca8a0bSMattias Rönnblom int rc;
691*ecca8a0bSMattias Rönnblom
692*ecca8a0bSMattias Rönnblom test_app_stop_dispatcher(app);
693*ecca8a0bSMattias Rönnblom
694*ecca8a0bSMattias Rönnblom rc = test_app_stop_service_cores(app);
695*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
696*ecca8a0bSMattias Rönnblom return rc;
697*ecca8a0bSMattias Rönnblom
698*ecca8a0bSMattias Rönnblom test_app_stop_event_dev(app);
699*ecca8a0bSMattias Rönnblom
700*ecca8a0bSMattias Rönnblom app->running = false;
701*ecca8a0bSMattias Rönnblom
702*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
703*ecca8a0bSMattias Rönnblom }
704*ecca8a0bSMattias Rönnblom
705*ecca8a0bSMattias Rönnblom struct test_app *test_app;
706*ecca8a0bSMattias Rönnblom
707*ecca8a0bSMattias Rönnblom static int
test_setup(void)708*ecca8a0bSMattias Rönnblom test_setup(void)
709*ecca8a0bSMattias Rönnblom {
710*ecca8a0bSMattias Rönnblom int rc;
711*ecca8a0bSMattias Rönnblom
712*ecca8a0bSMattias Rönnblom if (rte_lcore_count() < MIN_LCORES) {
713*ecca8a0bSMattias Rönnblom printf("Not enough cores for dispatcher_autotest; expecting at "
714*ecca8a0bSMattias Rönnblom "least %d.\n", MIN_LCORES);
715*ecca8a0bSMattias Rönnblom return TEST_SKIPPED;
716*ecca8a0bSMattias Rönnblom }
717*ecca8a0bSMattias Rönnblom
718*ecca8a0bSMattias Rönnblom test_app = test_app_create();
719*ecca8a0bSMattias Rönnblom TEST_ASSERT(test_app != NULL, "Unable to allocate memory");
720*ecca8a0bSMattias Rönnblom
721*ecca8a0bSMattias Rönnblom rc = test_app_setup_event_dev(test_app);
722*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
723*ecca8a0bSMattias Rönnblom goto err_free_app;
724*ecca8a0bSMattias Rönnblom
725*ecca8a0bSMattias Rönnblom rc = test_app_create_dispatcher(test_app);
726*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
727*ecca8a0bSMattias Rönnblom goto err_teardown_event_dev;
728*ecca8a0bSMattias Rönnblom
729*ecca8a0bSMattias Rönnblom rc = test_app_setup_service_cores(test_app);
730*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
731*ecca8a0bSMattias Rönnblom goto err_free_dispatcher;
732*ecca8a0bSMattias Rönnblom
733*ecca8a0bSMattias Rönnblom rc = test_app_register_callbacks(test_app);
734*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
735*ecca8a0bSMattias Rönnblom goto err_teardown_service_cores;
736*ecca8a0bSMattias Rönnblom
737*ecca8a0bSMattias Rönnblom rc = test_app_bind_ports(test_app);
738*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
739*ecca8a0bSMattias Rönnblom goto err_unregister_callbacks;
740*ecca8a0bSMattias Rönnblom
741*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
742*ecca8a0bSMattias Rönnblom
743*ecca8a0bSMattias Rönnblom err_unregister_callbacks:
744*ecca8a0bSMattias Rönnblom test_app_unregister_callbacks(test_app);
745*ecca8a0bSMattias Rönnblom err_teardown_service_cores:
746*ecca8a0bSMattias Rönnblom test_app_teardown_service_cores(test_app);
747*ecca8a0bSMattias Rönnblom err_free_dispatcher:
748*ecca8a0bSMattias Rönnblom test_app_free_dispatcher(test_app);
749*ecca8a0bSMattias Rönnblom err_teardown_event_dev:
750*ecca8a0bSMattias Rönnblom test_app_teardown_event_dev(test_app);
751*ecca8a0bSMattias Rönnblom err_free_app:
752*ecca8a0bSMattias Rönnblom test_app_free(test_app);
753*ecca8a0bSMattias Rönnblom
754*ecca8a0bSMattias Rönnblom test_app = NULL;
755*ecca8a0bSMattias Rönnblom
756*ecca8a0bSMattias Rönnblom return rc;
757*ecca8a0bSMattias Rönnblom }
758*ecca8a0bSMattias Rönnblom
test_teardown(void)759*ecca8a0bSMattias Rönnblom static void test_teardown(void)
760*ecca8a0bSMattias Rönnblom {
761*ecca8a0bSMattias Rönnblom if (test_app == NULL)
762*ecca8a0bSMattias Rönnblom return;
763*ecca8a0bSMattias Rönnblom
764*ecca8a0bSMattias Rönnblom if (test_app->running)
765*ecca8a0bSMattias Rönnblom test_app_stop(test_app);
766*ecca8a0bSMattias Rönnblom
767*ecca8a0bSMattias Rönnblom test_app_teardown_service_cores(test_app);
768*ecca8a0bSMattias Rönnblom
769*ecca8a0bSMattias Rönnblom test_app_unregister_callbacks(test_app);
770*ecca8a0bSMattias Rönnblom
771*ecca8a0bSMattias Rönnblom test_app_unbind_ports(test_app);
772*ecca8a0bSMattias Rönnblom
773*ecca8a0bSMattias Rönnblom test_app_free_dispatcher(test_app);
774*ecca8a0bSMattias Rönnblom
775*ecca8a0bSMattias Rönnblom test_app_teardown_event_dev(test_app);
776*ecca8a0bSMattias Rönnblom
777*ecca8a0bSMattias Rönnblom test_app_free(test_app);
778*ecca8a0bSMattias Rönnblom
779*ecca8a0bSMattias Rönnblom test_app = NULL;
780*ecca8a0bSMattias Rönnblom }
781*ecca8a0bSMattias Rönnblom
782*ecca8a0bSMattias Rönnblom static int
test_app_get_completed_events(struct test_app * app)783*ecca8a0bSMattias Rönnblom test_app_get_completed_events(struct test_app *app)
784*ecca8a0bSMattias Rönnblom {
785*ecca8a0bSMattias Rönnblom return rte_atomic_load_explicit(&app->completed_events,
786*ecca8a0bSMattias Rönnblom rte_memory_order_relaxed);
787*ecca8a0bSMattias Rönnblom }
788*ecca8a0bSMattias Rönnblom
789*ecca8a0bSMattias Rönnblom static int
test_app_get_errors(struct test_app * app)790*ecca8a0bSMattias Rönnblom test_app_get_errors(struct test_app *app)
791*ecca8a0bSMattias Rönnblom {
792*ecca8a0bSMattias Rönnblom return rte_atomic_load_explicit(&app->errors, rte_memory_order_relaxed);
793*ecca8a0bSMattias Rönnblom }
794*ecca8a0bSMattias Rönnblom
795*ecca8a0bSMattias Rönnblom static int
test_basic(void)796*ecca8a0bSMattias Rönnblom test_basic(void)
797*ecca8a0bSMattias Rönnblom {
798*ecca8a0bSMattias Rönnblom int rc;
799*ecca8a0bSMattias Rönnblom int i;
800*ecca8a0bSMattias Rönnblom
801*ecca8a0bSMattias Rönnblom rc = test_app_start(test_app);
802*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
803*ecca8a0bSMattias Rönnblom return rc;
804*ecca8a0bSMattias Rönnblom
805*ecca8a0bSMattias Rönnblom uint64_t sns[NUM_FLOWS] = { 0 };
806*ecca8a0bSMattias Rönnblom
807*ecca8a0bSMattias Rönnblom for (i = 0; i < NUM_EVENTS;) {
808*ecca8a0bSMattias Rönnblom struct rte_event events[ENQUEUE_BURST_SIZE];
809*ecca8a0bSMattias Rönnblom int left;
810*ecca8a0bSMattias Rönnblom int batch_size;
811*ecca8a0bSMattias Rönnblom int j;
812*ecca8a0bSMattias Rönnblom uint16_t n = 0;
813*ecca8a0bSMattias Rönnblom
814*ecca8a0bSMattias Rönnblom batch_size = 1 + rte_rand_max(ENQUEUE_BURST_SIZE);
815*ecca8a0bSMattias Rönnblom left = NUM_EVENTS - i;
816*ecca8a0bSMattias Rönnblom
817*ecca8a0bSMattias Rönnblom batch_size = RTE_MIN(left, batch_size);
818*ecca8a0bSMattias Rönnblom
819*ecca8a0bSMattias Rönnblom for (j = 0; j < batch_size; j++) {
820*ecca8a0bSMattias Rönnblom struct rte_event *event = &events[j];
821*ecca8a0bSMattias Rönnblom uint64_t sn;
822*ecca8a0bSMattias Rönnblom uint32_t flow_id;
823*ecca8a0bSMattias Rönnblom
824*ecca8a0bSMattias Rönnblom flow_id = rte_rand_max(NUM_FLOWS);
825*ecca8a0bSMattias Rönnblom
826*ecca8a0bSMattias Rönnblom sn = sns[flow_id]++;
827*ecca8a0bSMattias Rönnblom
828*ecca8a0bSMattias Rönnblom *event = (struct rte_event) {
829*ecca8a0bSMattias Rönnblom .queue_id = 0,
830*ecca8a0bSMattias Rönnblom .flow_id = flow_id,
831*ecca8a0bSMattias Rönnblom .sched_type = RTE_SCHED_TYPE_ATOMIC,
832*ecca8a0bSMattias Rönnblom .op = RTE_EVENT_OP_NEW,
833*ecca8a0bSMattias Rönnblom .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
834*ecca8a0bSMattias Rönnblom .u64 = sn
835*ecca8a0bSMattias Rönnblom };
836*ecca8a0bSMattias Rönnblom }
837*ecca8a0bSMattias Rönnblom
838*ecca8a0bSMattias Rönnblom while (n < batch_size)
839*ecca8a0bSMattias Rönnblom n += rte_event_enqueue_new_burst(test_app->event_dev_id,
840*ecca8a0bSMattias Rönnblom DRIVER_PORT_ID,
841*ecca8a0bSMattias Rönnblom events + n,
842*ecca8a0bSMattias Rönnblom batch_size - n);
843*ecca8a0bSMattias Rönnblom
844*ecca8a0bSMattias Rönnblom i += batch_size;
845*ecca8a0bSMattias Rönnblom }
846*ecca8a0bSMattias Rönnblom
847*ecca8a0bSMattias Rönnblom while (test_app_get_completed_events(test_app) != NUM_EVENTS)
848*ecca8a0bSMattias Rönnblom rte_event_maintain(test_app->event_dev_id, DRIVER_PORT_ID, 0);
849*ecca8a0bSMattias Rönnblom
850*ecca8a0bSMattias Rönnblom rc = test_app_get_errors(test_app);
851*ecca8a0bSMattias Rönnblom TEST_ASSERT(rc == 0, "%d errors occurred", rc);
852*ecca8a0bSMattias Rönnblom
853*ecca8a0bSMattias Rönnblom rc = test_app_stop(test_app);
854*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
855*ecca8a0bSMattias Rönnblom return rc;
856*ecca8a0bSMattias Rönnblom
857*ecca8a0bSMattias Rönnblom struct rte_dispatcher_stats stats;
858*ecca8a0bSMattias Rönnblom rte_dispatcher_stats_get(test_app->dispatcher, &stats);
859*ecca8a0bSMattias Rönnblom
860*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.ev_drop_count, 0, "Drop count is not zero");
861*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.ev_dispatch_count, NUM_EVENTS * NUM_QUEUES,
862*ecca8a0bSMattias Rönnblom "Invalid dispatch count");
863*ecca8a0bSMattias Rönnblom TEST_ASSERT(stats.poll_count > 0, "Poll count is zero");
864*ecca8a0bSMattias Rönnblom
865*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(test_app->never_process_count.count, 0,
866*ecca8a0bSMattias Rönnblom "Never-match handler's process function has "
867*ecca8a0bSMattias Rönnblom "been called");
868*ecca8a0bSMattias Rönnblom
869*ecca8a0bSMattias Rönnblom int finalize_count =
870*ecca8a0bSMattias Rönnblom rte_atomic_load_explicit(&test_app->finalize_count.count,
871*ecca8a0bSMattias Rönnblom rte_memory_order_relaxed);
872*ecca8a0bSMattias Rönnblom
873*ecca8a0bSMattias Rönnblom TEST_ASSERT(finalize_count > 0, "Finalize count is zero");
874*ecca8a0bSMattias Rönnblom TEST_ASSERT(finalize_count <= (int)stats.ev_dispatch_count,
875*ecca8a0bSMattias Rönnblom "Finalize count larger than event count");
876*ecca8a0bSMattias Rönnblom
877*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(finalize_count, (int)stats.ev_batch_count,
878*ecca8a0bSMattias Rönnblom "%"PRIu64" batches dequeued, but finalize called %d "
879*ecca8a0bSMattias Rönnblom "times", stats.ev_batch_count, finalize_count);
880*ecca8a0bSMattias Rönnblom
881*ecca8a0bSMattias Rönnblom /*
882*ecca8a0bSMattias Rönnblom * The event dispatcher should call often-matching match functions
883*ecca8a0bSMattias Rönnblom * more often, and thus this never-matching match function should
884*ecca8a0bSMattias Rönnblom * be called relatively infrequently.
885*ecca8a0bSMattias Rönnblom */
886*ecca8a0bSMattias Rönnblom TEST_ASSERT(test_app->never_match_count <
887*ecca8a0bSMattias Rönnblom (stats.ev_dispatch_count / 4),
888*ecca8a0bSMattias Rönnblom "Never-matching match function called suspiciously often");
889*ecca8a0bSMattias Rönnblom
890*ecca8a0bSMattias Rönnblom rc = test_app_reset_dispatcher_stats(test_app);
891*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
892*ecca8a0bSMattias Rönnblom return rc;
893*ecca8a0bSMattias Rönnblom
894*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
895*ecca8a0bSMattias Rönnblom }
896*ecca8a0bSMattias Rönnblom
897*ecca8a0bSMattias Rönnblom static int
test_drop(void)898*ecca8a0bSMattias Rönnblom test_drop(void)
899*ecca8a0bSMattias Rönnblom {
900*ecca8a0bSMattias Rönnblom int rc;
901*ecca8a0bSMattias Rönnblom uint8_t unhandled_queue;
902*ecca8a0bSMattias Rönnblom struct rte_dispatcher_stats stats;
903*ecca8a0bSMattias Rönnblom
904*ecca8a0bSMattias Rönnblom unhandled_queue = (uint8_t)rte_rand_max(NUM_QUEUES);
905*ecca8a0bSMattias Rönnblom
906*ecca8a0bSMattias Rönnblom rc = test_app_start(test_app);
907*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
908*ecca8a0bSMattias Rönnblom return rc;
909*ecca8a0bSMattias Rönnblom
910*ecca8a0bSMattias Rönnblom rc = test_app_unregister_callback(test_app, unhandled_queue);
911*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
912*ecca8a0bSMattias Rönnblom return rc;
913*ecca8a0bSMattias Rönnblom
914*ecca8a0bSMattias Rönnblom struct rte_event event = {
915*ecca8a0bSMattias Rönnblom .queue_id = unhandled_queue,
916*ecca8a0bSMattias Rönnblom .flow_id = 0,
917*ecca8a0bSMattias Rönnblom .sched_type = RTE_SCHED_TYPE_ATOMIC,
918*ecca8a0bSMattias Rönnblom .op = RTE_EVENT_OP_NEW,
919*ecca8a0bSMattias Rönnblom .priority = RTE_EVENT_DEV_PRIORITY_NORMAL,
920*ecca8a0bSMattias Rönnblom .u64 = 0
921*ecca8a0bSMattias Rönnblom };
922*ecca8a0bSMattias Rönnblom
923*ecca8a0bSMattias Rönnblom do {
924*ecca8a0bSMattias Rönnblom rc = rte_event_enqueue_burst(test_app->event_dev_id,
925*ecca8a0bSMattias Rönnblom DRIVER_PORT_ID, &event, 1);
926*ecca8a0bSMattias Rönnblom } while (rc == 0);
927*ecca8a0bSMattias Rönnblom
928*ecca8a0bSMattias Rönnblom do {
929*ecca8a0bSMattias Rönnblom rte_dispatcher_stats_get(test_app->dispatcher, &stats);
930*ecca8a0bSMattias Rönnblom
931*ecca8a0bSMattias Rönnblom rte_event_maintain(test_app->event_dev_id, DRIVER_PORT_ID, 0);
932*ecca8a0bSMattias Rönnblom } while (stats.ev_drop_count == 0 && stats.ev_dispatch_count == 0);
933*ecca8a0bSMattias Rönnblom
934*ecca8a0bSMattias Rönnblom rc = test_app_stop(test_app);
935*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
936*ecca8a0bSMattias Rönnblom return rc;
937*ecca8a0bSMattias Rönnblom
938*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.ev_drop_count, 1, "Drop count is not one");
939*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(stats.ev_dispatch_count, 0,
940*ecca8a0bSMattias Rönnblom "Dispatch count is not zero");
941*ecca8a0bSMattias Rönnblom TEST_ASSERT(stats.poll_count > 0, "Poll count is zero");
942*ecca8a0bSMattias Rönnblom
943*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
944*ecca8a0bSMattias Rönnblom }
945*ecca8a0bSMattias Rönnblom
946*ecca8a0bSMattias Rönnblom #define MORE_THAN_MAX_HANDLERS 1000
947*ecca8a0bSMattias Rönnblom #define MIN_HANDLERS 32
948*ecca8a0bSMattias Rönnblom
949*ecca8a0bSMattias Rönnblom static int
test_many_handler_registrations(void)950*ecca8a0bSMattias Rönnblom test_many_handler_registrations(void)
951*ecca8a0bSMattias Rönnblom {
952*ecca8a0bSMattias Rönnblom int rc;
953*ecca8a0bSMattias Rönnblom int num_regs = 0;
954*ecca8a0bSMattias Rönnblom int reg_ids[MORE_THAN_MAX_HANDLERS];
955*ecca8a0bSMattias Rönnblom int reg_id;
956*ecca8a0bSMattias Rönnblom int i;
957*ecca8a0bSMattias Rönnblom
958*ecca8a0bSMattias Rönnblom rc = test_app_unregister_callbacks(test_app);
959*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
960*ecca8a0bSMattias Rönnblom return rc;
961*ecca8a0bSMattias Rönnblom
962*ecca8a0bSMattias Rönnblom for (i = 0; i < MORE_THAN_MAX_HANDLERS; i++) {
963*ecca8a0bSMattias Rönnblom reg_id = rte_dispatcher_register(test_app->dispatcher,
964*ecca8a0bSMattias Rönnblom never_match, NULL,
965*ecca8a0bSMattias Rönnblom test_app_never_process, NULL);
966*ecca8a0bSMattias Rönnblom if (reg_id < 0)
967*ecca8a0bSMattias Rönnblom break;
968*ecca8a0bSMattias Rönnblom
969*ecca8a0bSMattias Rönnblom reg_ids[num_regs++] = reg_id;
970*ecca8a0bSMattias Rönnblom }
971*ecca8a0bSMattias Rönnblom
972*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(reg_id, -ENOMEM, "Incorrect return code. Expected "
973*ecca8a0bSMattias Rönnblom "%d but was %d", -ENOMEM, reg_id);
974*ecca8a0bSMattias Rönnblom TEST_ASSERT(num_regs >= MIN_HANDLERS, "Registration failed already "
975*ecca8a0bSMattias Rönnblom "after %d handler registrations.", num_regs);
976*ecca8a0bSMattias Rönnblom
977*ecca8a0bSMattias Rönnblom for (i = 0; i < num_regs; i++) {
978*ecca8a0bSMattias Rönnblom rc = rte_dispatcher_unregister(test_app->dispatcher,
979*ecca8a0bSMattias Rönnblom reg_ids[i]);
980*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to unregister handler %d",
981*ecca8a0bSMattias Rönnblom reg_ids[i]);
982*ecca8a0bSMattias Rönnblom }
983*ecca8a0bSMattias Rönnblom
984*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
985*ecca8a0bSMattias Rönnblom }
986*ecca8a0bSMattias Rönnblom
987*ecca8a0bSMattias Rönnblom static void
dummy_finalize(uint8_t event_dev_id __rte_unused,uint8_t event_port_id __rte_unused,void * cb_data __rte_unused)988*ecca8a0bSMattias Rönnblom dummy_finalize(uint8_t event_dev_id __rte_unused,
989*ecca8a0bSMattias Rönnblom uint8_t event_port_id __rte_unused,
990*ecca8a0bSMattias Rönnblom void *cb_data __rte_unused)
991*ecca8a0bSMattias Rönnblom {
992*ecca8a0bSMattias Rönnblom }
993*ecca8a0bSMattias Rönnblom
994*ecca8a0bSMattias Rönnblom #define MORE_THAN_MAX_FINALIZERS 1000
995*ecca8a0bSMattias Rönnblom #define MIN_FINALIZERS 16
996*ecca8a0bSMattias Rönnblom
997*ecca8a0bSMattias Rönnblom static int
test_many_finalize_registrations(void)998*ecca8a0bSMattias Rönnblom test_many_finalize_registrations(void)
999*ecca8a0bSMattias Rönnblom {
1000*ecca8a0bSMattias Rönnblom int rc;
1001*ecca8a0bSMattias Rönnblom int num_regs = 0;
1002*ecca8a0bSMattias Rönnblom int reg_ids[MORE_THAN_MAX_FINALIZERS];
1003*ecca8a0bSMattias Rönnblom int reg_id;
1004*ecca8a0bSMattias Rönnblom int i;
1005*ecca8a0bSMattias Rönnblom
1006*ecca8a0bSMattias Rönnblom rc = test_app_unregister_callbacks(test_app);
1007*ecca8a0bSMattias Rönnblom if (rc != TEST_SUCCESS)
1008*ecca8a0bSMattias Rönnblom return rc;
1009*ecca8a0bSMattias Rönnblom
1010*ecca8a0bSMattias Rönnblom for (i = 0; i < MORE_THAN_MAX_FINALIZERS; i++) {
1011*ecca8a0bSMattias Rönnblom reg_id = rte_dispatcher_finalize_register(
1012*ecca8a0bSMattias Rönnblom test_app->dispatcher, dummy_finalize, NULL
1013*ecca8a0bSMattias Rönnblom );
1014*ecca8a0bSMattias Rönnblom
1015*ecca8a0bSMattias Rönnblom if (reg_id < 0)
1016*ecca8a0bSMattias Rönnblom break;
1017*ecca8a0bSMattias Rönnblom
1018*ecca8a0bSMattias Rönnblom reg_ids[num_regs++] = reg_id;
1019*ecca8a0bSMattias Rönnblom }
1020*ecca8a0bSMattias Rönnblom
1021*ecca8a0bSMattias Rönnblom TEST_ASSERT_EQUAL(reg_id, -ENOMEM, "Incorrect return code. Expected "
1022*ecca8a0bSMattias Rönnblom "%d but was %d", -ENOMEM, reg_id);
1023*ecca8a0bSMattias Rönnblom TEST_ASSERT(num_regs >= MIN_FINALIZERS, "Finalize registration failed "
1024*ecca8a0bSMattias Rönnblom "already after %d registrations.", num_regs);
1025*ecca8a0bSMattias Rönnblom
1026*ecca8a0bSMattias Rönnblom for (i = 0; i < num_regs; i++) {
1027*ecca8a0bSMattias Rönnblom rc = rte_dispatcher_finalize_unregister(
1028*ecca8a0bSMattias Rönnblom test_app->dispatcher, reg_ids[i]
1029*ecca8a0bSMattias Rönnblom );
1030*ecca8a0bSMattias Rönnblom TEST_ASSERT_SUCCESS(rc, "Unable to unregister finalizer %d",
1031*ecca8a0bSMattias Rönnblom reg_ids[i]);
1032*ecca8a0bSMattias Rönnblom }
1033*ecca8a0bSMattias Rönnblom
1034*ecca8a0bSMattias Rönnblom return TEST_SUCCESS;
1035*ecca8a0bSMattias Rönnblom }
1036*ecca8a0bSMattias Rönnblom
1037*ecca8a0bSMattias Rönnblom static struct unit_test_suite test_suite = {
1038*ecca8a0bSMattias Rönnblom .suite_name = "Event dispatcher test suite",
1039*ecca8a0bSMattias Rönnblom .unit_test_cases = {
1040*ecca8a0bSMattias Rönnblom TEST_CASE_ST(test_setup, test_teardown, test_basic),
1041*ecca8a0bSMattias Rönnblom TEST_CASE_ST(test_setup, test_teardown, test_drop),
1042*ecca8a0bSMattias Rönnblom TEST_CASE_ST(test_setup, test_teardown,
1043*ecca8a0bSMattias Rönnblom test_many_handler_registrations),
1044*ecca8a0bSMattias Rönnblom TEST_CASE_ST(test_setup, test_teardown,
1045*ecca8a0bSMattias Rönnblom test_many_finalize_registrations),
1046*ecca8a0bSMattias Rönnblom TEST_CASES_END()
1047*ecca8a0bSMattias Rönnblom }
1048*ecca8a0bSMattias Rönnblom };
1049*ecca8a0bSMattias Rönnblom
1050*ecca8a0bSMattias Rönnblom static int
test_dispatcher(void)1051*ecca8a0bSMattias Rönnblom test_dispatcher(void)
1052*ecca8a0bSMattias Rönnblom {
1053*ecca8a0bSMattias Rönnblom return unit_test_suite_runner(&test_suite);
1054*ecca8a0bSMattias Rönnblom }
1055*ecca8a0bSMattias Rönnblom
1056*ecca8a0bSMattias Rönnblom REGISTER_FAST_TEST(dispatcher_autotest, false, true, test_dispatcher);
1057