xref: /dpdk/lib/eventdev/rte_event_timer_adapter.c (revision b53d106d34b5c638f5a2cbdfee0da5bd42d4383f)
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 contiguous 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 	rte_event_maintain(adapter->data->event_dev_id,
790 			   adapter->data->event_port_id, 0);
791 
792 	return 0;
793 }
794 
795 /* The adapter initialization function rounds the mempool size up to the next
796  * power of 2, so we can take the difference between that value and what the
797  * user requested, and use the space for caches.  This avoids a scenario where a
798  * user can't arm the number of timers the adapter was configured with because
799  * mempool objects have been lost to caches.
800  *
801  * nb_actual should always be a power of 2, so we can iterate over the powers
802  * of 2 to see what the largest cache size we can use is.
803  */
804 static int
805 compute_msg_mempool_cache_size(uint64_t nb_requested, uint64_t nb_actual)
806 {
807 	int i;
808 	int size;
809 	int cache_size = 0;
810 
811 	for (i = 0;; i++) {
812 		size = 1 << i;
813 
814 		if (RTE_MAX_LCORE * size < (int)(nb_actual - nb_requested) &&
815 		    size < RTE_MEMPOOL_CACHE_MAX_SIZE &&
816 		    size <= nb_actual / 1.5)
817 			cache_size = size;
818 		else
819 			break;
820 	}
821 
822 	return cache_size;
823 }
824 
825 static int
826 swtim_init(struct rte_event_timer_adapter *adapter)
827 {
828 	int i, ret;
829 	struct swtim *sw;
830 	unsigned int flags;
831 	struct rte_service_spec service;
832 
833 	/* Allocate storage for private data area */
834 #define SWTIM_NAMESIZE 32
835 	char swtim_name[SWTIM_NAMESIZE];
836 	snprintf(swtim_name, SWTIM_NAMESIZE, "swtim_%"PRIu8,
837 			adapter->data->id);
838 	sw = rte_zmalloc_socket(swtim_name, sizeof(*sw), RTE_CACHE_LINE_SIZE,
839 			adapter->data->socket_id);
840 	if (sw == NULL) {
841 		EVTIM_LOG_ERR("failed to allocate space for private data");
842 		rte_errno = ENOMEM;
843 		return -1;
844 	}
845 
846 	/* Connect storage to adapter instance */
847 	adapter->data->adapter_priv = sw;
848 	sw->adapter = adapter;
849 
850 	sw->timer_tick_ns = adapter->data->conf.timer_tick_ns;
851 	sw->max_tmo_ns = adapter->data->conf.max_tmo_ns;
852 
853 	/* Create a timer pool */
854 	char pool_name[SWTIM_NAMESIZE];
855 	snprintf(pool_name, SWTIM_NAMESIZE, "swtim_pool_%"PRIu8,
856 		 adapter->data->id);
857 	/* Optimal mempool size is a power of 2 minus one */
858 	uint64_t nb_timers = rte_align64pow2(adapter->data->conf.nb_timers);
859 	int pool_size = nb_timers - 1;
860 	int cache_size = compute_msg_mempool_cache_size(
861 				adapter->data->conf.nb_timers, nb_timers);
862 	flags = 0; /* pool is multi-producer, multi-consumer */
863 	sw->tim_pool = rte_mempool_create(pool_name, pool_size,
864 			sizeof(struct rte_timer), cache_size, 0, NULL, NULL,
865 			NULL, NULL, adapter->data->socket_id, flags);
866 	if (sw->tim_pool == NULL) {
867 		EVTIM_LOG_ERR("failed to create timer object mempool");
868 		rte_errno = ENOMEM;
869 		goto free_alloc;
870 	}
871 
872 	/* Initialize the variables that track in-use timer lists */
873 	for (i = 0; i < RTE_MAX_LCORE; i++)
874 		sw->in_use[i].v = 0;
875 
876 	/* Initialize the timer subsystem and allocate timer data instance */
877 	ret = rte_timer_subsystem_init();
878 	if (ret < 0) {
879 		if (ret != -EALREADY) {
880 			EVTIM_LOG_ERR("failed to initialize timer subsystem");
881 			rte_errno = -ret;
882 			goto free_mempool;
883 		}
884 	}
885 
886 	ret = rte_timer_data_alloc(&sw->timer_data_id);
887 	if (ret < 0) {
888 		EVTIM_LOG_ERR("failed to allocate timer data instance");
889 		rte_errno = -ret;
890 		goto free_mempool;
891 	}
892 
893 	/* Initialize timer event buffer */
894 	event_buffer_init(&sw->buffer);
895 
896 	sw->adapter = adapter;
897 
898 	/* Register a service component to run adapter logic */
899 	memset(&service, 0, sizeof(service));
900 	snprintf(service.name, RTE_SERVICE_NAME_MAX,
901 		 "swtim_svc_%"PRIu8, adapter->data->id);
902 	service.socket_id = adapter->data->socket_id;
903 	service.callback = swtim_service_func;
904 	service.callback_userdata = adapter;
905 	service.capabilities &= ~(RTE_SERVICE_CAP_MT_SAFE);
906 	ret = rte_service_component_register(&service, &sw->service_id);
907 	if (ret < 0) {
908 		EVTIM_LOG_ERR("failed to register service %s with id %"PRIu32
909 			      ": err = %d", service.name, sw->service_id,
910 			      ret);
911 
912 		rte_errno = ENOSPC;
913 		goto free_mempool;
914 	}
915 
916 	EVTIM_LOG_DBG("registered service %s with id %"PRIu32, service.name,
917 		      sw->service_id);
918 
919 	adapter->data->service_id = sw->service_id;
920 	adapter->data->service_inited = 1;
921 
922 	return 0;
923 free_mempool:
924 	rte_mempool_free(sw->tim_pool);
925 free_alloc:
926 	rte_free(sw);
927 	return -1;
928 }
929 
930 static void
931 swtim_free_tim(struct rte_timer *tim, void *arg)
932 {
933 	struct swtim *sw = arg;
934 
935 	rte_mempool_put(sw->tim_pool, tim);
936 }
937 
938 /* Traverse the list of outstanding timers and put them back in the mempool
939  * before freeing the adapter to avoid leaking the memory.
940  */
941 static int
942 swtim_uninit(struct rte_event_timer_adapter *adapter)
943 {
944 	int ret;
945 	struct swtim *sw = swtim_pmd_priv(adapter);
946 
947 	/* Free outstanding timers */
948 	rte_timer_stop_all(sw->timer_data_id,
949 			   sw->poll_lcores,
950 			   sw->n_poll_lcores,
951 			   swtim_free_tim,
952 			   sw);
953 
954 	ret = rte_service_component_unregister(sw->service_id);
955 	if (ret < 0) {
956 		EVTIM_LOG_ERR("failed to unregister service component");
957 		return ret;
958 	}
959 
960 	rte_mempool_free(sw->tim_pool);
961 	rte_free(sw);
962 	adapter->data->adapter_priv = NULL;
963 
964 	return 0;
965 }
966 
967 static inline int32_t
968 get_mapped_count_for_service(uint32_t service_id)
969 {
970 	int32_t core_count, i, mapped_count = 0;
971 	uint32_t lcore_arr[RTE_MAX_LCORE];
972 
973 	core_count = rte_service_lcore_list(lcore_arr, RTE_MAX_LCORE);
974 
975 	for (i = 0; i < core_count; i++)
976 		if (rte_service_map_lcore_get(service_id, lcore_arr[i]) == 1)
977 			mapped_count++;
978 
979 	return mapped_count;
980 }
981 
982 static int
983 swtim_start(const struct rte_event_timer_adapter *adapter)
984 {
985 	int mapped_count;
986 	struct swtim *sw = swtim_pmd_priv(adapter);
987 
988 	/* Mapping the service to more than one service core can introduce
989 	 * delays while one thread is waiting to acquire a lock, so only allow
990 	 * one core to be mapped to the service.
991 	 *
992 	 * Note: the service could be modified such that it spreads cores to
993 	 * poll over multiple service instances.
994 	 */
995 	mapped_count = get_mapped_count_for_service(sw->service_id);
996 
997 	if (mapped_count != 1)
998 		return mapped_count < 1 ? -ENOENT : -ENOTSUP;
999 
1000 	return rte_service_component_runstate_set(sw->service_id, 1);
1001 }
1002 
1003 static int
1004 swtim_stop(const struct rte_event_timer_adapter *adapter)
1005 {
1006 	int ret;
1007 	struct swtim *sw = swtim_pmd_priv(adapter);
1008 
1009 	ret = rte_service_component_runstate_set(sw->service_id, 0);
1010 	if (ret < 0)
1011 		return ret;
1012 
1013 	/* Wait for the service to complete its final iteration */
1014 	while (rte_service_may_be_active(sw->service_id))
1015 		rte_pause();
1016 
1017 	return 0;
1018 }
1019 
1020 static void
1021 swtim_get_info(const struct rte_event_timer_adapter *adapter,
1022 		struct rte_event_timer_adapter_info *adapter_info)
1023 {
1024 	struct swtim *sw = swtim_pmd_priv(adapter);
1025 	adapter_info->min_resolution_ns = sw->timer_tick_ns;
1026 	adapter_info->max_tmo_ns = sw->max_tmo_ns;
1027 }
1028 
1029 static int
1030 swtim_stats_get(const struct rte_event_timer_adapter *adapter,
1031 		struct rte_event_timer_adapter_stats *stats)
1032 {
1033 	struct swtim *sw = swtim_pmd_priv(adapter);
1034 	*stats = sw->stats; /* structure copy */
1035 	return 0;
1036 }
1037 
1038 static int
1039 swtim_stats_reset(const struct rte_event_timer_adapter *adapter)
1040 {
1041 	struct swtim *sw = swtim_pmd_priv(adapter);
1042 	memset(&sw->stats, 0, sizeof(sw->stats));
1043 	return 0;
1044 }
1045 
1046 static uint16_t
1047 __swtim_arm_burst(const struct rte_event_timer_adapter *adapter,
1048 		struct rte_event_timer **evtims,
1049 		uint16_t nb_evtims)
1050 {
1051 	int i, ret;
1052 	struct swtim *sw = swtim_pmd_priv(adapter);
1053 	uint32_t lcore_id = rte_lcore_id();
1054 	struct rte_timer *tim, *tims[nb_evtims];
1055 	uint64_t cycles;
1056 	int n_lcores;
1057 	/* Timer list for this lcore is not in use. */
1058 	uint16_t exp_state = 0;
1059 	enum rte_event_timer_state n_state;
1060 
1061 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
1062 	/* Check that the service is running. */
1063 	if (rte_service_runstate_get(adapter->data->service_id) != 1) {
1064 		rte_errno = EINVAL;
1065 		return 0;
1066 	}
1067 #endif
1068 
1069 	/* Adjust lcore_id if non-EAL thread. Arbitrarily pick the timer list of
1070 	 * the highest lcore to insert such timers into
1071 	 */
1072 	if (lcore_id == LCORE_ID_ANY)
1073 		lcore_id = RTE_MAX_LCORE - 1;
1074 
1075 	/* If this is the first time we're arming an event timer on this lcore,
1076 	 * mark this lcore as "in use"; this will cause the service
1077 	 * function to process the timer list that corresponds to this lcore.
1078 	 * The atomic compare-and-swap operation can prevent the race condition
1079 	 * on in_use flag between multiple non-EAL threads.
1080 	 */
1081 	if (unlikely(__atomic_compare_exchange_n(&sw->in_use[lcore_id].v,
1082 			&exp_state, 1, 0,
1083 			__ATOMIC_RELAXED, __ATOMIC_RELAXED))) {
1084 		EVTIM_LOG_DBG("Adding lcore id = %u to list of lcores to poll",
1085 			      lcore_id);
1086 		n_lcores = __atomic_fetch_add(&sw->n_poll_lcores, 1,
1087 					     __ATOMIC_RELAXED);
1088 		__atomic_store_n(&sw->poll_lcores[n_lcores], lcore_id,
1089 				__ATOMIC_RELAXED);
1090 	}
1091 
1092 	ret = rte_mempool_get_bulk(sw->tim_pool, (void **)tims,
1093 				   nb_evtims);
1094 	if (ret < 0) {
1095 		rte_errno = ENOSPC;
1096 		return 0;
1097 	}
1098 
1099 	for (i = 0; i < nb_evtims; i++) {
1100 		n_state = __atomic_load_n(&evtims[i]->state, __ATOMIC_ACQUIRE);
1101 		if (n_state == RTE_EVENT_TIMER_ARMED) {
1102 			rte_errno = EALREADY;
1103 			break;
1104 		} else if (!(n_state == RTE_EVENT_TIMER_NOT_ARMED ||
1105 			     n_state == RTE_EVENT_TIMER_CANCELED)) {
1106 			rte_errno = EINVAL;
1107 			break;
1108 		}
1109 
1110 		ret = check_timeout(evtims[i], adapter);
1111 		if (unlikely(ret == -1)) {
1112 			__atomic_store_n(&evtims[i]->state,
1113 					RTE_EVENT_TIMER_ERROR_TOOLATE,
1114 					__ATOMIC_RELAXED);
1115 			rte_errno = EINVAL;
1116 			break;
1117 		} else if (unlikely(ret == -2)) {
1118 			__atomic_store_n(&evtims[i]->state,
1119 					RTE_EVENT_TIMER_ERROR_TOOEARLY,
1120 					__ATOMIC_RELAXED);
1121 			rte_errno = EINVAL;
1122 			break;
1123 		}
1124 
1125 		if (unlikely(check_destination_event_queue(evtims[i],
1126 							   adapter) < 0)) {
1127 			__atomic_store_n(&evtims[i]->state,
1128 					RTE_EVENT_TIMER_ERROR,
1129 					__ATOMIC_RELAXED);
1130 			rte_errno = EINVAL;
1131 			break;
1132 		}
1133 
1134 		tim = tims[i];
1135 		rte_timer_init(tim);
1136 
1137 		evtims[i]->impl_opaque[0] = (uintptr_t)tim;
1138 		evtims[i]->impl_opaque[1] = (uintptr_t)adapter;
1139 
1140 		cycles = get_timeout_cycles(evtims[i], adapter);
1141 		ret = rte_timer_alt_reset(sw->timer_data_id, tim, cycles,
1142 					  SINGLE, lcore_id, NULL, evtims[i]);
1143 		if (ret < 0) {
1144 			/* tim was in RUNNING or CONFIG state */
1145 			__atomic_store_n(&evtims[i]->state,
1146 					RTE_EVENT_TIMER_ERROR,
1147 					__ATOMIC_RELEASE);
1148 			break;
1149 		}
1150 
1151 		EVTIM_LOG_DBG("armed an event timer");
1152 		/* RELEASE ordering guarantees the adapter specific value
1153 		 * changes observed before the update of state.
1154 		 */
1155 		__atomic_store_n(&evtims[i]->state, RTE_EVENT_TIMER_ARMED,
1156 				__ATOMIC_RELEASE);
1157 	}
1158 
1159 	if (i < nb_evtims)
1160 		rte_mempool_put_bulk(sw->tim_pool,
1161 				     (void **)&tims[i], nb_evtims - i);
1162 
1163 	return i;
1164 }
1165 
1166 static uint16_t
1167 swtim_arm_burst(const struct rte_event_timer_adapter *adapter,
1168 		struct rte_event_timer **evtims,
1169 		uint16_t nb_evtims)
1170 {
1171 	return __swtim_arm_burst(adapter, evtims, nb_evtims);
1172 }
1173 
1174 static uint16_t
1175 swtim_cancel_burst(const struct rte_event_timer_adapter *adapter,
1176 		   struct rte_event_timer **evtims,
1177 		   uint16_t nb_evtims)
1178 {
1179 	int i, ret;
1180 	struct rte_timer *timp;
1181 	uint64_t opaque;
1182 	struct swtim *sw = swtim_pmd_priv(adapter);
1183 	enum rte_event_timer_state n_state;
1184 
1185 #ifdef RTE_LIBRTE_EVENTDEV_DEBUG
1186 	/* Check that the service is running. */
1187 	if (rte_service_runstate_get(adapter->data->service_id) != 1) {
1188 		rte_errno = EINVAL;
1189 		return 0;
1190 	}
1191 #endif
1192 
1193 	for (i = 0; i < nb_evtims; i++) {
1194 		/* Don't modify the event timer state in these cases */
1195 		/* ACQUIRE ordering guarantees the access of implementation
1196 		 * specific opaque data under the correct state.
1197 		 */
1198 		n_state = __atomic_load_n(&evtims[i]->state, __ATOMIC_ACQUIRE);
1199 		if (n_state == RTE_EVENT_TIMER_CANCELED) {
1200 			rte_errno = EALREADY;
1201 			break;
1202 		} else if (n_state != RTE_EVENT_TIMER_ARMED) {
1203 			rte_errno = EINVAL;
1204 			break;
1205 		}
1206 
1207 		opaque = evtims[i]->impl_opaque[0];
1208 		timp = (struct rte_timer *)(uintptr_t)opaque;
1209 		RTE_ASSERT(timp != NULL);
1210 
1211 		ret = rte_timer_alt_stop(sw->timer_data_id, timp);
1212 		if (ret < 0) {
1213 			/* Timer is running or being configured */
1214 			rte_errno = EAGAIN;
1215 			break;
1216 		}
1217 
1218 		rte_mempool_put(sw->tim_pool, (void **)timp);
1219 
1220 		/* The RELEASE ordering here pairs with atomic ordering
1221 		 * to make sure the state update data observed between
1222 		 * threads.
1223 		 */
1224 		__atomic_store_n(&evtims[i]->state, RTE_EVENT_TIMER_CANCELED,
1225 				__ATOMIC_RELEASE);
1226 	}
1227 
1228 	return i;
1229 }
1230 
1231 static uint16_t
1232 swtim_arm_tmo_tick_burst(const struct rte_event_timer_adapter *adapter,
1233 			 struct rte_event_timer **evtims,
1234 			 uint64_t timeout_ticks,
1235 			 uint16_t nb_evtims)
1236 {
1237 	int i;
1238 
1239 	for (i = 0; i < nb_evtims; i++)
1240 		evtims[i]->timeout_ticks = timeout_ticks;
1241 
1242 	return __swtim_arm_burst(adapter, evtims, nb_evtims);
1243 }
1244 
1245 static const struct event_timer_adapter_ops swtim_ops = {
1246 	.init = swtim_init,
1247 	.uninit = swtim_uninit,
1248 	.start = swtim_start,
1249 	.stop = swtim_stop,
1250 	.get_info = swtim_get_info,
1251 	.stats_get = swtim_stats_get,
1252 	.stats_reset = swtim_stats_reset,
1253 	.arm_burst = swtim_arm_burst,
1254 	.arm_tmo_tick_burst = swtim_arm_tmo_tick_burst,
1255 	.cancel_burst = swtim_cancel_burst,
1256 };
1257