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