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