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