1ecca8a0bSMattias Rönnblom /* SPDX-License-Identifier: BSD-3-Clause
2ecca8a0bSMattias Rönnblom * Copyright(c) 2023 Ericsson AB
3ecca8a0bSMattias Rönnblom */
4ecca8a0bSMattias Rönnblom
5ecca8a0bSMattias Rönnblom #include <stdbool.h>
6ecca8a0bSMattias Rönnblom #include <stdint.h>
7ecca8a0bSMattias Rönnblom
8ecca8a0bSMattias Rönnblom #include <rte_branch_prediction.h>
9ecca8a0bSMattias Rönnblom #include <rte_common.h>
10ecca8a0bSMattias Rönnblom #include <rte_lcore.h>
11ecca8a0bSMattias Rönnblom #include <rte_random.h>
12ecca8a0bSMattias Rönnblom #include <rte_service_component.h>
13ecca8a0bSMattias Rönnblom
14ecca8a0bSMattias Rönnblom #include "eventdev_pmd.h"
15ecca8a0bSMattias Rönnblom
16ecca8a0bSMattias Rönnblom #include <rte_dispatcher.h>
17ecca8a0bSMattias Rönnblom
18ecca8a0bSMattias Rönnblom #define EVD_MAX_PORTS_PER_LCORE 4
19ecca8a0bSMattias Rönnblom #define EVD_MAX_HANDLERS 32
20ecca8a0bSMattias Rönnblom #define EVD_MAX_FINALIZERS 16
21ecca8a0bSMattias Rönnblom #define EVD_AVG_PRIO_INTERVAL 2000
22ecca8a0bSMattias Rönnblom #define EVD_SERVICE_NAME "dispatcher"
23ecca8a0bSMattias Rönnblom
24ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port {
25ecca8a0bSMattias Rönnblom uint8_t port_id;
26ecca8a0bSMattias Rönnblom uint16_t batch_size;
27ecca8a0bSMattias Rönnblom uint64_t timeout;
28ecca8a0bSMattias Rönnblom };
29ecca8a0bSMattias Rönnblom
30ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler {
31ecca8a0bSMattias Rönnblom int id;
32ecca8a0bSMattias Rönnblom rte_dispatcher_match_t match_fun;
33ecca8a0bSMattias Rönnblom void *match_data;
34ecca8a0bSMattias Rönnblom rte_dispatcher_process_t process_fun;
35ecca8a0bSMattias Rönnblom void *process_data;
36ecca8a0bSMattias Rönnblom };
37ecca8a0bSMattias Rönnblom
38ecca8a0bSMattias Rönnblom struct rte_dispatcher_finalizer {
39ecca8a0bSMattias Rönnblom int id;
40ecca8a0bSMattias Rönnblom rte_dispatcher_finalize_t finalize_fun;
41ecca8a0bSMattias Rönnblom void *finalize_data;
42ecca8a0bSMattias Rönnblom };
43ecca8a0bSMattias Rönnblom
44*c6552d9aSTyler Retzlaff struct __rte_cache_aligned rte_dispatcher_lcore {
45ecca8a0bSMattias Rönnblom uint8_t num_ports;
46ecca8a0bSMattias Rönnblom uint16_t num_handlers;
47ecca8a0bSMattias Rönnblom int32_t prio_count;
48ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port ports[EVD_MAX_PORTS_PER_LCORE];
49ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler handlers[EVD_MAX_HANDLERS];
50ecca8a0bSMattias Rönnblom struct rte_dispatcher_stats stats;
51a7ba9d04SMattias Rönnblom RTE_CACHE_GUARD;
52*c6552d9aSTyler Retzlaff };
53ecca8a0bSMattias Rönnblom
54ecca8a0bSMattias Rönnblom struct rte_dispatcher {
55ecca8a0bSMattias Rönnblom uint8_t event_dev_id;
56ecca8a0bSMattias Rönnblom int socket_id;
57ecca8a0bSMattias Rönnblom uint32_t service_id;
58ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore lcores[RTE_MAX_LCORE];
59ecca8a0bSMattias Rönnblom uint16_t num_finalizers;
60ecca8a0bSMattias Rönnblom struct rte_dispatcher_finalizer finalizers[EVD_MAX_FINALIZERS];
61ecca8a0bSMattias Rönnblom };
62ecca8a0bSMattias Rönnblom
63ecca8a0bSMattias Rönnblom static int
evd_lookup_handler_idx(struct rte_dispatcher_lcore * lcore,const struct rte_event * event)64ecca8a0bSMattias Rönnblom evd_lookup_handler_idx(struct rte_dispatcher_lcore *lcore,
65ecca8a0bSMattias Rönnblom const struct rte_event *event)
66ecca8a0bSMattias Rönnblom {
67ecca8a0bSMattias Rönnblom uint16_t i;
68ecca8a0bSMattias Rönnblom
69ecca8a0bSMattias Rönnblom for (i = 0; i < lcore->num_handlers; i++) {
70ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler *handler =
71ecca8a0bSMattias Rönnblom &lcore->handlers[i];
72ecca8a0bSMattias Rönnblom
73ecca8a0bSMattias Rönnblom if (handler->match_fun(event, handler->match_data))
74ecca8a0bSMattias Rönnblom return i;
75ecca8a0bSMattias Rönnblom }
76ecca8a0bSMattias Rönnblom
77ecca8a0bSMattias Rönnblom return -1;
78ecca8a0bSMattias Rönnblom }
79ecca8a0bSMattias Rönnblom
80ecca8a0bSMattias Rönnblom static void
evd_prioritize_handler(struct rte_dispatcher_lcore * lcore,int handler_idx)81ecca8a0bSMattias Rönnblom evd_prioritize_handler(struct rte_dispatcher_lcore *lcore,
82ecca8a0bSMattias Rönnblom int handler_idx)
83ecca8a0bSMattias Rönnblom {
84ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler tmp;
85ecca8a0bSMattias Rönnblom
86ecca8a0bSMattias Rönnblom if (handler_idx == 0)
87ecca8a0bSMattias Rönnblom return;
88ecca8a0bSMattias Rönnblom
89ecca8a0bSMattias Rönnblom /* Let the lucky handler "bubble" up the list */
90ecca8a0bSMattias Rönnblom
91ecca8a0bSMattias Rönnblom tmp = lcore->handlers[handler_idx - 1];
92ecca8a0bSMattias Rönnblom lcore->handlers[handler_idx - 1] = lcore->handlers[handler_idx];
93ecca8a0bSMattias Rönnblom lcore->handlers[handler_idx] = tmp;
94ecca8a0bSMattias Rönnblom }
95ecca8a0bSMattias Rönnblom
96ecca8a0bSMattias Rönnblom static inline void
evd_consider_prioritize_handler(struct rte_dispatcher_lcore * lcore,int handler_idx,uint16_t handler_events)97ecca8a0bSMattias Rönnblom evd_consider_prioritize_handler(struct rte_dispatcher_lcore *lcore,
98ecca8a0bSMattias Rönnblom int handler_idx, uint16_t handler_events)
99ecca8a0bSMattias Rönnblom {
100ecca8a0bSMattias Rönnblom lcore->prio_count -= handler_events;
101ecca8a0bSMattias Rönnblom
102ecca8a0bSMattias Rönnblom if (unlikely(lcore->prio_count <= 0)) {
103ecca8a0bSMattias Rönnblom evd_prioritize_handler(lcore, handler_idx);
104ecca8a0bSMattias Rönnblom
105ecca8a0bSMattias Rönnblom /*
106ecca8a0bSMattias Rönnblom * Randomize the interval in the unlikely case
107ecca8a0bSMattias Rönnblom * the traffic follow some very strict pattern.
108ecca8a0bSMattias Rönnblom */
109ecca8a0bSMattias Rönnblom lcore->prio_count =
110ecca8a0bSMattias Rönnblom rte_rand_max(EVD_AVG_PRIO_INTERVAL) +
111ecca8a0bSMattias Rönnblom EVD_AVG_PRIO_INTERVAL / 2;
112ecca8a0bSMattias Rönnblom }
113ecca8a0bSMattias Rönnblom }
114ecca8a0bSMattias Rönnblom
115ecca8a0bSMattias Rönnblom static inline void
evd_dispatch_events(struct rte_dispatcher * dispatcher,struct rte_dispatcher_lcore * lcore,struct rte_dispatcher_lcore_port * port,struct rte_event * events,uint16_t num_events)116ecca8a0bSMattias Rönnblom evd_dispatch_events(struct rte_dispatcher *dispatcher,
117ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore,
118ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port *port,
119ecca8a0bSMattias Rönnblom struct rte_event *events, uint16_t num_events)
120ecca8a0bSMattias Rönnblom {
121ecca8a0bSMattias Rönnblom int i;
122ecca8a0bSMattias Rönnblom struct rte_event bursts[EVD_MAX_HANDLERS][num_events];
123ecca8a0bSMattias Rönnblom uint16_t burst_lens[EVD_MAX_HANDLERS] = { 0 };
124ecca8a0bSMattias Rönnblom uint16_t drop_count = 0;
125ecca8a0bSMattias Rönnblom uint16_t dispatch_count;
126ecca8a0bSMattias Rönnblom uint16_t dispatched = 0;
127ecca8a0bSMattias Rönnblom
128ecca8a0bSMattias Rönnblom for (i = 0; i < num_events; i++) {
129ecca8a0bSMattias Rönnblom struct rte_event *event = &events[i];
130ecca8a0bSMattias Rönnblom int handler_idx;
131ecca8a0bSMattias Rönnblom
132ecca8a0bSMattias Rönnblom handler_idx = evd_lookup_handler_idx(lcore, event);
133ecca8a0bSMattias Rönnblom
134ecca8a0bSMattias Rönnblom if (unlikely(handler_idx < 0)) {
135ecca8a0bSMattias Rönnblom drop_count++;
136ecca8a0bSMattias Rönnblom continue;
137ecca8a0bSMattias Rönnblom }
138ecca8a0bSMattias Rönnblom
139ecca8a0bSMattias Rönnblom bursts[handler_idx][burst_lens[handler_idx]] = *event;
140ecca8a0bSMattias Rönnblom burst_lens[handler_idx]++;
141ecca8a0bSMattias Rönnblom }
142ecca8a0bSMattias Rönnblom
143ecca8a0bSMattias Rönnblom dispatch_count = num_events - drop_count;
144ecca8a0bSMattias Rönnblom
145ecca8a0bSMattias Rönnblom for (i = 0; i < lcore->num_handlers &&
146ecca8a0bSMattias Rönnblom dispatched < dispatch_count; i++) {
147ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler *handler =
148ecca8a0bSMattias Rönnblom &lcore->handlers[i];
149ecca8a0bSMattias Rönnblom uint16_t len = burst_lens[i];
150ecca8a0bSMattias Rönnblom
151ecca8a0bSMattias Rönnblom if (len == 0)
152ecca8a0bSMattias Rönnblom continue;
153ecca8a0bSMattias Rönnblom
154ecca8a0bSMattias Rönnblom handler->process_fun(dispatcher->event_dev_id, port->port_id,
155ecca8a0bSMattias Rönnblom bursts[i], len, handler->process_data);
156ecca8a0bSMattias Rönnblom
157ecca8a0bSMattias Rönnblom dispatched += len;
158ecca8a0bSMattias Rönnblom
159ecca8a0bSMattias Rönnblom /*
160ecca8a0bSMattias Rönnblom * Safe, since any reshuffling will only involve
161ecca8a0bSMattias Rönnblom * already-processed handlers.
162ecca8a0bSMattias Rönnblom */
163ecca8a0bSMattias Rönnblom evd_consider_prioritize_handler(lcore, i, len);
164ecca8a0bSMattias Rönnblom }
165ecca8a0bSMattias Rönnblom
166ecca8a0bSMattias Rönnblom lcore->stats.ev_batch_count++;
167ecca8a0bSMattias Rönnblom lcore->stats.ev_dispatch_count += dispatch_count;
168ecca8a0bSMattias Rönnblom lcore->stats.ev_drop_count += drop_count;
169ecca8a0bSMattias Rönnblom
170ecca8a0bSMattias Rönnblom for (i = 0; i < dispatcher->num_finalizers; i++) {
171ecca8a0bSMattias Rönnblom struct rte_dispatcher_finalizer *finalizer =
172ecca8a0bSMattias Rönnblom &dispatcher->finalizers[i];
173ecca8a0bSMattias Rönnblom
174ecca8a0bSMattias Rönnblom finalizer->finalize_fun(dispatcher->event_dev_id,
175ecca8a0bSMattias Rönnblom port->port_id,
176ecca8a0bSMattias Rönnblom finalizer->finalize_data);
177ecca8a0bSMattias Rönnblom }
178ecca8a0bSMattias Rönnblom }
179ecca8a0bSMattias Rönnblom
180ecca8a0bSMattias Rönnblom static __rte_always_inline uint16_t
evd_port_dequeue(struct rte_dispatcher * dispatcher,struct rte_dispatcher_lcore * lcore,struct rte_dispatcher_lcore_port * port)181ecca8a0bSMattias Rönnblom evd_port_dequeue(struct rte_dispatcher *dispatcher,
182ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore,
183ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port *port)
184ecca8a0bSMattias Rönnblom {
185ecca8a0bSMattias Rönnblom uint16_t batch_size = port->batch_size;
186ecca8a0bSMattias Rönnblom struct rte_event events[batch_size];
187ecca8a0bSMattias Rönnblom uint16_t n;
188ecca8a0bSMattias Rönnblom
189ecca8a0bSMattias Rönnblom n = rte_event_dequeue_burst(dispatcher->event_dev_id, port->port_id,
190ecca8a0bSMattias Rönnblom events, batch_size, port->timeout);
191ecca8a0bSMattias Rönnblom
192ecca8a0bSMattias Rönnblom if (likely(n > 0))
193ecca8a0bSMattias Rönnblom evd_dispatch_events(dispatcher, lcore, port, events, n);
194ecca8a0bSMattias Rönnblom
195ecca8a0bSMattias Rönnblom lcore->stats.poll_count++;
196ecca8a0bSMattias Rönnblom
197ecca8a0bSMattias Rönnblom return n;
198ecca8a0bSMattias Rönnblom }
199ecca8a0bSMattias Rönnblom
200ecca8a0bSMattias Rönnblom static __rte_always_inline uint16_t
evd_lcore_process(struct rte_dispatcher * dispatcher,struct rte_dispatcher_lcore * lcore)201ecca8a0bSMattias Rönnblom evd_lcore_process(struct rte_dispatcher *dispatcher,
202ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore)
203ecca8a0bSMattias Rönnblom {
204ecca8a0bSMattias Rönnblom uint16_t i;
205ecca8a0bSMattias Rönnblom uint16_t event_count = 0;
206ecca8a0bSMattias Rönnblom
207ecca8a0bSMattias Rönnblom for (i = 0; i < lcore->num_ports; i++) {
208ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port *port =
209ecca8a0bSMattias Rönnblom &lcore->ports[i];
210ecca8a0bSMattias Rönnblom
211ecca8a0bSMattias Rönnblom event_count += evd_port_dequeue(dispatcher, lcore, port);
212ecca8a0bSMattias Rönnblom }
213ecca8a0bSMattias Rönnblom
214ecca8a0bSMattias Rönnblom return event_count;
215ecca8a0bSMattias Rönnblom }
216ecca8a0bSMattias Rönnblom
217ecca8a0bSMattias Rönnblom static int32_t
evd_process(void * userdata)218ecca8a0bSMattias Rönnblom evd_process(void *userdata)
219ecca8a0bSMattias Rönnblom {
220ecca8a0bSMattias Rönnblom struct rte_dispatcher *dispatcher = userdata;
221ecca8a0bSMattias Rönnblom unsigned int lcore_id = rte_lcore_id();
222ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore =
223ecca8a0bSMattias Rönnblom &dispatcher->lcores[lcore_id];
224ecca8a0bSMattias Rönnblom uint64_t event_count;
225ecca8a0bSMattias Rönnblom
226ecca8a0bSMattias Rönnblom event_count = evd_lcore_process(dispatcher, lcore);
227ecca8a0bSMattias Rönnblom
228ecca8a0bSMattias Rönnblom if (unlikely(event_count == 0))
229ecca8a0bSMattias Rönnblom return -EAGAIN;
230ecca8a0bSMattias Rönnblom
231ecca8a0bSMattias Rönnblom return 0;
232ecca8a0bSMattias Rönnblom }
233ecca8a0bSMattias Rönnblom
234ecca8a0bSMattias Rönnblom static int
evd_service_register(struct rte_dispatcher * dispatcher)235ecca8a0bSMattias Rönnblom evd_service_register(struct rte_dispatcher *dispatcher)
236ecca8a0bSMattias Rönnblom {
237ecca8a0bSMattias Rönnblom struct rte_service_spec service = {
238ecca8a0bSMattias Rönnblom .callback = evd_process,
239ecca8a0bSMattias Rönnblom .callback_userdata = dispatcher,
240ecca8a0bSMattias Rönnblom .capabilities = RTE_SERVICE_CAP_MT_SAFE,
241ecca8a0bSMattias Rönnblom .socket_id = dispatcher->socket_id
242ecca8a0bSMattias Rönnblom };
243ecca8a0bSMattias Rönnblom int rc;
244ecca8a0bSMattias Rönnblom
245ecca8a0bSMattias Rönnblom snprintf(service.name, sizeof(service.name), EVD_SERVICE_NAME);
246ecca8a0bSMattias Rönnblom
247ecca8a0bSMattias Rönnblom rc = rte_service_component_register(&service, &dispatcher->service_id);
248ecca8a0bSMattias Rönnblom if (rc != 0)
249ecca8a0bSMattias Rönnblom RTE_EDEV_LOG_ERR("Registration of dispatcher service "
250ae282b06SDavid Marchand "%s failed with error code %d",
251ecca8a0bSMattias Rönnblom service.name, rc);
252ecca8a0bSMattias Rönnblom
253ecca8a0bSMattias Rönnblom return rc;
254ecca8a0bSMattias Rönnblom }
255ecca8a0bSMattias Rönnblom
256ecca8a0bSMattias Rönnblom static int
evd_service_unregister(struct rte_dispatcher * dispatcher)257ecca8a0bSMattias Rönnblom evd_service_unregister(struct rte_dispatcher *dispatcher)
258ecca8a0bSMattias Rönnblom {
259ecca8a0bSMattias Rönnblom int rc;
260ecca8a0bSMattias Rönnblom
261ecca8a0bSMattias Rönnblom rc = rte_service_component_unregister(dispatcher->service_id);
262ecca8a0bSMattias Rönnblom if (rc != 0)
263ecca8a0bSMattias Rönnblom RTE_EDEV_LOG_ERR("Unregistration of dispatcher service "
264ae282b06SDavid Marchand "failed with error code %d", rc);
265ecca8a0bSMattias Rönnblom
266ecca8a0bSMattias Rönnblom return rc;
267ecca8a0bSMattias Rönnblom }
268ecca8a0bSMattias Rönnblom
269ecca8a0bSMattias Rönnblom struct rte_dispatcher *
rte_dispatcher_create(uint8_t event_dev_id)270ecca8a0bSMattias Rönnblom rte_dispatcher_create(uint8_t event_dev_id)
271ecca8a0bSMattias Rönnblom {
272ecca8a0bSMattias Rönnblom int socket_id;
273ecca8a0bSMattias Rönnblom struct rte_dispatcher *dispatcher;
274ecca8a0bSMattias Rönnblom int rc;
275ecca8a0bSMattias Rönnblom
276ecca8a0bSMattias Rönnblom socket_id = rte_event_dev_socket_id(event_dev_id);
277ecca8a0bSMattias Rönnblom
278ecca8a0bSMattias Rönnblom dispatcher =
279ecca8a0bSMattias Rönnblom rte_malloc_socket("dispatcher", sizeof(struct rte_dispatcher),
280ecca8a0bSMattias Rönnblom RTE_CACHE_LINE_SIZE, socket_id);
281ecca8a0bSMattias Rönnblom
282ecca8a0bSMattias Rönnblom if (dispatcher == NULL) {
283ae282b06SDavid Marchand RTE_EDEV_LOG_ERR("Unable to allocate memory for dispatcher");
284ecca8a0bSMattias Rönnblom rte_errno = ENOMEM;
285ecca8a0bSMattias Rönnblom return NULL;
286ecca8a0bSMattias Rönnblom }
287ecca8a0bSMattias Rönnblom
288ecca8a0bSMattias Rönnblom *dispatcher = (struct rte_dispatcher) {
289ecca8a0bSMattias Rönnblom .event_dev_id = event_dev_id,
290ecca8a0bSMattias Rönnblom .socket_id = socket_id
291ecca8a0bSMattias Rönnblom };
292ecca8a0bSMattias Rönnblom
293ecca8a0bSMattias Rönnblom rc = evd_service_register(dispatcher);
294ecca8a0bSMattias Rönnblom if (rc < 0) {
295ecca8a0bSMattias Rönnblom rte_free(dispatcher);
296ecca8a0bSMattias Rönnblom rte_errno = -rc;
297ecca8a0bSMattias Rönnblom return NULL;
298ecca8a0bSMattias Rönnblom }
299ecca8a0bSMattias Rönnblom
300ecca8a0bSMattias Rönnblom return dispatcher;
301ecca8a0bSMattias Rönnblom }
302ecca8a0bSMattias Rönnblom
303ecca8a0bSMattias Rönnblom int
rte_dispatcher_free(struct rte_dispatcher * dispatcher)304ecca8a0bSMattias Rönnblom rte_dispatcher_free(struct rte_dispatcher *dispatcher)
305ecca8a0bSMattias Rönnblom {
306ecca8a0bSMattias Rönnblom int rc;
307ecca8a0bSMattias Rönnblom
308ecca8a0bSMattias Rönnblom if (dispatcher == NULL)
309ecca8a0bSMattias Rönnblom return 0;
310ecca8a0bSMattias Rönnblom
311ecca8a0bSMattias Rönnblom rc = evd_service_unregister(dispatcher);
312ecca8a0bSMattias Rönnblom if (rc != 0)
313ecca8a0bSMattias Rönnblom return rc;
314ecca8a0bSMattias Rönnblom
315ecca8a0bSMattias Rönnblom rte_free(dispatcher);
316ecca8a0bSMattias Rönnblom
317ecca8a0bSMattias Rönnblom return 0;
318ecca8a0bSMattias Rönnblom }
319ecca8a0bSMattias Rönnblom
320ecca8a0bSMattias Rönnblom uint32_t
rte_dispatcher_service_id_get(const struct rte_dispatcher * dispatcher)321ecca8a0bSMattias Rönnblom rte_dispatcher_service_id_get(const struct rte_dispatcher *dispatcher)
322ecca8a0bSMattias Rönnblom {
323ecca8a0bSMattias Rönnblom return dispatcher->service_id;
324ecca8a0bSMattias Rönnblom }
325ecca8a0bSMattias Rönnblom
326ecca8a0bSMattias Rönnblom static int
lcore_port_index(struct rte_dispatcher_lcore * lcore,uint8_t event_port_id)327ecca8a0bSMattias Rönnblom lcore_port_index(struct rte_dispatcher_lcore *lcore,
328ecca8a0bSMattias Rönnblom uint8_t event_port_id)
329ecca8a0bSMattias Rönnblom {
330ecca8a0bSMattias Rönnblom uint16_t i;
331ecca8a0bSMattias Rönnblom
332ecca8a0bSMattias Rönnblom for (i = 0; i < lcore->num_ports; i++) {
333ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port *port =
334ecca8a0bSMattias Rönnblom &lcore->ports[i];
335ecca8a0bSMattias Rönnblom
336ecca8a0bSMattias Rönnblom if (port->port_id == event_port_id)
337ecca8a0bSMattias Rönnblom return i;
338ecca8a0bSMattias Rönnblom }
339ecca8a0bSMattias Rönnblom
340ecca8a0bSMattias Rönnblom return -1;
341ecca8a0bSMattias Rönnblom }
342ecca8a0bSMattias Rönnblom
343ecca8a0bSMattias Rönnblom int
rte_dispatcher_bind_port_to_lcore(struct rte_dispatcher * dispatcher,uint8_t event_port_id,uint16_t batch_size,uint64_t timeout,unsigned int lcore_id)344ecca8a0bSMattias Rönnblom rte_dispatcher_bind_port_to_lcore(struct rte_dispatcher *dispatcher,
345ecca8a0bSMattias Rönnblom uint8_t event_port_id, uint16_t batch_size, uint64_t timeout,
346ecca8a0bSMattias Rönnblom unsigned int lcore_id)
347ecca8a0bSMattias Rönnblom {
348ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore;
349ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port *port;
350ecca8a0bSMattias Rönnblom
351ecca8a0bSMattias Rönnblom lcore = &dispatcher->lcores[lcore_id];
352ecca8a0bSMattias Rönnblom
353ecca8a0bSMattias Rönnblom if (lcore->num_ports == EVD_MAX_PORTS_PER_LCORE)
354ecca8a0bSMattias Rönnblom return -ENOMEM;
355ecca8a0bSMattias Rönnblom
356ecca8a0bSMattias Rönnblom if (lcore_port_index(lcore, event_port_id) >= 0)
357ecca8a0bSMattias Rönnblom return -EEXIST;
358ecca8a0bSMattias Rönnblom
359ecca8a0bSMattias Rönnblom port = &lcore->ports[lcore->num_ports];
360ecca8a0bSMattias Rönnblom
361ecca8a0bSMattias Rönnblom *port = (struct rte_dispatcher_lcore_port) {
362ecca8a0bSMattias Rönnblom .port_id = event_port_id,
363ecca8a0bSMattias Rönnblom .batch_size = batch_size,
364ecca8a0bSMattias Rönnblom .timeout = timeout
365ecca8a0bSMattias Rönnblom };
366ecca8a0bSMattias Rönnblom
367ecca8a0bSMattias Rönnblom lcore->num_ports++;
368ecca8a0bSMattias Rönnblom
369ecca8a0bSMattias Rönnblom return 0;
370ecca8a0bSMattias Rönnblom }
371ecca8a0bSMattias Rönnblom
372ecca8a0bSMattias Rönnblom int
rte_dispatcher_unbind_port_from_lcore(struct rte_dispatcher * dispatcher,uint8_t event_port_id,unsigned int lcore_id)373ecca8a0bSMattias Rönnblom rte_dispatcher_unbind_port_from_lcore(struct rte_dispatcher *dispatcher,
374ecca8a0bSMattias Rönnblom uint8_t event_port_id, unsigned int lcore_id)
375ecca8a0bSMattias Rönnblom {
376ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore;
377ecca8a0bSMattias Rönnblom int port_idx;
378ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port *port;
379ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore_port *last;
380ecca8a0bSMattias Rönnblom
381ecca8a0bSMattias Rönnblom lcore = &dispatcher->lcores[lcore_id];
382ecca8a0bSMattias Rönnblom
383ecca8a0bSMattias Rönnblom port_idx = lcore_port_index(lcore, event_port_id);
384ecca8a0bSMattias Rönnblom
385ecca8a0bSMattias Rönnblom if (port_idx < 0)
386ecca8a0bSMattias Rönnblom return -ENOENT;
387ecca8a0bSMattias Rönnblom
388ecca8a0bSMattias Rönnblom port = &lcore->ports[port_idx];
389ecca8a0bSMattias Rönnblom last = &lcore->ports[lcore->num_ports - 1];
390ecca8a0bSMattias Rönnblom
391ecca8a0bSMattias Rönnblom if (port != last)
392ecca8a0bSMattias Rönnblom *port = *last;
393ecca8a0bSMattias Rönnblom
394ecca8a0bSMattias Rönnblom lcore->num_ports--;
395ecca8a0bSMattias Rönnblom
396ecca8a0bSMattias Rönnblom return 0;
397ecca8a0bSMattias Rönnblom }
398ecca8a0bSMattias Rönnblom
399ecca8a0bSMattias Rönnblom static struct rte_dispatcher_handler *
evd_lcore_get_handler_by_id(struct rte_dispatcher_lcore * lcore,int handler_id)400ecca8a0bSMattias Rönnblom evd_lcore_get_handler_by_id(struct rte_dispatcher_lcore *lcore, int handler_id)
401ecca8a0bSMattias Rönnblom {
402ecca8a0bSMattias Rönnblom uint16_t i;
403ecca8a0bSMattias Rönnblom
404ecca8a0bSMattias Rönnblom for (i = 0; i < lcore->num_handlers; i++) {
405ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler *handler =
406ecca8a0bSMattias Rönnblom &lcore->handlers[i];
407ecca8a0bSMattias Rönnblom
408ecca8a0bSMattias Rönnblom if (handler->id == handler_id)
409ecca8a0bSMattias Rönnblom return handler;
410ecca8a0bSMattias Rönnblom }
411ecca8a0bSMattias Rönnblom
412ecca8a0bSMattias Rönnblom return NULL;
413ecca8a0bSMattias Rönnblom }
414ecca8a0bSMattias Rönnblom
415ecca8a0bSMattias Rönnblom static int
evd_alloc_handler_id(struct rte_dispatcher * dispatcher)416ecca8a0bSMattias Rönnblom evd_alloc_handler_id(struct rte_dispatcher *dispatcher)
417ecca8a0bSMattias Rönnblom {
418ecca8a0bSMattias Rönnblom int handler_id = 0;
419ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *reference_lcore =
420ecca8a0bSMattias Rönnblom &dispatcher->lcores[0];
421ecca8a0bSMattias Rönnblom
422ecca8a0bSMattias Rönnblom if (reference_lcore->num_handlers == EVD_MAX_HANDLERS)
423ecca8a0bSMattias Rönnblom return -1;
424ecca8a0bSMattias Rönnblom
425ecca8a0bSMattias Rönnblom while (evd_lcore_get_handler_by_id(reference_lcore, handler_id) != NULL)
426ecca8a0bSMattias Rönnblom handler_id++;
427ecca8a0bSMattias Rönnblom
428ecca8a0bSMattias Rönnblom return handler_id;
429ecca8a0bSMattias Rönnblom }
430ecca8a0bSMattias Rönnblom
431ecca8a0bSMattias Rönnblom static void
evd_lcore_install_handler(struct rte_dispatcher_lcore * lcore,const struct rte_dispatcher_handler * handler)432ecca8a0bSMattias Rönnblom evd_lcore_install_handler(struct rte_dispatcher_lcore *lcore,
433ecca8a0bSMattias Rönnblom const struct rte_dispatcher_handler *handler)
434ecca8a0bSMattias Rönnblom {
435ecca8a0bSMattias Rönnblom int handler_idx = lcore->num_handlers;
436ecca8a0bSMattias Rönnblom
437ecca8a0bSMattias Rönnblom lcore->handlers[handler_idx] = *handler;
438ecca8a0bSMattias Rönnblom lcore->num_handlers++;
439ecca8a0bSMattias Rönnblom }
440ecca8a0bSMattias Rönnblom
441ecca8a0bSMattias Rönnblom static void
evd_install_handler(struct rte_dispatcher * dispatcher,const struct rte_dispatcher_handler * handler)442ecca8a0bSMattias Rönnblom evd_install_handler(struct rte_dispatcher *dispatcher,
443ecca8a0bSMattias Rönnblom const struct rte_dispatcher_handler *handler)
444ecca8a0bSMattias Rönnblom {
445ecca8a0bSMattias Rönnblom int i;
446ecca8a0bSMattias Rönnblom
447ecca8a0bSMattias Rönnblom for (i = 0; i < RTE_MAX_LCORE; i++) {
448ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore =
449ecca8a0bSMattias Rönnblom &dispatcher->lcores[i];
450ecca8a0bSMattias Rönnblom evd_lcore_install_handler(lcore, handler);
451ecca8a0bSMattias Rönnblom }
452ecca8a0bSMattias Rönnblom }
453ecca8a0bSMattias Rönnblom
454ecca8a0bSMattias Rönnblom int
rte_dispatcher_register(struct rte_dispatcher * dispatcher,rte_dispatcher_match_t match_fun,void * match_data,rte_dispatcher_process_t process_fun,void * process_data)455ecca8a0bSMattias Rönnblom rte_dispatcher_register(struct rte_dispatcher *dispatcher,
456ecca8a0bSMattias Rönnblom rte_dispatcher_match_t match_fun, void *match_data,
457ecca8a0bSMattias Rönnblom rte_dispatcher_process_t process_fun, void *process_data)
458ecca8a0bSMattias Rönnblom {
459ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler handler = {
460ecca8a0bSMattias Rönnblom .match_fun = match_fun,
461ecca8a0bSMattias Rönnblom .match_data = match_data,
462ecca8a0bSMattias Rönnblom .process_fun = process_fun,
463ecca8a0bSMattias Rönnblom .process_data = process_data
464ecca8a0bSMattias Rönnblom };
465ecca8a0bSMattias Rönnblom
466ecca8a0bSMattias Rönnblom handler.id = evd_alloc_handler_id(dispatcher);
467ecca8a0bSMattias Rönnblom
468ecca8a0bSMattias Rönnblom if (handler.id < 0)
469ecca8a0bSMattias Rönnblom return -ENOMEM;
470ecca8a0bSMattias Rönnblom
471ecca8a0bSMattias Rönnblom evd_install_handler(dispatcher, &handler);
472ecca8a0bSMattias Rönnblom
473ecca8a0bSMattias Rönnblom return handler.id;
474ecca8a0bSMattias Rönnblom }
475ecca8a0bSMattias Rönnblom
476ecca8a0bSMattias Rönnblom static int
evd_lcore_uninstall_handler(struct rte_dispatcher_lcore * lcore,int handler_id)477ecca8a0bSMattias Rönnblom evd_lcore_uninstall_handler(struct rte_dispatcher_lcore *lcore,
478ecca8a0bSMattias Rönnblom int handler_id)
479ecca8a0bSMattias Rönnblom {
480ecca8a0bSMattias Rönnblom struct rte_dispatcher_handler *unreg_handler;
481ecca8a0bSMattias Rönnblom int handler_idx;
482ecca8a0bSMattias Rönnblom uint16_t last_idx;
483ecca8a0bSMattias Rönnblom
484ecca8a0bSMattias Rönnblom unreg_handler = evd_lcore_get_handler_by_id(lcore, handler_id);
485ecca8a0bSMattias Rönnblom
486ecca8a0bSMattias Rönnblom if (unreg_handler == NULL) {
487ae282b06SDavid Marchand RTE_EDEV_LOG_ERR("Invalid handler id %d", handler_id);
488ecca8a0bSMattias Rönnblom return -EINVAL;
489ecca8a0bSMattias Rönnblom }
490ecca8a0bSMattias Rönnblom
491ecca8a0bSMattias Rönnblom handler_idx = unreg_handler - &lcore->handlers[0];
492ecca8a0bSMattias Rönnblom
493ecca8a0bSMattias Rönnblom last_idx = lcore->num_handlers - 1;
494ecca8a0bSMattias Rönnblom
495ecca8a0bSMattias Rönnblom if (handler_idx != last_idx) {
496ecca8a0bSMattias Rönnblom /* move all handlers to maintain handler order */
497ecca8a0bSMattias Rönnblom int n = last_idx - handler_idx;
498ecca8a0bSMattias Rönnblom memmove(unreg_handler, unreg_handler + 1,
499ecca8a0bSMattias Rönnblom sizeof(struct rte_dispatcher_handler) * n);
500ecca8a0bSMattias Rönnblom }
501ecca8a0bSMattias Rönnblom
502ecca8a0bSMattias Rönnblom lcore->num_handlers--;
503ecca8a0bSMattias Rönnblom
504ecca8a0bSMattias Rönnblom return 0;
505ecca8a0bSMattias Rönnblom }
506ecca8a0bSMattias Rönnblom
507ecca8a0bSMattias Rönnblom static int
evd_uninstall_handler(struct rte_dispatcher * dispatcher,int handler_id)508ecca8a0bSMattias Rönnblom evd_uninstall_handler(struct rte_dispatcher *dispatcher, int handler_id)
509ecca8a0bSMattias Rönnblom {
510ecca8a0bSMattias Rönnblom unsigned int lcore_id;
511ecca8a0bSMattias Rönnblom
512ecca8a0bSMattias Rönnblom for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
513ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore =
514ecca8a0bSMattias Rönnblom &dispatcher->lcores[lcore_id];
515ecca8a0bSMattias Rönnblom int rc;
516ecca8a0bSMattias Rönnblom
517ecca8a0bSMattias Rönnblom rc = evd_lcore_uninstall_handler(lcore, handler_id);
518ecca8a0bSMattias Rönnblom if (rc < 0)
519ecca8a0bSMattias Rönnblom return rc;
520ecca8a0bSMattias Rönnblom }
521ecca8a0bSMattias Rönnblom
522ecca8a0bSMattias Rönnblom return 0;
523ecca8a0bSMattias Rönnblom }
524ecca8a0bSMattias Rönnblom
525ecca8a0bSMattias Rönnblom int
rte_dispatcher_unregister(struct rte_dispatcher * dispatcher,int handler_id)526ecca8a0bSMattias Rönnblom rte_dispatcher_unregister(struct rte_dispatcher *dispatcher, int handler_id)
527ecca8a0bSMattias Rönnblom {
528ecca8a0bSMattias Rönnblom return evd_uninstall_handler(dispatcher, handler_id);
529ecca8a0bSMattias Rönnblom }
530ecca8a0bSMattias Rönnblom
531ecca8a0bSMattias Rönnblom static struct rte_dispatcher_finalizer *
evd_get_finalizer_by_id(struct rte_dispatcher * dispatcher,int handler_id)532ecca8a0bSMattias Rönnblom evd_get_finalizer_by_id(struct rte_dispatcher *dispatcher,
533ecca8a0bSMattias Rönnblom int handler_id)
534ecca8a0bSMattias Rönnblom {
535ecca8a0bSMattias Rönnblom int i;
536ecca8a0bSMattias Rönnblom
537ecca8a0bSMattias Rönnblom for (i = 0; i < dispatcher->num_finalizers; i++) {
538ecca8a0bSMattias Rönnblom struct rte_dispatcher_finalizer *finalizer =
539ecca8a0bSMattias Rönnblom &dispatcher->finalizers[i];
540ecca8a0bSMattias Rönnblom
541ecca8a0bSMattias Rönnblom if (finalizer->id == handler_id)
542ecca8a0bSMattias Rönnblom return finalizer;
543ecca8a0bSMattias Rönnblom }
544ecca8a0bSMattias Rönnblom
545ecca8a0bSMattias Rönnblom return NULL;
546ecca8a0bSMattias Rönnblom }
547ecca8a0bSMattias Rönnblom
548ecca8a0bSMattias Rönnblom static int
evd_alloc_finalizer_id(struct rte_dispatcher * dispatcher)549ecca8a0bSMattias Rönnblom evd_alloc_finalizer_id(struct rte_dispatcher *dispatcher)
550ecca8a0bSMattias Rönnblom {
551ecca8a0bSMattias Rönnblom int finalizer_id = 0;
552ecca8a0bSMattias Rönnblom
553ecca8a0bSMattias Rönnblom while (evd_get_finalizer_by_id(dispatcher, finalizer_id) != NULL)
554ecca8a0bSMattias Rönnblom finalizer_id++;
555ecca8a0bSMattias Rönnblom
556ecca8a0bSMattias Rönnblom return finalizer_id;
557ecca8a0bSMattias Rönnblom }
558ecca8a0bSMattias Rönnblom
559ecca8a0bSMattias Rönnblom static struct rte_dispatcher_finalizer *
evd_alloc_finalizer(struct rte_dispatcher * dispatcher)560ecca8a0bSMattias Rönnblom evd_alloc_finalizer(struct rte_dispatcher *dispatcher)
561ecca8a0bSMattias Rönnblom {
562ecca8a0bSMattias Rönnblom int finalizer_idx;
563ecca8a0bSMattias Rönnblom struct rte_dispatcher_finalizer *finalizer;
564ecca8a0bSMattias Rönnblom
565ecca8a0bSMattias Rönnblom if (dispatcher->num_finalizers == EVD_MAX_FINALIZERS)
566ecca8a0bSMattias Rönnblom return NULL;
567ecca8a0bSMattias Rönnblom
568ecca8a0bSMattias Rönnblom finalizer_idx = dispatcher->num_finalizers;
569ecca8a0bSMattias Rönnblom finalizer = &dispatcher->finalizers[finalizer_idx];
570ecca8a0bSMattias Rönnblom
571ecca8a0bSMattias Rönnblom finalizer->id = evd_alloc_finalizer_id(dispatcher);
572ecca8a0bSMattias Rönnblom
573ecca8a0bSMattias Rönnblom dispatcher->num_finalizers++;
574ecca8a0bSMattias Rönnblom
575ecca8a0bSMattias Rönnblom return finalizer;
576ecca8a0bSMattias Rönnblom }
577ecca8a0bSMattias Rönnblom
578ecca8a0bSMattias Rönnblom int
rte_dispatcher_finalize_register(struct rte_dispatcher * dispatcher,rte_dispatcher_finalize_t finalize_fun,void * finalize_data)579ecca8a0bSMattias Rönnblom rte_dispatcher_finalize_register(struct rte_dispatcher *dispatcher,
580ecca8a0bSMattias Rönnblom rte_dispatcher_finalize_t finalize_fun, void *finalize_data)
581ecca8a0bSMattias Rönnblom {
582ecca8a0bSMattias Rönnblom struct rte_dispatcher_finalizer *finalizer;
583ecca8a0bSMattias Rönnblom
584ecca8a0bSMattias Rönnblom finalizer = evd_alloc_finalizer(dispatcher);
585ecca8a0bSMattias Rönnblom
586ecca8a0bSMattias Rönnblom if (finalizer == NULL)
587ecca8a0bSMattias Rönnblom return -ENOMEM;
588ecca8a0bSMattias Rönnblom
589ecca8a0bSMattias Rönnblom finalizer->finalize_fun = finalize_fun;
590ecca8a0bSMattias Rönnblom finalizer->finalize_data = finalize_data;
591ecca8a0bSMattias Rönnblom
592ecca8a0bSMattias Rönnblom return finalizer->id;
593ecca8a0bSMattias Rönnblom }
594ecca8a0bSMattias Rönnblom
595ecca8a0bSMattias Rönnblom int
rte_dispatcher_finalize_unregister(struct rte_dispatcher * dispatcher,int finalizer_id)596ecca8a0bSMattias Rönnblom rte_dispatcher_finalize_unregister(struct rte_dispatcher *dispatcher,
597ecca8a0bSMattias Rönnblom int finalizer_id)
598ecca8a0bSMattias Rönnblom {
599ecca8a0bSMattias Rönnblom struct rte_dispatcher_finalizer *unreg_finalizer;
600ecca8a0bSMattias Rönnblom int finalizer_idx;
601ecca8a0bSMattias Rönnblom uint16_t last_idx;
602ecca8a0bSMattias Rönnblom
603ecca8a0bSMattias Rönnblom unreg_finalizer = evd_get_finalizer_by_id(dispatcher, finalizer_id);
604ecca8a0bSMattias Rönnblom
605ecca8a0bSMattias Rönnblom if (unreg_finalizer == NULL) {
606ae282b06SDavid Marchand RTE_EDEV_LOG_ERR("Invalid finalizer id %d", finalizer_id);
607ecca8a0bSMattias Rönnblom return -EINVAL;
608ecca8a0bSMattias Rönnblom }
609ecca8a0bSMattias Rönnblom
610ecca8a0bSMattias Rönnblom finalizer_idx = unreg_finalizer - &dispatcher->finalizers[0];
611ecca8a0bSMattias Rönnblom
612ecca8a0bSMattias Rönnblom last_idx = dispatcher->num_finalizers - 1;
613ecca8a0bSMattias Rönnblom
614ecca8a0bSMattias Rönnblom if (finalizer_idx != last_idx) {
615ecca8a0bSMattias Rönnblom /* move all finalizers to maintain order */
616ecca8a0bSMattias Rönnblom int n = last_idx - finalizer_idx;
617ecca8a0bSMattias Rönnblom memmove(unreg_finalizer, unreg_finalizer + 1,
618ecca8a0bSMattias Rönnblom sizeof(struct rte_dispatcher_finalizer) * n);
619ecca8a0bSMattias Rönnblom }
620ecca8a0bSMattias Rönnblom
621ecca8a0bSMattias Rönnblom dispatcher->num_finalizers--;
622ecca8a0bSMattias Rönnblom
623ecca8a0bSMattias Rönnblom return 0;
624ecca8a0bSMattias Rönnblom }
625ecca8a0bSMattias Rönnblom
626ecca8a0bSMattias Rönnblom static void
evd_set_service_runstate(struct rte_dispatcher * dispatcher,int state)627ecca8a0bSMattias Rönnblom evd_set_service_runstate(struct rte_dispatcher *dispatcher, int state)
628ecca8a0bSMattias Rönnblom {
629ecca8a0bSMattias Rönnblom int rc;
630ecca8a0bSMattias Rönnblom
631ecca8a0bSMattias Rönnblom rc = rte_service_component_runstate_set(dispatcher->service_id,
632ecca8a0bSMattias Rönnblom state);
633ecca8a0bSMattias Rönnblom /*
634ecca8a0bSMattias Rönnblom * The only cause of a runstate_set() failure is an invalid
635ecca8a0bSMattias Rönnblom * service id, which in turns means the dispatcher instance's
636ecca8a0bSMattias Rönnblom * state is invalid.
637ecca8a0bSMattias Rönnblom */
638ecca8a0bSMattias Rönnblom if (rc != 0)
639ecca8a0bSMattias Rönnblom RTE_EDEV_LOG_ERR("Unexpected error %d occurred while setting "
640ae282b06SDavid Marchand "service component run state to %d", rc,
641ecca8a0bSMattias Rönnblom state);
642ecca8a0bSMattias Rönnblom
643ecca8a0bSMattias Rönnblom RTE_VERIFY(rc == 0);
644ecca8a0bSMattias Rönnblom }
645ecca8a0bSMattias Rönnblom
646ecca8a0bSMattias Rönnblom void
rte_dispatcher_start(struct rte_dispatcher * dispatcher)647ecca8a0bSMattias Rönnblom rte_dispatcher_start(struct rte_dispatcher *dispatcher)
648ecca8a0bSMattias Rönnblom {
649ecca8a0bSMattias Rönnblom evd_set_service_runstate(dispatcher, 1);
650ecca8a0bSMattias Rönnblom }
651ecca8a0bSMattias Rönnblom
652ecca8a0bSMattias Rönnblom void
rte_dispatcher_stop(struct rte_dispatcher * dispatcher)653ecca8a0bSMattias Rönnblom rte_dispatcher_stop(struct rte_dispatcher *dispatcher)
654ecca8a0bSMattias Rönnblom {
655ecca8a0bSMattias Rönnblom evd_set_service_runstate(dispatcher, 0);
656ecca8a0bSMattias Rönnblom }
657ecca8a0bSMattias Rönnblom
658ecca8a0bSMattias Rönnblom static void
evd_aggregate_stats(struct rte_dispatcher_stats * result,const struct rte_dispatcher_stats * part)659ecca8a0bSMattias Rönnblom evd_aggregate_stats(struct rte_dispatcher_stats *result,
660ecca8a0bSMattias Rönnblom const struct rte_dispatcher_stats *part)
661ecca8a0bSMattias Rönnblom {
662ecca8a0bSMattias Rönnblom result->poll_count += part->poll_count;
663ecca8a0bSMattias Rönnblom result->ev_batch_count += part->ev_batch_count;
664ecca8a0bSMattias Rönnblom result->ev_dispatch_count += part->ev_dispatch_count;
665ecca8a0bSMattias Rönnblom result->ev_drop_count += part->ev_drop_count;
666ecca8a0bSMattias Rönnblom }
667ecca8a0bSMattias Rönnblom
668ecca8a0bSMattias Rönnblom void
rte_dispatcher_stats_get(const struct rte_dispatcher * dispatcher,struct rte_dispatcher_stats * stats)669ecca8a0bSMattias Rönnblom rte_dispatcher_stats_get(const struct rte_dispatcher *dispatcher,
670ecca8a0bSMattias Rönnblom struct rte_dispatcher_stats *stats)
671ecca8a0bSMattias Rönnblom {
672ecca8a0bSMattias Rönnblom unsigned int lcore_id;
673ecca8a0bSMattias Rönnblom
674ecca8a0bSMattias Rönnblom *stats = (struct rte_dispatcher_stats) {};
675ecca8a0bSMattias Rönnblom
676ecca8a0bSMattias Rönnblom for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
677ecca8a0bSMattias Rönnblom const struct rte_dispatcher_lcore *lcore =
678ecca8a0bSMattias Rönnblom &dispatcher->lcores[lcore_id];
679ecca8a0bSMattias Rönnblom
680ecca8a0bSMattias Rönnblom evd_aggregate_stats(stats, &lcore->stats);
681ecca8a0bSMattias Rönnblom }
682ecca8a0bSMattias Rönnblom }
683ecca8a0bSMattias Rönnblom
684ecca8a0bSMattias Rönnblom void
rte_dispatcher_stats_reset(struct rte_dispatcher * dispatcher)685ecca8a0bSMattias Rönnblom rte_dispatcher_stats_reset(struct rte_dispatcher *dispatcher)
686ecca8a0bSMattias Rönnblom {
687ecca8a0bSMattias Rönnblom unsigned int lcore_id;
688ecca8a0bSMattias Rönnblom
689ecca8a0bSMattias Rönnblom for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
690ecca8a0bSMattias Rönnblom struct rte_dispatcher_lcore *lcore =
691ecca8a0bSMattias Rönnblom &dispatcher->lcores[lcore_id];
692ecca8a0bSMattias Rönnblom
693ecca8a0bSMattias Rönnblom lcore->stats = (struct rte_dispatcher_stats) {};
694ecca8a0bSMattias Rönnblom }
695ecca8a0bSMattias Rönnblom }
696