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