]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/lib/librte_eventdev/rte_event_timer_adapter.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / dpdk / lib / librte_eventdev / rte_event_timer_adapter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017-2018 Intel Corporation.
3 * All rights reserved.
4 */
5
6 #include <string.h>
7 #include <inttypes.h>
8 #include <stdbool.h>
9 #include <sys/queue.h>
10
11 #include <rte_memzone.h>
12 #include <rte_memory.h>
13 #include <rte_dev.h>
14 #include <rte_errno.h>
15 #include <rte_malloc.h>
16 #include <rte_ring.h>
17 #include <rte_mempool.h>
18 #include <rte_common.h>
19 #include <rte_timer.h>
20 #include <rte_service_component.h>
21 #include <rte_cycles.h>
22
23 #include "rte_eventdev.h"
24 #include "rte_eventdev_pmd.h"
25 #include "rte_event_timer_adapter.h"
26 #include "rte_event_timer_adapter_pmd.h"
27
28 #define DATA_MZ_NAME_MAX_LEN 64
29 #define DATA_MZ_NAME_FORMAT "rte_event_timer_adapter_data_%d"
30
31 static int evtim_logtype;
32 static int evtim_svc_logtype;
33 static int evtim_buffer_logtype;
34
35 static struct rte_event_timer_adapter adapters[RTE_EVENT_TIMER_ADAPTER_NUM_MAX];
36
37 static const struct rte_event_timer_adapter_ops sw_event_adapter_timer_ops;
38
39 #define EVTIM_LOG(level, logtype, ...) \
40 rte_log(RTE_LOG_ ## level, logtype, \
41 RTE_FMT("EVTIMER: %s() line %u: " RTE_FMT_HEAD(__VA_ARGS__,) \
42 "\n", __func__, __LINE__, RTE_FMT_TAIL(__VA_ARGS__,)))
43
44 #define EVTIM_LOG_ERR(...) EVTIM_LOG(ERR, evtim_logtype, __VA_ARGS__)
45
46 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
47 #define EVTIM_LOG_DBG(...) \
48 EVTIM_LOG(DEBUG, evtim_logtype, __VA_ARGS__)
49 #define EVTIM_BUF_LOG_DBG(...) \
50 EVTIM_LOG(DEBUG, evtim_buffer_logtype, __VA_ARGS__)
51 #define EVTIM_SVC_LOG_DBG(...) \
52 EVTIM_LOG(DEBUG, evtim_svc_logtype, __VA_ARGS__)
53 #else
54 #define EVTIM_LOG_DBG(...) (void)0
55 #define EVTIM_BUF_LOG_DBG(...) (void)0
56 #define EVTIM_SVC_LOG_DBG(...) (void)0
57 #endif
58
59 static int
60 default_port_conf_cb(uint16_t id, uint8_t event_dev_id, uint8_t *event_port_id,
61 void *conf_arg)
62 {
63 struct rte_event_timer_adapter *adapter;
64 struct rte_eventdev *dev;
65 struct rte_event_dev_config dev_conf;
66 struct rte_event_port_conf *port_conf, def_port_conf = {0};
67 int started;
68 uint8_t port_id;
69 uint8_t dev_id;
70 int ret;
71
72 RTE_SET_USED(event_dev_id);
73
74 adapter = &adapters[id];
75 dev = &rte_eventdevs[adapter->data->event_dev_id];
76 dev_id = dev->data->dev_id;
77 dev_conf = dev->data->dev_conf;
78
79 started = dev->data->dev_started;
80 if (started)
81 rte_event_dev_stop(dev_id);
82
83 port_id = dev_conf.nb_event_ports;
84 dev_conf.nb_event_ports += 1;
85 ret = rte_event_dev_configure(dev_id, &dev_conf);
86 if (ret < 0) {
87 EVTIM_LOG_ERR("failed to configure event dev %u\n", dev_id);
88 if (started)
89 if (rte_event_dev_start(dev_id))
90 return -EIO;
91
92 return ret;
93 }
94
95 if (conf_arg != NULL)
96 port_conf = conf_arg;
97 else {
98 port_conf = &def_port_conf;
99 ret = rte_event_port_default_conf_get(dev_id, port_id,
100 port_conf);
101 if (ret < 0)
102 return ret;
103 }
104
105 ret = rte_event_port_setup(dev_id, port_id, port_conf);
106 if (ret < 0) {
107 EVTIM_LOG_ERR("failed to setup event port %u on event dev %u\n",
108 port_id, dev_id);
109 return ret;
110 }
111
112 *event_port_id = port_id;
113
114 if (started)
115 ret = rte_event_dev_start(dev_id);
116
117 return ret;
118 }
119
120 struct rte_event_timer_adapter *
121 rte_event_timer_adapter_create(const struct rte_event_timer_adapter_conf *conf)
122 {
123 return rte_event_timer_adapter_create_ext(conf, default_port_conf_cb,
124 NULL);
125 }
126
127 struct rte_event_timer_adapter *
128 rte_event_timer_adapter_create_ext(
129 const struct rte_event_timer_adapter_conf *conf,
130 rte_event_timer_adapter_port_conf_cb_t conf_cb,
131 void *conf_arg)
132 {
133 uint16_t adapter_id;
134 struct rte_event_timer_adapter *adapter;
135 const struct rte_memzone *mz;
136 char mz_name[DATA_MZ_NAME_MAX_LEN];
137 int n, ret;
138 struct rte_eventdev *dev;
139
140 if (conf == NULL) {
141 rte_errno = EINVAL;
142 return NULL;
143 }
144
145 /* Check eventdev ID */
146 if (!rte_event_pmd_is_valid_dev(conf->event_dev_id)) {
147 rte_errno = EINVAL;
148 return NULL;
149 }
150 dev = &rte_eventdevs[conf->event_dev_id];
151
152 adapter_id = conf->timer_adapter_id;
153
154 /* Check that adapter_id is in range */
155 if (adapter_id >= RTE_EVENT_TIMER_ADAPTER_NUM_MAX) {
156 rte_errno = EINVAL;
157 return NULL;
158 }
159
160 /* Check adapter ID not already allocated */
161 adapter = &adapters[adapter_id];
162 if (adapter->allocated) {
163 rte_errno = EEXIST;
164 return NULL;
165 }
166
167 /* Create shared data area. */
168 n = snprintf(mz_name, sizeof(mz_name), DATA_MZ_NAME_FORMAT, adapter_id);
169 if (n >= (int)sizeof(mz_name)) {
170 rte_errno = EINVAL;
171 return NULL;
172 }
173 mz = rte_memzone_reserve(mz_name,
174 sizeof(struct rte_event_timer_adapter_data),
175 conf->socket_id, 0);
176 if (mz == NULL)
177 /* rte_errno set by rte_memzone_reserve */
178 return NULL;
179
180 adapter->data = mz->addr;
181 memset(adapter->data, 0, sizeof(struct rte_event_timer_adapter_data));
182
183 adapter->data->mz = mz;
184 adapter->data->event_dev_id = conf->event_dev_id;
185 adapter->data->id = adapter_id;
186 adapter->data->socket_id = conf->socket_id;
187 adapter->data->conf = *conf; /* copy conf structure */
188
189 /* Query eventdev PMD for timer adapter capabilities and ops */
190 ret = dev->dev_ops->timer_adapter_caps_get(dev,
191 adapter->data->conf.flags,
192 &adapter->data->caps,
193 &adapter->ops);
194 if (ret < 0) {
195 rte_errno = ret;
196 goto free_memzone;
197 }
198
199 if (!(adapter->data->caps &
200 RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT)) {
201 FUNC_PTR_OR_NULL_RET_WITH_ERRNO(conf_cb, -EINVAL);
202 ret = conf_cb(adapter->data->id, adapter->data->event_dev_id,
203 &adapter->data->event_port_id, conf_arg);
204 if (ret < 0) {
205 rte_errno = ret;
206 goto free_memzone;
207 }
208 }
209
210 /* If eventdev PMD did not provide ops, use default software
211 * implementation.
212 */
213 if (adapter->ops == NULL)
214 adapter->ops = &sw_event_adapter_timer_ops;
215
216 /* Allow driver to do some setup */
217 FUNC_PTR_OR_NULL_RET_WITH_ERRNO(adapter->ops->init, -ENOTSUP);
218 ret = adapter->ops->init(adapter);
219 if (ret < 0) {
220 rte_errno = ret;
221 goto free_memzone;
222 }
223
224 /* Set fast-path function pointers */
225 adapter->arm_burst = adapter->ops->arm_burst;
226 adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst;
227 adapter->cancel_burst = adapter->ops->cancel_burst;
228
229 adapter->allocated = 1;
230
231 return adapter;
232
233 free_memzone:
234 rte_memzone_free(adapter->data->mz);
235 return NULL;
236 }
237
238 int
239 rte_event_timer_adapter_get_info(const struct rte_event_timer_adapter *adapter,
240 struct rte_event_timer_adapter_info *adapter_info)
241 {
242 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
243
244 if (adapter->ops->get_info)
245 /* let driver set values it knows */
246 adapter->ops->get_info(adapter, adapter_info);
247
248 /* Set common values */
249 adapter_info->conf = adapter->data->conf;
250 adapter_info->event_dev_port_id = adapter->data->event_port_id;
251 adapter_info->caps = adapter->data->caps;
252
253 return 0;
254 }
255
256 int
257 rte_event_timer_adapter_start(const struct rte_event_timer_adapter *adapter)
258 {
259 int ret;
260
261 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
262 FUNC_PTR_OR_ERR_RET(adapter->ops->start, -EINVAL);
263
264 if (adapter->data->started) {
265 EVTIM_LOG_ERR("event timer adapter %"PRIu8" already started",
266 adapter->data->id);
267 return -EALREADY;
268 }
269
270 ret = adapter->ops->start(adapter);
271 if (ret < 0)
272 return ret;
273
274 adapter->data->started = 1;
275
276 return 0;
277 }
278
279 int
280 rte_event_timer_adapter_stop(const struct rte_event_timer_adapter *adapter)
281 {
282 int ret;
283
284 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
285 FUNC_PTR_OR_ERR_RET(adapter->ops->stop, -EINVAL);
286
287 if (adapter->data->started == 0) {
288 EVTIM_LOG_ERR("event timer adapter %"PRIu8" already stopped",
289 adapter->data->id);
290 return 0;
291 }
292
293 ret = adapter->ops->stop(adapter);
294 if (ret < 0)
295 return ret;
296
297 adapter->data->started = 0;
298
299 return 0;
300 }
301
302 struct rte_event_timer_adapter *
303 rte_event_timer_adapter_lookup(uint16_t adapter_id)
304 {
305 char name[DATA_MZ_NAME_MAX_LEN];
306 const struct rte_memzone *mz;
307 struct rte_event_timer_adapter_data *data;
308 struct rte_event_timer_adapter *adapter;
309 int ret;
310 struct rte_eventdev *dev;
311
312 if (adapters[adapter_id].allocated)
313 return &adapters[adapter_id]; /* Adapter is already loaded */
314
315 snprintf(name, DATA_MZ_NAME_MAX_LEN, DATA_MZ_NAME_FORMAT, adapter_id);
316 mz = rte_memzone_lookup(name);
317 if (mz == NULL) {
318 rte_errno = ENOENT;
319 return NULL;
320 }
321
322 data = mz->addr;
323
324 adapter = &adapters[data->id];
325 adapter->data = data;
326
327 dev = &rte_eventdevs[adapter->data->event_dev_id];
328
329 /* Query eventdev PMD for timer adapter capabilities and ops */
330 ret = dev->dev_ops->timer_adapter_caps_get(dev,
331 adapter->data->conf.flags,
332 &adapter->data->caps,
333 &adapter->ops);
334 if (ret < 0) {
335 rte_errno = EINVAL;
336 return NULL;
337 }
338
339 /* If eventdev PMD did not provide ops, use default software
340 * implementation.
341 */
342 if (adapter->ops == NULL)
343 adapter->ops = &sw_event_adapter_timer_ops;
344
345 /* Set fast-path function pointers */
346 adapter->arm_burst = adapter->ops->arm_burst;
347 adapter->arm_tmo_tick_burst = adapter->ops->arm_tmo_tick_burst;
348 adapter->cancel_burst = adapter->ops->cancel_burst;
349
350 adapter->allocated = 1;
351
352 return adapter;
353 }
354
355 int
356 rte_event_timer_adapter_free(struct rte_event_timer_adapter *adapter)
357 {
358 int ret;
359
360 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
361 FUNC_PTR_OR_ERR_RET(adapter->ops->uninit, -EINVAL);
362
363 if (adapter->data->started == 1) {
364 EVTIM_LOG_ERR("event timer adapter %"PRIu8" must be stopped "
365 "before freeing", adapter->data->id);
366 return -EBUSY;
367 }
368
369 /* free impl priv data */
370 ret = adapter->ops->uninit(adapter);
371 if (ret < 0)
372 return ret;
373
374 /* free shared data area */
375 ret = rte_memzone_free(adapter->data->mz);
376 if (ret < 0)
377 return ret;
378
379 adapter->data = NULL;
380 adapter->allocated = 0;
381
382 return 0;
383 }
384
385 int
386 rte_event_timer_adapter_service_id_get(struct rte_event_timer_adapter *adapter,
387 uint32_t *service_id)
388 {
389 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
390
391 if (adapter->data->service_inited && service_id != NULL)
392 *service_id = adapter->data->service_id;
393
394 return adapter->data->service_inited ? 0 : -ESRCH;
395 }
396
397 int
398 rte_event_timer_adapter_stats_get(struct rte_event_timer_adapter *adapter,
399 struct rte_event_timer_adapter_stats *stats)
400 {
401 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
402 FUNC_PTR_OR_ERR_RET(adapter->ops->stats_get, -EINVAL);
403 if (stats == NULL)
404 return -EINVAL;
405
406 return adapter->ops->stats_get(adapter, stats);
407 }
408
409 int
410 rte_event_timer_adapter_stats_reset(struct rte_event_timer_adapter *adapter)
411 {
412 ADAPTER_VALID_OR_ERR_RET(adapter, -EINVAL);
413 FUNC_PTR_OR_ERR_RET(adapter->ops->stats_reset, -EINVAL);
414 return adapter->ops->stats_reset(adapter);
415 }
416
417 /*
418 * Software event timer adapter buffer helper functions
419 */
420
421 #define NSECPERSEC 1E9
422
423 /* Optimizations used to index into the buffer require that the buffer size
424 * be a power of 2.
425 */
426 #define EVENT_BUFFER_SZ 4096
427 #define EVENT_BUFFER_BATCHSZ 32
428 #define EVENT_BUFFER_MASK (EVENT_BUFFER_SZ - 1)
429
430 struct event_buffer {
431 uint16_t head;
432 uint16_t tail;
433 struct rte_event events[EVENT_BUFFER_SZ];
434 } __rte_cache_aligned;
435
436 static inline bool
437 event_buffer_full(struct event_buffer *bufp)
438 {
439 return (bufp->head - bufp->tail) == EVENT_BUFFER_SZ;
440 }
441
442 static inline bool
443 event_buffer_batch_ready(struct event_buffer *bufp)
444 {
445 return (bufp->head - bufp->tail) >= EVENT_BUFFER_BATCHSZ;
446 }
447
448 static void
449 event_buffer_init(struct event_buffer *bufp)
450 {
451 bufp->head = bufp->tail = 0;
452 memset(&bufp->events, 0, sizeof(struct rte_event) * EVENT_BUFFER_SZ);
453 }
454
455 static int
456 event_buffer_add(struct event_buffer *bufp, struct rte_event *eventp)
457 {
458 uint16_t head_idx;
459 struct rte_event *buf_eventp;
460
461 if (event_buffer_full(bufp))
462 return -1;
463
464 /* Instead of modulus, bitwise AND with mask to get head_idx. */
465 head_idx = bufp->head & EVENT_BUFFER_MASK;
466 buf_eventp = &bufp->events[head_idx];
467 rte_memcpy(buf_eventp, eventp, sizeof(struct rte_event));
468
469 /* Wrap automatically when overflow occurs. */
470 bufp->head++;
471
472 return 0;
473 }
474
475 static void
476 event_buffer_flush(struct event_buffer *bufp, uint8_t dev_id, uint8_t port_id,
477 uint16_t *nb_events_flushed,
478 uint16_t *nb_events_inv)
479 {
480 uint16_t head_idx, tail_idx, n = 0;
481 struct rte_event *events = bufp->events;
482
483 /* Instead of modulus, bitwise AND with mask to get index. */
484 head_idx = bufp->head & EVENT_BUFFER_MASK;
485 tail_idx = bufp->tail & EVENT_BUFFER_MASK;
486
487 /* Determine the largest contigous run we can attempt to enqueue to the
488 * event device.
489 */
490 if (head_idx > tail_idx)
491 n = head_idx - tail_idx;
492 else if (head_idx < tail_idx)
493 n = EVENT_BUFFER_SZ - tail_idx;
494 else {
495 *nb_events_flushed = 0;
496 return;
497 }
498
499 *nb_events_inv = 0;
500 *nb_events_flushed = rte_event_enqueue_burst(dev_id, port_id,
501 &events[tail_idx], n);
502 if (*nb_events_flushed != n && rte_errno == -EINVAL) {
503 EVTIM_LOG_ERR("failed to enqueue invalid event - dropping it");
504 (*nb_events_inv)++;
505 }
506
507 bufp->tail = bufp->tail + *nb_events_flushed + *nb_events_inv;
508 }
509
510 /*
511 * Software event timer adapter implementation
512 */
513
514 struct rte_event_timer_adapter_sw_data {
515 /* List of messages for outstanding timers */
516 TAILQ_HEAD(, msg) msgs_tailq_head;
517 /* Lock to guard tailq and armed count */
518 rte_spinlock_t msgs_tailq_sl;
519 /* Identifier of service executing timer management logic. */
520 uint32_t service_id;
521 /* The cycle count at which the adapter should next tick */
522 uint64_t next_tick_cycles;
523 /* Incremented as the service moves through phases of an iteration */
524 volatile int service_phase;
525 /* The tick resolution used by adapter instance. May have been
526 * adjusted from what user requested
527 */
528 uint64_t timer_tick_ns;
529 /* Maximum timeout in nanoseconds allowed by adapter instance. */
530 uint64_t max_tmo_ns;
531 /* Ring containing messages to arm or cancel event timers */
532 struct rte_ring *msg_ring;
533 /* Mempool containing msg objects */
534 struct rte_mempool *msg_pool;
535 /* Buffered timer expiry events to be enqueued to an event device. */
536 struct event_buffer buffer;
537 /* Statistics */
538 struct rte_event_timer_adapter_stats stats;
539 /* The number of threads currently adding to the message ring */
540 rte_atomic16_t message_producer_count;
541 };
542
543 enum msg_type {MSG_TYPE_ARM, MSG_TYPE_CANCEL};
544
545 struct msg {
546 enum msg_type type;
547 struct rte_event_timer *evtim;
548 struct rte_timer tim;
549 TAILQ_ENTRY(msg) msgs;
550 };
551
552 static void
553 sw_event_timer_cb(struct rte_timer *tim, void *arg)
554 {
555 int ret;
556 uint16_t nb_evs_flushed = 0;
557 uint16_t nb_evs_invalid = 0;
558 uint64_t opaque;
559 struct rte_event_timer *evtim;
560 struct rte_event_timer_adapter *adapter;
561 struct rte_event_timer_adapter_sw_data *sw_data;
562
563 evtim = arg;
564 opaque = evtim->impl_opaque[1];
565 adapter = (struct rte_event_timer_adapter *)(uintptr_t)opaque;
566 sw_data = adapter->data->adapter_priv;
567
568 ret = event_buffer_add(&sw_data->buffer, &evtim->ev);
569 if (ret < 0) {
570 /* If event buffer is full, put timer back in list with
571 * immediate expiry value, so that we process it again on the
572 * next iteration.
573 */
574 rte_timer_reset_sync(tim, 0, SINGLE, rte_lcore_id(),
575 sw_event_timer_cb, evtim);
576
577 sw_data->stats.evtim_retry_count++;
578 EVTIM_LOG_DBG("event buffer full, resetting rte_timer with "
579 "immediate expiry value");
580 } else {
581 struct msg *m = container_of(tim, struct msg, tim);
582 TAILQ_REMOVE(&sw_data->msgs_tailq_head, m, msgs);
583 EVTIM_BUF_LOG_DBG("buffered an event timer expiry event");
584 evtim->state = RTE_EVENT_TIMER_NOT_ARMED;
585
586 /* Free the msg object containing the rte_timer now that
587 * we've buffered its event successfully.
588 */
589 rte_mempool_put(sw_data->msg_pool, m);
590
591 /* Bump the count when we successfully add an expiry event to
592 * the buffer.
593 */
594 sw_data->stats.evtim_exp_count++;
595 }
596
597 if (event_buffer_batch_ready(&sw_data->buffer)) {
598 event_buffer_flush(&sw_data->buffer,
599 adapter->data->event_dev_id,
600 adapter->data->event_port_id,
601 &nb_evs_flushed,
602 &nb_evs_invalid);
603
604 sw_data->stats.ev_enq_count += nb_evs_flushed;
605 sw_data->stats.ev_inv_count += nb_evs_invalid;
606 }
607 }
608
609 static __rte_always_inline uint64_t
610 get_timeout_cycles(struct rte_event_timer *evtim,
611 struct rte_event_timer_adapter *adapter)
612 {
613 uint64_t timeout_ns;
614 struct rte_event_timer_adapter_sw_data *sw_data;
615
616 sw_data = adapter->data->adapter_priv;
617 timeout_ns = evtim->timeout_ticks * sw_data->timer_tick_ns;
618 return timeout_ns * rte_get_timer_hz() / NSECPERSEC;
619
620 }
621
622 /* This function returns true if one or more (adapter) ticks have occurred since
623 * the last time it was called.
624 */
625 static inline bool
626 adapter_did_tick(struct rte_event_timer_adapter *adapter)
627 {
628 uint64_t cycles_per_adapter_tick, start_cycles;
629 uint64_t *next_tick_cyclesp;
630 struct rte_event_timer_adapter_sw_data *sw_data;
631
632 sw_data = adapter->data->adapter_priv;
633 next_tick_cyclesp = &sw_data->next_tick_cycles;
634
635 cycles_per_adapter_tick = sw_data->timer_tick_ns *
636 (rte_get_timer_hz() / NSECPERSEC);
637
638 start_cycles = rte_get_timer_cycles();
639
640 /* Note: initially, *next_tick_cyclesp == 0, so the clause below will
641 * execute, and set things going.
642 */
643
644 if (start_cycles >= *next_tick_cyclesp) {
645 /* Snap the current cycle count to the preceding adapter tick
646 * boundary.
647 */
648 start_cycles -= start_cycles % cycles_per_adapter_tick;
649
650 *next_tick_cyclesp = start_cycles + cycles_per_adapter_tick;
651
652 return true;
653 }
654
655 return false;
656 }
657
658 /* Check that event timer timeout value is in range */
659 static __rte_always_inline int
660 check_timeout(struct rte_event_timer *evtim,
661 const struct rte_event_timer_adapter *adapter)
662 {
663 uint64_t tmo_nsec;
664 struct rte_event_timer_adapter_sw_data *sw_data;
665
666 sw_data = adapter->data->adapter_priv;
667 tmo_nsec = evtim->timeout_ticks * sw_data->timer_tick_ns;
668
669 if (tmo_nsec > sw_data->max_tmo_ns)
670 return -1;
671
672 if (tmo_nsec < sw_data->timer_tick_ns)
673 return -2;
674
675 return 0;
676 }
677
678 /* Check that event timer event queue sched type matches destination event queue
679 * sched type
680 */
681 static __rte_always_inline int
682 check_destination_event_queue(struct rte_event_timer *evtim,
683 const struct rte_event_timer_adapter *adapter)
684 {
685 int ret;
686 uint32_t sched_type;
687
688 ret = rte_event_queue_attr_get(adapter->data->event_dev_id,
689 evtim->ev.queue_id,
690 RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE,
691 &sched_type);
692
693 if ((ret < 0 && ret != -EOVERFLOW) ||
694 evtim->ev.sched_type != sched_type)
695 return -1;
696
697 return 0;
698 }
699
700 #define NB_OBJS 32
701 static int
702 sw_event_timer_adapter_service_func(void *arg)
703 {
704 int i, num_msgs;
705 uint64_t cycles, opaque;
706 uint16_t nb_evs_flushed = 0;
707 uint16_t nb_evs_invalid = 0;
708 struct rte_event_timer_adapter *adapter;
709 struct rte_event_timer_adapter_sw_data *sw_data;
710 struct rte_event_timer *evtim = NULL;
711 struct rte_timer *tim = NULL;
712 struct msg *msg, *msgs[NB_OBJS];
713
714 adapter = arg;
715 sw_data = adapter->data->adapter_priv;
716
717 sw_data->service_phase = 1;
718 rte_smp_wmb();
719
720 while (rte_atomic16_read(&sw_data->message_producer_count) > 0 ||
721 !rte_ring_empty(sw_data->msg_ring)) {
722
723 num_msgs = rte_ring_dequeue_burst(sw_data->msg_ring,
724 (void **)msgs, NB_OBJS, NULL);
725
726 for (i = 0; i < num_msgs; i++) {
727 int ret = 0;
728
729 RTE_SET_USED(ret);
730
731 msg = msgs[i];
732 evtim = msg->evtim;
733
734 switch (msg->type) {
735 case MSG_TYPE_ARM:
736 EVTIM_SVC_LOG_DBG("dequeued ARM message from "
737 "ring");
738 tim = &msg->tim;
739 rte_timer_init(tim);
740 cycles = get_timeout_cycles(evtim,
741 adapter);
742 ret = rte_timer_reset(tim, cycles, SINGLE,
743 rte_lcore_id(),
744 sw_event_timer_cb,
745 evtim);
746 RTE_ASSERT(ret == 0);
747
748 evtim->impl_opaque[0] = (uintptr_t)tim;
749 evtim->impl_opaque[1] = (uintptr_t)adapter;
750
751 TAILQ_INSERT_TAIL(&sw_data->msgs_tailq_head,
752 msg,
753 msgs);
754 break;
755 case MSG_TYPE_CANCEL:
756 EVTIM_SVC_LOG_DBG("dequeued CANCEL message "
757 "from ring");
758 opaque = evtim->impl_opaque[0];
759 tim = (struct rte_timer *)(uintptr_t)opaque;
760 RTE_ASSERT(tim != NULL);
761
762 ret = rte_timer_stop(tim);
763 RTE_ASSERT(ret == 0);
764
765 /* Free the msg object for the original arm
766 * request.
767 */
768 struct msg *m;
769 m = container_of(tim, struct msg, tim);
770 TAILQ_REMOVE(&sw_data->msgs_tailq_head, m,
771 msgs);
772 rte_mempool_put(sw_data->msg_pool, m);
773
774 /* Free the msg object for the current msg */
775 rte_mempool_put(sw_data->msg_pool, msg);
776
777 evtim->impl_opaque[0] = 0;
778 evtim->impl_opaque[1] = 0;
779
780 break;
781 }
782 }
783 }
784
785 sw_data->service_phase = 2;
786 rte_smp_wmb();
787
788 if (adapter_did_tick(adapter)) {
789 rte_timer_manage();
790
791 event_buffer_flush(&sw_data->buffer,
792 adapter->data->event_dev_id,
793 adapter->data->event_port_id,
794 &nb_evs_flushed, &nb_evs_invalid);
795
796 sw_data->stats.ev_enq_count += nb_evs_flushed;
797 sw_data->stats.ev_inv_count += nb_evs_invalid;
798 sw_data->stats.adapter_tick_count++;
799 }
800
801 sw_data->service_phase = 0;
802 rte_smp_wmb();
803
804 return 0;
805 }
806
807 /* The adapter initialization function rounds the mempool size up to the next
808 * power of 2, so we can take the difference between that value and what the
809 * user requested, and use the space for caches. This avoids a scenario where a
810 * user can't arm the number of timers the adapter was configured with because
811 * mempool objects have been lost to caches.
812 *
813 * nb_actual should always be a power of 2, so we can iterate over the powers
814 * of 2 to see what the largest cache size we can use is.
815 */
816 static int
817 compute_msg_mempool_cache_size(uint64_t nb_requested, uint64_t nb_actual)
818 {
819 int i;
820 int size;
821 int cache_size = 0;
822
823 for (i = 0; ; i++) {
824 size = 1 << i;
825
826 if (RTE_MAX_LCORE * size < (int)(nb_actual - nb_requested) &&
827 size < RTE_MEMPOOL_CACHE_MAX_SIZE &&
828 size <= nb_actual / 1.5)
829 cache_size = size;
830 else
831 break;
832 }
833
834 return cache_size;
835 }
836
837 #define SW_MIN_INTERVAL 1E5
838
839 static int
840 sw_event_timer_adapter_init(struct rte_event_timer_adapter *adapter)
841 {
842 int ret;
843 struct rte_event_timer_adapter_sw_data *sw_data;
844 uint64_t nb_timers;
845 unsigned int flags;
846 struct rte_service_spec service;
847 static bool timer_subsystem_inited; // static initialized to false
848
849 /* Allocate storage for SW implementation data */
850 char priv_data_name[RTE_RING_NAMESIZE];
851 snprintf(priv_data_name, RTE_RING_NAMESIZE, "sw_evtim_adap_priv_%"PRIu8,
852 adapter->data->id);
853 adapter->data->adapter_priv = rte_zmalloc_socket(
854 priv_data_name,
855 sizeof(struct rte_event_timer_adapter_sw_data),
856 RTE_CACHE_LINE_SIZE,
857 adapter->data->socket_id);
858 if (adapter->data->adapter_priv == NULL) {
859 EVTIM_LOG_ERR("failed to allocate space for private data");
860 rte_errno = ENOMEM;
861 return -1;
862 }
863
864 if (adapter->data->conf.timer_tick_ns < SW_MIN_INTERVAL) {
865 EVTIM_LOG_ERR("failed to create adapter with requested tick "
866 "interval");
867 rte_errno = EINVAL;
868 return -1;
869 }
870
871 sw_data = adapter->data->adapter_priv;
872
873 sw_data->timer_tick_ns = adapter->data->conf.timer_tick_ns;
874 sw_data->max_tmo_ns = adapter->data->conf.max_tmo_ns;
875
876 TAILQ_INIT(&sw_data->msgs_tailq_head);
877 rte_spinlock_init(&sw_data->msgs_tailq_sl);
878 rte_atomic16_init(&sw_data->message_producer_count);
879
880 /* Rings require power of 2, so round up to next such value */
881 nb_timers = rte_align64pow2(adapter->data->conf.nb_timers);
882
883 char msg_ring_name[RTE_RING_NAMESIZE];
884 snprintf(msg_ring_name, RTE_RING_NAMESIZE,
885 "sw_evtim_adap_msg_ring_%"PRIu8, adapter->data->id);
886 flags = adapter->data->conf.flags & RTE_EVENT_TIMER_ADAPTER_F_SP_PUT ?
887 RING_F_SP_ENQ | RING_F_SC_DEQ :
888 RING_F_SC_DEQ;
889 sw_data->msg_ring = rte_ring_create(msg_ring_name, nb_timers,
890 adapter->data->socket_id, flags);
891 if (sw_data->msg_ring == NULL) {
892 EVTIM_LOG_ERR("failed to create message ring");
893 rte_errno = ENOMEM;
894 goto free_priv_data;
895 }
896
897 char pool_name[RTE_RING_NAMESIZE];
898 snprintf(pool_name, RTE_RING_NAMESIZE, "sw_evtim_adap_msg_pool_%"PRIu8,
899 adapter->data->id);
900
901 /* Both the arming/canceling thread and the service thread will do puts
902 * to the mempool, but if the SP_PUT flag is enabled, we can specify
903 * single-consumer get for the mempool.
904 */
905 flags = adapter->data->conf.flags & RTE_EVENT_TIMER_ADAPTER_F_SP_PUT ?
906 MEMPOOL_F_SC_GET : 0;
907
908 /* The usable size of a ring is count - 1, so subtract one here to
909 * make the counts agree.
910 */
911 int pool_size = nb_timers - 1;
912 int cache_size = compute_msg_mempool_cache_size(
913 adapter->data->conf.nb_timers, nb_timers);
914 sw_data->msg_pool = rte_mempool_create(pool_name, pool_size,
915 sizeof(struct msg), cache_size,
916 0, NULL, NULL, NULL, NULL,
917 adapter->data->socket_id, flags);
918 if (sw_data->msg_pool == NULL) {
919 EVTIM_LOG_ERR("failed to create message object mempool");
920 rte_errno = ENOMEM;
921 goto free_msg_ring;
922 }
923
924 event_buffer_init(&sw_data->buffer);
925
926 /* Register a service component to run adapter logic */
927 memset(&service, 0, sizeof(service));
928 snprintf(service.name, RTE_SERVICE_NAME_MAX,
929 "sw_evimer_adap_svc_%"PRIu8, adapter->data->id);
930 service.socket_id = adapter->data->socket_id;
931 service.callback = sw_event_timer_adapter_service_func;
932 service.callback_userdata = adapter;
933 service.capabilities &= ~(RTE_SERVICE_CAP_MT_SAFE);
934 ret = rte_service_component_register(&service, &sw_data->service_id);
935 if (ret < 0) {
936 EVTIM_LOG_ERR("failed to register service %s with id %"PRIu32
937 ": err = %d", service.name, sw_data->service_id,
938 ret);
939
940 rte_errno = ENOSPC;
941 goto free_msg_pool;
942 }
943
944 EVTIM_LOG_DBG("registered service %s with id %"PRIu32, service.name,
945 sw_data->service_id);
946
947 adapter->data->service_id = sw_data->service_id;
948 adapter->data->service_inited = 1;
949
950 if (!timer_subsystem_inited) {
951 rte_timer_subsystem_init();
952 timer_subsystem_inited = true;
953 }
954
955 return 0;
956
957 free_msg_pool:
958 rte_mempool_free(sw_data->msg_pool);
959 free_msg_ring:
960 rte_ring_free(sw_data->msg_ring);
961 free_priv_data:
962 rte_free(sw_data);
963 return -1;
964 }
965
966 static int
967 sw_event_timer_adapter_uninit(struct rte_event_timer_adapter *adapter)
968 {
969 int ret;
970 struct msg *m1, *m2;
971 struct rte_event_timer_adapter_sw_data *sw_data =
972 adapter->data->adapter_priv;
973
974 rte_spinlock_lock(&sw_data->msgs_tailq_sl);
975
976 /* Cancel outstanding rte_timers and free msg objects */
977 m1 = TAILQ_FIRST(&sw_data->msgs_tailq_head);
978 while (m1 != NULL) {
979 EVTIM_LOG_DBG("freeing outstanding timer");
980 m2 = TAILQ_NEXT(m1, msgs);
981
982 rte_timer_stop_sync(&m1->tim);
983 rte_mempool_put(sw_data->msg_pool, m1);
984
985 m1 = m2;
986 }
987
988 rte_spinlock_unlock(&sw_data->msgs_tailq_sl);
989
990 ret = rte_service_component_unregister(sw_data->service_id);
991 if (ret < 0) {
992 EVTIM_LOG_ERR("failed to unregister service component");
993 return ret;
994 }
995
996 rte_ring_free(sw_data->msg_ring);
997 rte_mempool_free(sw_data->msg_pool);
998 rte_free(adapter->data->adapter_priv);
999
1000 return 0;
1001 }
1002
1003 static inline int32_t
1004 get_mapped_count_for_service(uint32_t service_id)
1005 {
1006 int32_t core_count, i, mapped_count = 0;
1007 uint32_t lcore_arr[RTE_MAX_LCORE];
1008
1009 core_count = rte_service_lcore_list(lcore_arr, RTE_MAX_LCORE);
1010
1011 for (i = 0; i < core_count; i++)
1012 if (rte_service_map_lcore_get(service_id, lcore_arr[i]) == 1)
1013 mapped_count++;
1014
1015 return mapped_count;
1016 }
1017
1018 static int
1019 sw_event_timer_adapter_start(const struct rte_event_timer_adapter *adapter)
1020 {
1021 int mapped_count;
1022 struct rte_event_timer_adapter_sw_data *sw_data;
1023
1024 sw_data = adapter->data->adapter_priv;
1025
1026 /* Mapping the service to more than one service core can introduce
1027 * delays while one thread is waiting to acquire a lock, so only allow
1028 * one core to be mapped to the service.
1029 */
1030 mapped_count = get_mapped_count_for_service(sw_data->service_id);
1031
1032 if (mapped_count == 1)
1033 return rte_service_component_runstate_set(sw_data->service_id,
1034 1);
1035
1036 return mapped_count < 1 ? -ENOENT : -ENOTSUP;
1037 }
1038
1039 static int
1040 sw_event_timer_adapter_stop(const struct rte_event_timer_adapter *adapter)
1041 {
1042 int ret;
1043 struct rte_event_timer_adapter_sw_data *sw_data =
1044 adapter->data->adapter_priv;
1045
1046 ret = rte_service_component_runstate_set(sw_data->service_id, 0);
1047 if (ret < 0)
1048 return ret;
1049
1050 /* Wait for the service to complete its final iteration before
1051 * stopping.
1052 */
1053 while (sw_data->service_phase != 0)
1054 rte_pause();
1055
1056 rte_smp_rmb();
1057
1058 return 0;
1059 }
1060
1061 static void
1062 sw_event_timer_adapter_get_info(const struct rte_event_timer_adapter *adapter,
1063 struct rte_event_timer_adapter_info *adapter_info)
1064 {
1065 struct rte_event_timer_adapter_sw_data *sw_data;
1066 sw_data = adapter->data->adapter_priv;
1067
1068 adapter_info->min_resolution_ns = sw_data->timer_tick_ns;
1069 adapter_info->max_tmo_ns = sw_data->max_tmo_ns;
1070 }
1071
1072 static int
1073 sw_event_timer_adapter_stats_get(const struct rte_event_timer_adapter *adapter,
1074 struct rte_event_timer_adapter_stats *stats)
1075 {
1076 struct rte_event_timer_adapter_sw_data *sw_data;
1077 sw_data = adapter->data->adapter_priv;
1078 *stats = sw_data->stats;
1079 return 0;
1080 }
1081
1082 static int
1083 sw_event_timer_adapter_stats_reset(
1084 const struct rte_event_timer_adapter *adapter)
1085 {
1086 struct rte_event_timer_adapter_sw_data *sw_data;
1087 sw_data = adapter->data->adapter_priv;
1088 memset(&sw_data->stats, 0, sizeof(sw_data->stats));
1089 return 0;
1090 }
1091
1092 static __rte_always_inline uint16_t
1093 __sw_event_timer_arm_burst(const struct rte_event_timer_adapter *adapter,
1094 struct rte_event_timer **evtims,
1095 uint16_t nb_evtims)
1096 {
1097 uint16_t i;
1098 int ret;
1099 struct rte_event_timer_adapter_sw_data *sw_data;
1100 struct msg *msgs[nb_evtims];
1101
1102 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
1103 /* Check that the service is running. */
1104 if (rte_service_runstate_get(adapter->data->service_id) != 1) {
1105 rte_errno = EINVAL;
1106 return 0;
1107 }
1108 #endif
1109
1110 sw_data = adapter->data->adapter_priv;
1111
1112 ret = rte_mempool_get_bulk(sw_data->msg_pool, (void **)msgs, nb_evtims);
1113 if (ret < 0) {
1114 rte_errno = ENOSPC;
1115 return 0;
1116 }
1117
1118 /* Let the service know we're producing messages for it to process */
1119 rte_atomic16_inc(&sw_data->message_producer_count);
1120
1121 /* If the service is managing timers, wait for it to finish */
1122 while (sw_data->service_phase == 2)
1123 rte_pause();
1124
1125 rte_smp_rmb();
1126
1127 for (i = 0; i < nb_evtims; i++) {
1128 /* Don't modify the event timer state in these cases */
1129 if (evtims[i]->state == RTE_EVENT_TIMER_ARMED) {
1130 rte_errno = EALREADY;
1131 break;
1132 } else if (!(evtims[i]->state == RTE_EVENT_TIMER_NOT_ARMED ||
1133 evtims[i]->state == RTE_EVENT_TIMER_CANCELED)) {
1134 rte_errno = EINVAL;
1135 break;
1136 }
1137
1138 ret = check_timeout(evtims[i], adapter);
1139 if (ret == -1) {
1140 evtims[i]->state = RTE_EVENT_TIMER_ERROR_TOOLATE;
1141 rte_errno = EINVAL;
1142 break;
1143 }
1144 if (ret == -2) {
1145 evtims[i]->state = RTE_EVENT_TIMER_ERROR_TOOEARLY;
1146 rte_errno = EINVAL;
1147 break;
1148 }
1149
1150 if (check_destination_event_queue(evtims[i], adapter) < 0) {
1151 evtims[i]->state = RTE_EVENT_TIMER_ERROR;
1152 rte_errno = EINVAL;
1153 break;
1154 }
1155
1156 /* Checks passed, set up a message to enqueue */
1157 msgs[i]->type = MSG_TYPE_ARM;
1158 msgs[i]->evtim = evtims[i];
1159
1160 /* Set the payload pointer if not set. */
1161 if (evtims[i]->ev.event_ptr == NULL)
1162 evtims[i]->ev.event_ptr = evtims[i];
1163
1164 /* msg objects that get enqueued successfully will be freed
1165 * either by a future cancel operation or by the timer
1166 * expiration callback.
1167 */
1168 if (rte_ring_enqueue(sw_data->msg_ring, msgs[i]) < 0) {
1169 rte_errno = ENOSPC;
1170 break;
1171 }
1172
1173 EVTIM_LOG_DBG("enqueued ARM message to ring");
1174
1175 evtims[i]->state = RTE_EVENT_TIMER_ARMED;
1176 }
1177
1178 /* Let the service know we're done producing messages */
1179 rte_atomic16_dec(&sw_data->message_producer_count);
1180
1181 if (i < nb_evtims)
1182 rte_mempool_put_bulk(sw_data->msg_pool, (void **)&msgs[i],
1183 nb_evtims - i);
1184
1185 return i;
1186 }
1187
1188 static uint16_t
1189 sw_event_timer_arm_burst(const struct rte_event_timer_adapter *adapter,
1190 struct rte_event_timer **evtims,
1191 uint16_t nb_evtims)
1192 {
1193 return __sw_event_timer_arm_burst(adapter, evtims, nb_evtims);
1194 }
1195
1196 static uint16_t
1197 sw_event_timer_cancel_burst(const struct rte_event_timer_adapter *adapter,
1198 struct rte_event_timer **evtims,
1199 uint16_t nb_evtims)
1200 {
1201 uint16_t i;
1202 int ret;
1203 struct rte_event_timer_adapter_sw_data *sw_data;
1204 struct msg *msgs[nb_evtims];
1205
1206 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
1207 /* Check that the service is running. */
1208 if (rte_service_runstate_get(adapter->data->service_id) != 1) {
1209 rte_errno = EINVAL;
1210 return 0;
1211 }
1212 #endif
1213
1214 sw_data = adapter->data->adapter_priv;
1215
1216 ret = rte_mempool_get_bulk(sw_data->msg_pool, (void **)msgs, nb_evtims);
1217 if (ret < 0) {
1218 rte_errno = ENOSPC;
1219 return 0;
1220 }
1221
1222 /* Let the service know we're producing messages for it to process */
1223 rte_atomic16_inc(&sw_data->message_producer_count);
1224
1225 /* If the service could be modifying event timer states, wait */
1226 while (sw_data->service_phase == 2)
1227 rte_pause();
1228
1229 rte_smp_rmb();
1230
1231 for (i = 0; i < nb_evtims; i++) {
1232 /* Don't modify the event timer state in these cases */
1233 if (evtims[i]->state == RTE_EVENT_TIMER_CANCELED) {
1234 rte_errno = EALREADY;
1235 break;
1236 } else if (evtims[i]->state != RTE_EVENT_TIMER_ARMED) {
1237 rte_errno = EINVAL;
1238 break;
1239 }
1240
1241 msgs[i]->type = MSG_TYPE_CANCEL;
1242 msgs[i]->evtim = evtims[i];
1243
1244 if (rte_ring_enqueue(sw_data->msg_ring, msgs[i]) < 0) {
1245 rte_errno = ENOSPC;
1246 break;
1247 }
1248
1249 EVTIM_LOG_DBG("enqueued CANCEL message to ring");
1250
1251 evtims[i]->state = RTE_EVENT_TIMER_CANCELED;
1252 }
1253
1254 /* Let the service know we're done producing messages */
1255 rte_atomic16_dec(&sw_data->message_producer_count);
1256
1257 if (i < nb_evtims)
1258 rte_mempool_put_bulk(sw_data->msg_pool, (void **)&msgs[i],
1259 nb_evtims - i);
1260
1261 return i;
1262 }
1263
1264 static uint16_t
1265 sw_event_timer_arm_tmo_tick_burst(const struct rte_event_timer_adapter *adapter,
1266 struct rte_event_timer **evtims,
1267 uint64_t timeout_ticks,
1268 uint16_t nb_evtims)
1269 {
1270 int i;
1271
1272 for (i = 0; i < nb_evtims; i++)
1273 evtims[i]->timeout_ticks = timeout_ticks;
1274
1275 return __sw_event_timer_arm_burst(adapter, evtims, nb_evtims);
1276 }
1277
1278 static const struct rte_event_timer_adapter_ops sw_event_adapter_timer_ops = {
1279 .init = sw_event_timer_adapter_init,
1280 .uninit = sw_event_timer_adapter_uninit,
1281 .start = sw_event_timer_adapter_start,
1282 .stop = sw_event_timer_adapter_stop,
1283 .get_info = sw_event_timer_adapter_get_info,
1284 .stats_get = sw_event_timer_adapter_stats_get,
1285 .stats_reset = sw_event_timer_adapter_stats_reset,
1286 .arm_burst = sw_event_timer_arm_burst,
1287 .arm_tmo_tick_burst = sw_event_timer_arm_tmo_tick_burst,
1288 .cancel_burst = sw_event_timer_cancel_burst,
1289 };
1290
1291 RTE_INIT(event_timer_adapter_init_log)
1292 {
1293 evtim_logtype = rte_log_register("lib.eventdev.adapter.timer");
1294 if (evtim_logtype >= 0)
1295 rte_log_set_level(evtim_logtype, RTE_LOG_NOTICE);
1296
1297 evtim_buffer_logtype = rte_log_register("lib.eventdev.adapter.timer."
1298 "buffer");
1299 if (evtim_buffer_logtype >= 0)
1300 rte_log_set_level(evtim_buffer_logtype, RTE_LOG_NOTICE);
1301
1302 evtim_svc_logtype = rte_log_register("lib.eventdev.adapter.timer.svc");
1303 if (evtim_svc_logtype >= 0)
1304 rte_log_set_level(evtim_svc_logtype, RTE_LOG_NOTICE);
1305 }