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