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