xref: /dpdk/lib/eal/freebsd/eal_interrupts.c (revision ae67895b507bb6af22263c79ba0d5c374b396485)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2018 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #include <string.h>
699a2dd95SBruce Richardson #include <sys/types.h>
799a2dd95SBruce Richardson #include <sys/event.h>
899a2dd95SBruce Richardson #include <sys/queue.h>
999a2dd95SBruce Richardson #include <unistd.h>
1099a2dd95SBruce Richardson 
1145a685caSAnkur Dwivedi #include <eal_trace_internal.h>
1299a2dd95SBruce Richardson #include <rte_errno.h>
1399a2dd95SBruce Richardson #include <rte_lcore.h>
1499a2dd95SBruce Richardson #include <rte_spinlock.h>
1599a2dd95SBruce Richardson #include <rte_common.h>
1699a2dd95SBruce Richardson #include <rte_interrupts.h>
1799a2dd95SBruce Richardson 
1899a2dd95SBruce Richardson #include "eal_private.h"
1999a2dd95SBruce Richardson #include "eal_alarm_private.h"
2099a2dd95SBruce Richardson 
2199a2dd95SBruce Richardson #define MAX_INTR_EVENTS 16
2299a2dd95SBruce Richardson 
2399a2dd95SBruce Richardson /**
2499a2dd95SBruce Richardson  * union buffer for reading on different devices
2599a2dd95SBruce Richardson  */
2699a2dd95SBruce Richardson union rte_intr_read_buffer {
2799a2dd95SBruce Richardson 	char charbuf[16];                /* for others */
2899a2dd95SBruce Richardson };
2999a2dd95SBruce Richardson 
3099a2dd95SBruce Richardson TAILQ_HEAD(rte_intr_cb_list, rte_intr_callback);
3199a2dd95SBruce Richardson TAILQ_HEAD(rte_intr_source_list, rte_intr_source);
3299a2dd95SBruce Richardson 
3399a2dd95SBruce Richardson struct rte_intr_callback {
3499a2dd95SBruce Richardson 	TAILQ_ENTRY(rte_intr_callback) next;
3599a2dd95SBruce Richardson 	rte_intr_callback_fn cb_fn;  /**< callback address */
3699a2dd95SBruce Richardson 	void *cb_arg;                /**< parameter for callback */
3799a2dd95SBruce Richardson 	uint8_t pending_delete;      /**< delete after callback is called */
3899a2dd95SBruce Richardson 	rte_intr_unregister_callback_fn ucb_fn; /**< fn to call before cb is deleted */
3999a2dd95SBruce Richardson };
4099a2dd95SBruce Richardson 
4199a2dd95SBruce Richardson struct rte_intr_source {
4299a2dd95SBruce Richardson 	TAILQ_ENTRY(rte_intr_source) next;
43bbbac4cdSHarman Kalra 	struct rte_intr_handle *intr_handle; /**< interrupt handle */
4499a2dd95SBruce Richardson 	struct rte_intr_cb_list callbacks;  /**< user callbacks */
4599a2dd95SBruce Richardson 	uint32_t active;
4699a2dd95SBruce Richardson };
4799a2dd95SBruce Richardson 
4899a2dd95SBruce Richardson /* global spinlock for interrupt data operation */
4999a2dd95SBruce Richardson static rte_spinlock_t intr_lock = RTE_SPINLOCK_INITIALIZER;
5099a2dd95SBruce Richardson 
5199a2dd95SBruce Richardson /* interrupt sources list */
5299a2dd95SBruce Richardson static struct rte_intr_source_list intr_sources;
5399a2dd95SBruce Richardson 
5499a2dd95SBruce Richardson /* interrupt handling thread */
551c1abf17SThomas Monjalon static rte_thread_t intr_thread;
5699a2dd95SBruce Richardson 
5799a2dd95SBruce Richardson static volatile int kq = -1;
5899a2dd95SBruce Richardson 
5999a2dd95SBruce Richardson static int
intr_source_to_kevent(const struct rte_intr_handle * ih,struct kevent * ke)6099a2dd95SBruce Richardson intr_source_to_kevent(const struct rte_intr_handle *ih, struct kevent *ke)
6199a2dd95SBruce Richardson {
6299a2dd95SBruce Richardson 	/* alarm callbacks are special case */
63bbbac4cdSHarman Kalra 	if (rte_intr_type_get(ih) == RTE_INTR_HANDLE_ALARM) {
6499a2dd95SBruce Richardson 		uint64_t timeout_ns;
6599a2dd95SBruce Richardson 
6699a2dd95SBruce Richardson 		/* get soonest alarm timeout */
6799a2dd95SBruce Richardson 		if (eal_alarm_get_timeout_ns(&timeout_ns) < 0)
6899a2dd95SBruce Richardson 			return -1;
6999a2dd95SBruce Richardson 
7099a2dd95SBruce Richardson 		ke->filter = EVFILT_TIMER;
7199a2dd95SBruce Richardson 		/* timers are one shot */
7299a2dd95SBruce Richardson 		ke->flags |= EV_ONESHOT;
7399a2dd95SBruce Richardson 		ke->fflags = NOTE_NSECONDS;
7499a2dd95SBruce Richardson 		ke->data = timeout_ns;
7599a2dd95SBruce Richardson 	} else {
7699a2dd95SBruce Richardson 		ke->filter = EVFILT_READ;
7799a2dd95SBruce Richardson 	}
78bbbac4cdSHarman Kalra 	ke->ident = rte_intr_fd_get(ih);
7999a2dd95SBruce Richardson 
8099a2dd95SBruce Richardson 	return 0;
8199a2dd95SBruce Richardson }
8299a2dd95SBruce Richardson 
8399a2dd95SBruce Richardson int
rte_intr_callback_register(const struct rte_intr_handle * intr_handle,rte_intr_callback_fn cb,void * cb_arg)8499a2dd95SBruce Richardson rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
8599a2dd95SBruce Richardson 		rte_intr_callback_fn cb, void *cb_arg)
8699a2dd95SBruce Richardson {
8799a2dd95SBruce Richardson 	struct rte_intr_callback *callback;
8899a2dd95SBruce Richardson 	struct rte_intr_source *src;
8999a2dd95SBruce Richardson 	int ret = 0, add_event = 0;
9099a2dd95SBruce Richardson 
9199a2dd95SBruce Richardson 	/* first do parameter checking */
92bbbac4cdSHarman Kalra 	if (rte_intr_fd_get(intr_handle) < 0 || cb == NULL) {
93*ae67895bSDavid Marchand 		EAL_LOG(ERR,
94*ae67895bSDavid Marchand 			"Registering with invalid input parameter");
9599a2dd95SBruce Richardson 		return -EINVAL;
9699a2dd95SBruce Richardson 	}
9799a2dd95SBruce Richardson 	if (kq < 0) {
98*ae67895bSDavid Marchand 		EAL_LOG(ERR, "Kqueue is not active: %d", kq);
9999a2dd95SBruce Richardson 		return -ENODEV;
10099a2dd95SBruce Richardson 	}
10199a2dd95SBruce Richardson 
10299a2dd95SBruce Richardson 	rte_spinlock_lock(&intr_lock);
10399a2dd95SBruce Richardson 
10499a2dd95SBruce Richardson 	/* find the source for this intr_handle */
10599a2dd95SBruce Richardson 	TAILQ_FOREACH(src, &intr_sources, next) {
106bbbac4cdSHarman Kalra 		if (rte_intr_fd_get(src->intr_handle) == rte_intr_fd_get(intr_handle))
10799a2dd95SBruce Richardson 			break;
10899a2dd95SBruce Richardson 	}
10999a2dd95SBruce Richardson 
11099a2dd95SBruce Richardson 	/* if this is an alarm interrupt and it already has a callback,
11199a2dd95SBruce Richardson 	 * then we don't want to create a new callback because the only
11299a2dd95SBruce Richardson 	 * thing on the list should be eal_alarm_callback() and we may
11399a2dd95SBruce Richardson 	 * be called just to reset the timer.
11499a2dd95SBruce Richardson 	 */
115bbbac4cdSHarman Kalra 	if (src != NULL &&
116bbbac4cdSHarman Kalra 			rte_intr_type_get(src->intr_handle) == RTE_INTR_HANDLE_ALARM &&
11799a2dd95SBruce Richardson 			!TAILQ_EMPTY(&src->callbacks)) {
11899a2dd95SBruce Richardson 		callback = NULL;
11999a2dd95SBruce Richardson 	} else {
12099a2dd95SBruce Richardson 		/* allocate a new interrupt callback entity */
12199a2dd95SBruce Richardson 		callback = calloc(1, sizeof(*callback));
12299a2dd95SBruce Richardson 		if (callback == NULL) {
123*ae67895bSDavid Marchand 			EAL_LOG(ERR, "Can not allocate memory");
12499a2dd95SBruce Richardson 			ret = -ENOMEM;
12599a2dd95SBruce Richardson 			goto fail;
12699a2dd95SBruce Richardson 		}
12799a2dd95SBruce Richardson 		callback->cb_fn = cb;
12899a2dd95SBruce Richardson 		callback->cb_arg = cb_arg;
12999a2dd95SBruce Richardson 		callback->pending_delete = 0;
13099a2dd95SBruce Richardson 		callback->ucb_fn = NULL;
13199a2dd95SBruce Richardson 
13299a2dd95SBruce Richardson 		if (src == NULL) {
13399a2dd95SBruce Richardson 			src = calloc(1, sizeof(*src));
13499a2dd95SBruce Richardson 			if (src == NULL) {
135*ae67895bSDavid Marchand 				EAL_LOG(ERR, "Can not allocate memory");
13699a2dd95SBruce Richardson 				ret = -ENOMEM;
13799a2dd95SBruce Richardson 				goto fail;
13899a2dd95SBruce Richardson 			} else {
139bbbac4cdSHarman Kalra 				src->intr_handle = rte_intr_instance_dup(intr_handle);
140bbbac4cdSHarman Kalra 				if (src->intr_handle == NULL) {
141*ae67895bSDavid Marchand 					EAL_LOG(ERR, "Can not create intr instance");
142bbbac4cdSHarman Kalra 					ret = -ENOMEM;
143bbbac4cdSHarman Kalra 					free(src);
144bbbac4cdSHarman Kalra 					src = NULL;
145bbbac4cdSHarman Kalra 					goto fail;
146bbbac4cdSHarman Kalra 				}
14799a2dd95SBruce Richardson 				TAILQ_INIT(&src->callbacks);
14899a2dd95SBruce Richardson 				TAILQ_INSERT_TAIL(&intr_sources, src, next);
14999a2dd95SBruce Richardson 			}
15099a2dd95SBruce Richardson 		}
15199a2dd95SBruce Richardson 
15299a2dd95SBruce Richardson 		/* we had no interrupts for this */
15399a2dd95SBruce Richardson 		if (TAILQ_EMPTY(&src->callbacks))
15499a2dd95SBruce Richardson 			add_event = 1;
15599a2dd95SBruce Richardson 
15699a2dd95SBruce Richardson 		TAILQ_INSERT_TAIL(&(src->callbacks), callback, next);
15799a2dd95SBruce Richardson 	}
15899a2dd95SBruce Richardson 
15999a2dd95SBruce Richardson 	/* add events to the queue. timer events are special as we need to
16099a2dd95SBruce Richardson 	 * re-set the timer.
16199a2dd95SBruce Richardson 	 */
162bbbac4cdSHarman Kalra 	if (add_event ||
163bbbac4cdSHarman Kalra 			rte_intr_type_get(src->intr_handle) == RTE_INTR_HANDLE_ALARM) {
16499a2dd95SBruce Richardson 		struct kevent ke;
16599a2dd95SBruce Richardson 
16699a2dd95SBruce Richardson 		memset(&ke, 0, sizeof(ke));
16799a2dd95SBruce Richardson 		ke.flags = EV_ADD; /* mark for addition to the queue */
16899a2dd95SBruce Richardson 
16999a2dd95SBruce Richardson 		if (intr_source_to_kevent(intr_handle, &ke) < 0) {
170*ae67895bSDavid Marchand 			EAL_LOG(ERR, "Cannot convert interrupt handle to kevent");
17199a2dd95SBruce Richardson 			ret = -ENODEV;
17299a2dd95SBruce Richardson 			goto fail;
17399a2dd95SBruce Richardson 		}
17499a2dd95SBruce Richardson 
17599a2dd95SBruce Richardson 		/**
17699a2dd95SBruce Richardson 		 * add the intr file descriptor into wait list.
17799a2dd95SBruce Richardson 		 */
17899a2dd95SBruce Richardson 		if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) {
17999a2dd95SBruce Richardson 			/* currently, nic_uio does not support interrupts, so
18099a2dd95SBruce Richardson 			 * this error will always be triggered and output to the
18199a2dd95SBruce Richardson 			 * user. so, don't output it unless debug log level set.
18299a2dd95SBruce Richardson 			 */
18399a2dd95SBruce Richardson 			if (errno == ENODEV)
184*ae67895bSDavid Marchand 				EAL_LOG(DEBUG, "Interrupt handle %d not supported",
185bbbac4cdSHarman Kalra 					rte_intr_fd_get(src->intr_handle));
18699a2dd95SBruce Richardson 			else
187*ae67895bSDavid Marchand 				EAL_LOG(ERR, "Error adding fd %d kevent, %s",
188bbbac4cdSHarman Kalra 					rte_intr_fd_get(src->intr_handle),
18999a2dd95SBruce Richardson 					strerror(errno));
19099a2dd95SBruce Richardson 			ret = -errno;
19199a2dd95SBruce Richardson 			goto fail;
19299a2dd95SBruce Richardson 		}
19399a2dd95SBruce Richardson 	}
19499a2dd95SBruce Richardson 	rte_eal_trace_intr_callback_register(intr_handle, cb, cb_arg, ret);
19599a2dd95SBruce Richardson 	rte_spinlock_unlock(&intr_lock);
19699a2dd95SBruce Richardson 
19799a2dd95SBruce Richardson 	return 0;
19899a2dd95SBruce Richardson fail:
19999a2dd95SBruce Richardson 	/* clean up */
20099a2dd95SBruce Richardson 	if (src != NULL) {
20199a2dd95SBruce Richardson 		if (callback != NULL)
20299a2dd95SBruce Richardson 			TAILQ_REMOVE(&(src->callbacks), callback, next);
20399a2dd95SBruce Richardson 		if (TAILQ_EMPTY(&(src->callbacks))) {
20499a2dd95SBruce Richardson 			TAILQ_REMOVE(&intr_sources, src, next);
20599a2dd95SBruce Richardson 			free(src);
20699a2dd95SBruce Richardson 		}
20799a2dd95SBruce Richardson 	}
20899a2dd95SBruce Richardson 	free(callback);
20999a2dd95SBruce Richardson 	rte_eal_trace_intr_callback_register(intr_handle, cb, cb_arg, ret);
21099a2dd95SBruce Richardson 	rte_spinlock_unlock(&intr_lock);
21199a2dd95SBruce Richardson 	return ret;
21299a2dd95SBruce Richardson }
21399a2dd95SBruce Richardson 
21499a2dd95SBruce Richardson int
rte_intr_callback_unregister_pending(const struct rte_intr_handle * intr_handle,rte_intr_callback_fn cb_fn,void * cb_arg,rte_intr_unregister_callback_fn ucb_fn)21599a2dd95SBruce Richardson rte_intr_callback_unregister_pending(const struct rte_intr_handle *intr_handle,
21699a2dd95SBruce Richardson 				rte_intr_callback_fn cb_fn, void *cb_arg,
21799a2dd95SBruce Richardson 				rte_intr_unregister_callback_fn ucb_fn)
21899a2dd95SBruce Richardson {
21999a2dd95SBruce Richardson 	int ret;
22099a2dd95SBruce Richardson 	struct rte_intr_source *src;
22199a2dd95SBruce Richardson 	struct rte_intr_callback *cb, *next;
22299a2dd95SBruce Richardson 
22399a2dd95SBruce Richardson 	/* do parameter checking first */
224bbbac4cdSHarman Kalra 	if (rte_intr_fd_get(intr_handle) < 0) {
225*ae67895bSDavid Marchand 		EAL_LOG(ERR,
226*ae67895bSDavid Marchand 		"Unregistering with invalid input parameter");
22799a2dd95SBruce Richardson 		return -EINVAL;
22899a2dd95SBruce Richardson 	}
22999a2dd95SBruce Richardson 
23099a2dd95SBruce Richardson 	if (kq < 0) {
231*ae67895bSDavid Marchand 		EAL_LOG(ERR, "Kqueue is not active");
23299a2dd95SBruce Richardson 		return -ENODEV;
23399a2dd95SBruce Richardson 	}
23499a2dd95SBruce Richardson 
23599a2dd95SBruce Richardson 	rte_spinlock_lock(&intr_lock);
23699a2dd95SBruce Richardson 
2377be78d02SJosh Soref 	/* check if the interrupt source for the fd is existent */
23899a2dd95SBruce Richardson 	TAILQ_FOREACH(src, &intr_sources, next)
239bbbac4cdSHarman Kalra 		if (rte_intr_fd_get(src->intr_handle) == rte_intr_fd_get(intr_handle))
24099a2dd95SBruce Richardson 			break;
24199a2dd95SBruce Richardson 
24299a2dd95SBruce Richardson 	/* No interrupt source registered for the fd */
24399a2dd95SBruce Richardson 	if (src == NULL) {
24499a2dd95SBruce Richardson 		ret = -ENOENT;
24599a2dd95SBruce Richardson 
24699a2dd95SBruce Richardson 	/* only usable if the source is active */
24799a2dd95SBruce Richardson 	} else if (src->active == 0) {
24899a2dd95SBruce Richardson 		ret = -EAGAIN;
24999a2dd95SBruce Richardson 
25099a2dd95SBruce Richardson 	} else {
25199a2dd95SBruce Richardson 		ret = 0;
25299a2dd95SBruce Richardson 
25399a2dd95SBruce Richardson 		/* walk through the callbacks and mark all that match. */
25499a2dd95SBruce Richardson 		for (cb = TAILQ_FIRST(&src->callbacks); cb != NULL; cb = next) {
25599a2dd95SBruce Richardson 			next = TAILQ_NEXT(cb, next);
25699a2dd95SBruce Richardson 			if (cb->cb_fn == cb_fn && (cb_arg == (void *)-1 ||
25799a2dd95SBruce Richardson 					cb->cb_arg == cb_arg)) {
25899a2dd95SBruce Richardson 				cb->pending_delete = 1;
25999a2dd95SBruce Richardson 				cb->ucb_fn = ucb_fn;
26099a2dd95SBruce Richardson 				ret++;
26199a2dd95SBruce Richardson 			}
26299a2dd95SBruce Richardson 		}
26399a2dd95SBruce Richardson 	}
26499a2dd95SBruce Richardson 
26599a2dd95SBruce Richardson 	rte_spinlock_unlock(&intr_lock);
26699a2dd95SBruce Richardson 
26799a2dd95SBruce Richardson 	return ret;
26899a2dd95SBruce Richardson }
26999a2dd95SBruce Richardson 
27099a2dd95SBruce Richardson int
rte_intr_callback_unregister(const struct rte_intr_handle * intr_handle,rte_intr_callback_fn cb_fn,void * cb_arg)27199a2dd95SBruce Richardson rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
27299a2dd95SBruce Richardson 		rte_intr_callback_fn cb_fn, void *cb_arg)
27399a2dd95SBruce Richardson {
27499a2dd95SBruce Richardson 	int ret;
27599a2dd95SBruce Richardson 	struct rte_intr_source *src;
27699a2dd95SBruce Richardson 	struct rte_intr_callback *cb, *next;
27799a2dd95SBruce Richardson 
27899a2dd95SBruce Richardson 	/* do parameter checking first */
279bbbac4cdSHarman Kalra 	if (rte_intr_fd_get(intr_handle) < 0) {
280*ae67895bSDavid Marchand 		EAL_LOG(ERR,
281*ae67895bSDavid Marchand 		"Unregistering with invalid input parameter");
28299a2dd95SBruce Richardson 		return -EINVAL;
28399a2dd95SBruce Richardson 	}
28499a2dd95SBruce Richardson 	if (kq < 0) {
285*ae67895bSDavid Marchand 		EAL_LOG(ERR, "Kqueue is not active");
28699a2dd95SBruce Richardson 		return -ENODEV;
28799a2dd95SBruce Richardson 	}
28899a2dd95SBruce Richardson 
28999a2dd95SBruce Richardson 	rte_spinlock_lock(&intr_lock);
29099a2dd95SBruce Richardson 
2917be78d02SJosh Soref 	/* check if the interrupt source for the fd is existent */
29299a2dd95SBruce Richardson 	TAILQ_FOREACH(src, &intr_sources, next)
293bbbac4cdSHarman Kalra 		if (rte_intr_fd_get(src->intr_handle) == rte_intr_fd_get(intr_handle))
29499a2dd95SBruce Richardson 			break;
29599a2dd95SBruce Richardson 
29699a2dd95SBruce Richardson 	/* No interrupt source registered for the fd */
29799a2dd95SBruce Richardson 	if (src == NULL) {
29899a2dd95SBruce Richardson 		ret = -ENOENT;
29999a2dd95SBruce Richardson 
30099a2dd95SBruce Richardson 	/* interrupt source has some active callbacks right now. */
30199a2dd95SBruce Richardson 	} else if (src->active != 0) {
30299a2dd95SBruce Richardson 		ret = -EAGAIN;
30399a2dd95SBruce Richardson 
30499a2dd95SBruce Richardson 	/* ok to remove. */
30599a2dd95SBruce Richardson 	} else {
30699a2dd95SBruce Richardson 		struct kevent ke;
30799a2dd95SBruce Richardson 
30899a2dd95SBruce Richardson 		ret = 0;
30999a2dd95SBruce Richardson 
31099a2dd95SBruce Richardson 		/* remove it from the kqueue */
31199a2dd95SBruce Richardson 		memset(&ke, 0, sizeof(ke));
31299a2dd95SBruce Richardson 		ke.flags = EV_DELETE; /* mark for deletion from the queue */
31399a2dd95SBruce Richardson 
31499a2dd95SBruce Richardson 		if (intr_source_to_kevent(intr_handle, &ke) < 0) {
315*ae67895bSDavid Marchand 			EAL_LOG(ERR, "Cannot convert to kevent");
31699a2dd95SBruce Richardson 			ret = -ENODEV;
31799a2dd95SBruce Richardson 			goto out;
31899a2dd95SBruce Richardson 		}
31999a2dd95SBruce Richardson 
32099a2dd95SBruce Richardson 		/**
32199a2dd95SBruce Richardson 		 * remove intr file descriptor from wait list.
32299a2dd95SBruce Richardson 		 */
32399a2dd95SBruce Richardson 		if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) {
324*ae67895bSDavid Marchand 			EAL_LOG(ERR, "Error removing fd %d kevent, %s",
325bbbac4cdSHarman Kalra 				rte_intr_fd_get(src->intr_handle),
326bbbac4cdSHarman Kalra 				strerror(errno));
32799a2dd95SBruce Richardson 			/* removing non-existent even is an expected condition
32899a2dd95SBruce Richardson 			 * in some circumstances (e.g. oneshot events).
32999a2dd95SBruce Richardson 			 */
33099a2dd95SBruce Richardson 		}
33199a2dd95SBruce Richardson 
33299a2dd95SBruce Richardson 		/*walk through the callbacks and remove all that match. */
33399a2dd95SBruce Richardson 		for (cb = TAILQ_FIRST(&src->callbacks); cb != NULL; cb = next) {
33499a2dd95SBruce Richardson 			next = TAILQ_NEXT(cb, next);
33599a2dd95SBruce Richardson 			if (cb->cb_fn == cb_fn && (cb_arg == (void *)-1 ||
33699a2dd95SBruce Richardson 					cb->cb_arg == cb_arg)) {
33799a2dd95SBruce Richardson 				TAILQ_REMOVE(&src->callbacks, cb, next);
33899a2dd95SBruce Richardson 				free(cb);
33999a2dd95SBruce Richardson 				ret++;
34099a2dd95SBruce Richardson 			}
34199a2dd95SBruce Richardson 		}
34299a2dd95SBruce Richardson 
34399a2dd95SBruce Richardson 		/* all callbacks for that source are removed. */
34499a2dd95SBruce Richardson 		if (TAILQ_EMPTY(&src->callbacks)) {
34599a2dd95SBruce Richardson 			TAILQ_REMOVE(&intr_sources, src, next);
34699a2dd95SBruce Richardson 			free(src);
34799a2dd95SBruce Richardson 		}
34899a2dd95SBruce Richardson 	}
34999a2dd95SBruce Richardson out:
35099a2dd95SBruce Richardson 	rte_eal_trace_intr_callback_unregister(intr_handle, cb_fn, cb_arg,
35199a2dd95SBruce Richardson 		ret);
35299a2dd95SBruce Richardson 	rte_spinlock_unlock(&intr_lock);
35399a2dd95SBruce Richardson 
35499a2dd95SBruce Richardson 	return ret;
35599a2dd95SBruce Richardson }
35699a2dd95SBruce Richardson 
35799a2dd95SBruce Richardson int
rte_intr_callback_unregister_sync(const struct rte_intr_handle * intr_handle,rte_intr_callback_fn cb_fn,void * cb_arg)35899a2dd95SBruce Richardson rte_intr_callback_unregister_sync(const struct rte_intr_handle *intr_handle,
35999a2dd95SBruce Richardson 		rte_intr_callback_fn cb_fn, void *cb_arg)
36099a2dd95SBruce Richardson {
36199a2dd95SBruce Richardson 	int ret = 0;
36299a2dd95SBruce Richardson 
36399a2dd95SBruce Richardson 	while ((ret = rte_intr_callback_unregister(intr_handle, cb_fn, cb_arg)) == -EAGAIN)
36499a2dd95SBruce Richardson 		rte_pause();
36599a2dd95SBruce Richardson 
36699a2dd95SBruce Richardson 	return ret;
36799a2dd95SBruce Richardson }
36899a2dd95SBruce Richardson 
36999a2dd95SBruce Richardson int
rte_intr_enable(const struct rte_intr_handle * intr_handle)37099a2dd95SBruce Richardson rte_intr_enable(const struct rte_intr_handle *intr_handle)
37199a2dd95SBruce Richardson {
37299a2dd95SBruce Richardson 	int rc = 0;
37399a2dd95SBruce Richardson 
37499a2dd95SBruce Richardson 	if (intr_handle == NULL)
37599a2dd95SBruce Richardson 		return -1;
37699a2dd95SBruce Richardson 
377bbbac4cdSHarman Kalra 	if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) {
37899a2dd95SBruce Richardson 		rc = 0;
37999a2dd95SBruce Richardson 		goto out;
38099a2dd95SBruce Richardson 	}
38199a2dd95SBruce Richardson 
382bbbac4cdSHarman Kalra 	if (rte_intr_fd_get(intr_handle) < 0 ||
383bbbac4cdSHarman Kalra 			rte_intr_dev_fd_get(intr_handle) < 0) {
38499a2dd95SBruce Richardson 		rc = -1;
38599a2dd95SBruce Richardson 		goto out;
38699a2dd95SBruce Richardson 	}
38799a2dd95SBruce Richardson 
388bbbac4cdSHarman Kalra 	switch (rte_intr_type_get(intr_handle)) {
38999a2dd95SBruce Richardson 	/* not used at this moment */
39099a2dd95SBruce Richardson 	case RTE_INTR_HANDLE_ALARM:
39199a2dd95SBruce Richardson 		rc = -1;
39299a2dd95SBruce Richardson 		break;
39399a2dd95SBruce Richardson 	/* not used at this moment */
39499a2dd95SBruce Richardson 	case RTE_INTR_HANDLE_DEV_EVENT:
39599a2dd95SBruce Richardson 		rc = -1;
39699a2dd95SBruce Richardson 		break;
39799a2dd95SBruce Richardson 	/* unknown handle type */
39899a2dd95SBruce Richardson 	default:
399*ae67895bSDavid Marchand 		EAL_LOG(ERR, "Unknown handle type of fd %d",
400bbbac4cdSHarman Kalra 			rte_intr_fd_get(intr_handle));
40199a2dd95SBruce Richardson 		rc = -1;
40299a2dd95SBruce Richardson 		break;
40399a2dd95SBruce Richardson 	}
40499a2dd95SBruce Richardson 
40599a2dd95SBruce Richardson out:
40699a2dd95SBruce Richardson 	rte_eal_trace_intr_enable(intr_handle, rc);
40799a2dd95SBruce Richardson 	return rc;
40899a2dd95SBruce Richardson }
40999a2dd95SBruce Richardson 
41099a2dd95SBruce Richardson int
rte_intr_disable(const struct rte_intr_handle * intr_handle)41199a2dd95SBruce Richardson rte_intr_disable(const struct rte_intr_handle *intr_handle)
41299a2dd95SBruce Richardson {
41399a2dd95SBruce Richardson 	int rc = 0;
41499a2dd95SBruce Richardson 
41599a2dd95SBruce Richardson 	if (intr_handle == NULL)
41699a2dd95SBruce Richardson 		return -1;
41799a2dd95SBruce Richardson 
418bbbac4cdSHarman Kalra 	if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV) {
41999a2dd95SBruce Richardson 		rc = 0;
42099a2dd95SBruce Richardson 		goto out;
42199a2dd95SBruce Richardson 	}
42299a2dd95SBruce Richardson 
423bbbac4cdSHarman Kalra 	if (rte_intr_fd_get(intr_handle) < 0 ||
424bbbac4cdSHarman Kalra 			rte_intr_dev_fd_get(intr_handle) < 0) {
42599a2dd95SBruce Richardson 		rc = -1;
42699a2dd95SBruce Richardson 		goto out;
42799a2dd95SBruce Richardson 	}
42899a2dd95SBruce Richardson 
429bbbac4cdSHarman Kalra 	switch (rte_intr_type_get(intr_handle)) {
43099a2dd95SBruce Richardson 	/* not used at this moment */
43199a2dd95SBruce Richardson 	case RTE_INTR_HANDLE_ALARM:
43299a2dd95SBruce Richardson 		rc = -1;
43399a2dd95SBruce Richardson 		break;
43499a2dd95SBruce Richardson 	/* not used at this moment */
43599a2dd95SBruce Richardson 	case RTE_INTR_HANDLE_DEV_EVENT:
43699a2dd95SBruce Richardson 		rc = -1;
43799a2dd95SBruce Richardson 		break;
43899a2dd95SBruce Richardson 	/* unknown handle type */
43999a2dd95SBruce Richardson 	default:
440*ae67895bSDavid Marchand 		EAL_LOG(ERR, "Unknown handle type of fd %d",
441bbbac4cdSHarman Kalra 			rte_intr_fd_get(intr_handle));
44299a2dd95SBruce Richardson 		rc = -1;
44399a2dd95SBruce Richardson 		break;
44499a2dd95SBruce Richardson 	}
44599a2dd95SBruce Richardson out:
44699a2dd95SBruce Richardson 	rte_eal_trace_intr_disable(intr_handle, rc);
44799a2dd95SBruce Richardson 	return rc;
44899a2dd95SBruce Richardson }
44999a2dd95SBruce Richardson 
45099a2dd95SBruce Richardson int
rte_intr_ack(const struct rte_intr_handle * intr_handle)45199a2dd95SBruce Richardson rte_intr_ack(const struct rte_intr_handle *intr_handle)
45299a2dd95SBruce Richardson {
453bbbac4cdSHarman Kalra 	if (rte_intr_type_get(intr_handle) == RTE_INTR_HANDLE_VDEV)
45499a2dd95SBruce Richardson 		return 0;
45599a2dd95SBruce Richardson 
45699a2dd95SBruce Richardson 	return -1;
45799a2dd95SBruce Richardson }
45899a2dd95SBruce Richardson 
45999a2dd95SBruce Richardson static void
eal_intr_process_interrupts(struct kevent * events,int nfds)46099a2dd95SBruce Richardson eal_intr_process_interrupts(struct kevent *events, int nfds)
46199a2dd95SBruce Richardson {
46299a2dd95SBruce Richardson 	struct rte_intr_callback active_cb;
46399a2dd95SBruce Richardson 	union rte_intr_read_buffer buf;
46499a2dd95SBruce Richardson 	struct rte_intr_callback *cb, *next;
46599a2dd95SBruce Richardson 	struct rte_intr_source *src;
46699a2dd95SBruce Richardson 	bool call = false;
46799a2dd95SBruce Richardson 	int n, bytes_read;
46899a2dd95SBruce Richardson 	struct kevent ke;
46999a2dd95SBruce Richardson 
47099a2dd95SBruce Richardson 	for (n = 0; n < nfds; n++) {
47199a2dd95SBruce Richardson 		int event_fd = events[n].ident;
47299a2dd95SBruce Richardson 
47399a2dd95SBruce Richardson 		rte_spinlock_lock(&intr_lock);
47499a2dd95SBruce Richardson 		TAILQ_FOREACH(src, &intr_sources, next)
475bbbac4cdSHarman Kalra 			if (rte_intr_fd_get(src->intr_handle) == event_fd)
47699a2dd95SBruce Richardson 				break;
47799a2dd95SBruce Richardson 		if (src == NULL) {
47899a2dd95SBruce Richardson 			rte_spinlock_unlock(&intr_lock);
47999a2dd95SBruce Richardson 			continue;
48099a2dd95SBruce Richardson 		}
48199a2dd95SBruce Richardson 
48299a2dd95SBruce Richardson 		/* mark this interrupt source as active and release the lock. */
48399a2dd95SBruce Richardson 		src->active = 1;
48499a2dd95SBruce Richardson 		rte_spinlock_unlock(&intr_lock);
48599a2dd95SBruce Richardson 
48699a2dd95SBruce Richardson 		/* set the length to be read dor different handle type */
487bbbac4cdSHarman Kalra 		switch (rte_intr_type_get(src->intr_handle)) {
48899a2dd95SBruce Richardson 		case RTE_INTR_HANDLE_ALARM:
48999a2dd95SBruce Richardson 			bytes_read = 0;
49099a2dd95SBruce Richardson 			call = true;
49199a2dd95SBruce Richardson 			break;
49299a2dd95SBruce Richardson 		case RTE_INTR_HANDLE_VDEV:
49399a2dd95SBruce Richardson 		case RTE_INTR_HANDLE_EXT:
49499a2dd95SBruce Richardson 			bytes_read = 0;
49599a2dd95SBruce Richardson 			call = true;
49699a2dd95SBruce Richardson 			break;
49799a2dd95SBruce Richardson 		case RTE_INTR_HANDLE_DEV_EVENT:
49899a2dd95SBruce Richardson 			bytes_read = 0;
49999a2dd95SBruce Richardson 			call = true;
50099a2dd95SBruce Richardson 			break;
50199a2dd95SBruce Richardson 		default:
50299a2dd95SBruce Richardson 			bytes_read = 1;
50399a2dd95SBruce Richardson 			break;
50499a2dd95SBruce Richardson 		}
50599a2dd95SBruce Richardson 
50699a2dd95SBruce Richardson 		if (bytes_read > 0) {
50799a2dd95SBruce Richardson 			/**
50899a2dd95SBruce Richardson 			 * read out to clear the ready-to-be-read flag
50999a2dd95SBruce Richardson 			 * for epoll_wait.
51099a2dd95SBruce Richardson 			 */
51199a2dd95SBruce Richardson 			bytes_read = read(event_fd, &buf, bytes_read);
51299a2dd95SBruce Richardson 			if (bytes_read < 0) {
51399a2dd95SBruce Richardson 				if (errno == EINTR || errno == EWOULDBLOCK)
51499a2dd95SBruce Richardson 					continue;
51599a2dd95SBruce Richardson 
516*ae67895bSDavid Marchand 				EAL_LOG(ERR, "Error reading from file "
517*ae67895bSDavid Marchand 					"descriptor %d: %s",
51899a2dd95SBruce Richardson 					event_fd,
51999a2dd95SBruce Richardson 					strerror(errno));
52099a2dd95SBruce Richardson 			} else if (bytes_read == 0)
521*ae67895bSDavid Marchand 				EAL_LOG(ERR, "Read nothing from file "
522*ae67895bSDavid Marchand 					"descriptor %d", event_fd);
52399a2dd95SBruce Richardson 			else
52499a2dd95SBruce Richardson 				call = true;
52599a2dd95SBruce Richardson 		}
52699a2dd95SBruce Richardson 
52799a2dd95SBruce Richardson 		/* grab a lock, again to call callbacks and update status. */
52899a2dd95SBruce Richardson 		rte_spinlock_lock(&intr_lock);
52999a2dd95SBruce Richardson 
53099a2dd95SBruce Richardson 		if (call) {
53199a2dd95SBruce Richardson 			/* Finally, call all callbacks. */
53299a2dd95SBruce Richardson 			TAILQ_FOREACH(cb, &src->callbacks, next) {
53399a2dd95SBruce Richardson 
53499a2dd95SBruce Richardson 				/* make a copy and unlock. */
53599a2dd95SBruce Richardson 				active_cb = *cb;
53699a2dd95SBruce Richardson 				rte_spinlock_unlock(&intr_lock);
53799a2dd95SBruce Richardson 
53899a2dd95SBruce Richardson 				/* call the actual callback */
53999a2dd95SBruce Richardson 				active_cb.cb_fn(active_cb.cb_arg);
54099a2dd95SBruce Richardson 
54199a2dd95SBruce Richardson 				/*get the lock back. */
54299a2dd95SBruce Richardson 				rte_spinlock_lock(&intr_lock);
54399a2dd95SBruce Richardson 			}
54499a2dd95SBruce Richardson 		}
54599a2dd95SBruce Richardson 
54699a2dd95SBruce Richardson 		/* we done with that interrupt source, release it. */
54799a2dd95SBruce Richardson 		src->active = 0;
54899a2dd95SBruce Richardson 
54999a2dd95SBruce Richardson 		/* check if any callback are supposed to be removed */
55099a2dd95SBruce Richardson 		for (cb = TAILQ_FIRST(&src->callbacks); cb != NULL; cb = next) {
55199a2dd95SBruce Richardson 			next = TAILQ_NEXT(cb, next);
55299a2dd95SBruce Richardson 			if (cb->pending_delete) {
55399a2dd95SBruce Richardson 				/* remove it from the kqueue */
55499a2dd95SBruce Richardson 				memset(&ke, 0, sizeof(ke));
55599a2dd95SBruce Richardson 				/* mark for deletion from the queue */
55699a2dd95SBruce Richardson 				ke.flags = EV_DELETE;
55799a2dd95SBruce Richardson 
558bbbac4cdSHarman Kalra 				if (intr_source_to_kevent(src->intr_handle, &ke) < 0) {
559*ae67895bSDavid Marchand 					EAL_LOG(ERR, "Cannot convert to kevent");
56099a2dd95SBruce Richardson 					rte_spinlock_unlock(&intr_lock);
56199a2dd95SBruce Richardson 					return;
56299a2dd95SBruce Richardson 				}
56399a2dd95SBruce Richardson 
56499a2dd95SBruce Richardson 				/**
56599a2dd95SBruce Richardson 				 * remove intr file descriptor from wait list.
56699a2dd95SBruce Richardson 				 */
56799a2dd95SBruce Richardson 				if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) {
568*ae67895bSDavid Marchand 					EAL_LOG(ERR, "Error removing fd %d kevent, %s",
569bbbac4cdSHarman Kalra 						rte_intr_fd_get(src->intr_handle),
57099a2dd95SBruce Richardson 						strerror(errno));
57199a2dd95SBruce Richardson 					/* removing non-existent even is an expected
57299a2dd95SBruce Richardson 					 * condition in some circumstances
57399a2dd95SBruce Richardson 					 * (e.g. oneshot events).
57499a2dd95SBruce Richardson 					 */
57599a2dd95SBruce Richardson 				}
57699a2dd95SBruce Richardson 
57799a2dd95SBruce Richardson 				TAILQ_REMOVE(&src->callbacks, cb, next);
57899a2dd95SBruce Richardson 				if (cb->ucb_fn)
579bbbac4cdSHarman Kalra 					cb->ucb_fn(src->intr_handle, cb->cb_arg);
58099a2dd95SBruce Richardson 				free(cb);
58199a2dd95SBruce Richardson 			}
58299a2dd95SBruce Richardson 		}
58399a2dd95SBruce Richardson 
58499a2dd95SBruce Richardson 		/* all callbacks for that source are removed. */
58599a2dd95SBruce Richardson 		if (TAILQ_EMPTY(&src->callbacks)) {
58699a2dd95SBruce Richardson 			TAILQ_REMOVE(&intr_sources, src, next);
58799a2dd95SBruce Richardson 			free(src);
58899a2dd95SBruce Richardson 		}
58999a2dd95SBruce Richardson 
59099a2dd95SBruce Richardson 		rte_spinlock_unlock(&intr_lock);
59199a2dd95SBruce Richardson 	}
59299a2dd95SBruce Richardson }
59399a2dd95SBruce Richardson 
5941c1abf17SThomas Monjalon static uint32_t
eal_intr_thread_main(void * arg __rte_unused)59599a2dd95SBruce Richardson eal_intr_thread_main(void *arg __rte_unused)
59699a2dd95SBruce Richardson {
59799a2dd95SBruce Richardson 	struct kevent events[MAX_INTR_EVENTS];
59899a2dd95SBruce Richardson 	int nfds;
59999a2dd95SBruce Richardson 
60099a2dd95SBruce Richardson 	/* host thread, never break out */
60199a2dd95SBruce Richardson 	for (;;) {
60299a2dd95SBruce Richardson 		/* do not change anything, just wait */
60399a2dd95SBruce Richardson 		nfds = kevent(kq, NULL, 0, events, MAX_INTR_EVENTS, NULL);
60499a2dd95SBruce Richardson 
60599a2dd95SBruce Richardson 		/* kevent fail */
60699a2dd95SBruce Richardson 		if (nfds < 0) {
60799a2dd95SBruce Richardson 			if (errno == EINTR)
60899a2dd95SBruce Richardson 				continue;
609*ae67895bSDavid Marchand 			EAL_LOG(ERR,
610*ae67895bSDavid Marchand 				"kevent returns with fail");
61199a2dd95SBruce Richardson 			break;
61299a2dd95SBruce Richardson 		}
61399a2dd95SBruce Richardson 		/* kevent timeout, will never happen here */
61499a2dd95SBruce Richardson 		else if (nfds == 0)
61599a2dd95SBruce Richardson 			continue;
61699a2dd95SBruce Richardson 
61799a2dd95SBruce Richardson 		/* kevent has at least one fd ready to read */
61899a2dd95SBruce Richardson 		eal_intr_process_interrupts(events, nfds);
61999a2dd95SBruce Richardson 	}
62099a2dd95SBruce Richardson 	close(kq);
62199a2dd95SBruce Richardson 	kq = -1;
6221c1abf17SThomas Monjalon 	return 0;
62399a2dd95SBruce Richardson }
62499a2dd95SBruce Richardson 
62599a2dd95SBruce Richardson int
rte_eal_intr_init(void)62699a2dd95SBruce Richardson rte_eal_intr_init(void)
62799a2dd95SBruce Richardson {
62899a2dd95SBruce Richardson 	int ret = 0;
62999a2dd95SBruce Richardson 
63099a2dd95SBruce Richardson 	/* init the global interrupt source head */
63199a2dd95SBruce Richardson 	TAILQ_INIT(&intr_sources);
63299a2dd95SBruce Richardson 
63399a2dd95SBruce Richardson 	kq = kqueue();
63499a2dd95SBruce Richardson 	if (kq < 0) {
635*ae67895bSDavid Marchand 		EAL_LOG(ERR, "Cannot create kqueue instance");
63699a2dd95SBruce Richardson 		return -1;
63799a2dd95SBruce Richardson 	}
63899a2dd95SBruce Richardson 
63999a2dd95SBruce Richardson 	/* create the host thread to wait/handle the interrupt */
6401c1abf17SThomas Monjalon 	ret = rte_thread_create_internal_control(&intr_thread, "intr",
64199a2dd95SBruce Richardson 			eal_intr_thread_main, NULL);
64299a2dd95SBruce Richardson 	if (ret != 0) {
64399a2dd95SBruce Richardson 		rte_errno = -ret;
644*ae67895bSDavid Marchand 		EAL_LOG(ERR,
645*ae67895bSDavid Marchand 			"Failed to create thread for interrupt handling");
64699a2dd95SBruce Richardson 	}
64799a2dd95SBruce Richardson 
64899a2dd95SBruce Richardson 	return ret;
64999a2dd95SBruce Richardson }
65099a2dd95SBruce Richardson 
65199a2dd95SBruce Richardson int
rte_intr_rx_ctl(struct rte_intr_handle * intr_handle,int epfd,int op,unsigned int vec,void * data)65299a2dd95SBruce Richardson rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
65399a2dd95SBruce Richardson 		int epfd, int op, unsigned int vec, void *data)
65499a2dd95SBruce Richardson {
65599a2dd95SBruce Richardson 	RTE_SET_USED(intr_handle);
65699a2dd95SBruce Richardson 	RTE_SET_USED(epfd);
65799a2dd95SBruce Richardson 	RTE_SET_USED(op);
65899a2dd95SBruce Richardson 	RTE_SET_USED(vec);
65999a2dd95SBruce Richardson 	RTE_SET_USED(data);
66099a2dd95SBruce Richardson 
66199a2dd95SBruce Richardson 	return -ENOTSUP;
66299a2dd95SBruce Richardson }
66399a2dd95SBruce Richardson 
66499a2dd95SBruce Richardson int
rte_intr_efd_enable(struct rte_intr_handle * intr_handle,uint32_t nb_efd)66599a2dd95SBruce Richardson rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
66699a2dd95SBruce Richardson {
66799a2dd95SBruce Richardson 	RTE_SET_USED(intr_handle);
66899a2dd95SBruce Richardson 	RTE_SET_USED(nb_efd);
66999a2dd95SBruce Richardson 
67099a2dd95SBruce Richardson 	return 0;
67199a2dd95SBruce Richardson }
67299a2dd95SBruce Richardson 
67399a2dd95SBruce Richardson void
rte_intr_efd_disable(struct rte_intr_handle * intr_handle)67499a2dd95SBruce Richardson rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
67599a2dd95SBruce Richardson {
67699a2dd95SBruce Richardson 	RTE_SET_USED(intr_handle);
67799a2dd95SBruce Richardson }
67899a2dd95SBruce Richardson 
67999a2dd95SBruce Richardson int
rte_intr_dp_is_en(struct rte_intr_handle * intr_handle)68099a2dd95SBruce Richardson rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
68199a2dd95SBruce Richardson {
68299a2dd95SBruce Richardson 	RTE_SET_USED(intr_handle);
68399a2dd95SBruce Richardson 	return 0;
68499a2dd95SBruce Richardson }
68599a2dd95SBruce Richardson 
68699a2dd95SBruce Richardson int
rte_intr_allow_others(struct rte_intr_handle * intr_handle)68799a2dd95SBruce Richardson rte_intr_allow_others(struct rte_intr_handle *intr_handle)
68899a2dd95SBruce Richardson {
68999a2dd95SBruce Richardson 	RTE_SET_USED(intr_handle);
69099a2dd95SBruce Richardson 	return 1;
69199a2dd95SBruce Richardson }
69299a2dd95SBruce Richardson 
69399a2dd95SBruce Richardson int
rte_intr_cap_multiple(struct rte_intr_handle * intr_handle)69499a2dd95SBruce Richardson rte_intr_cap_multiple(struct rte_intr_handle *intr_handle)
69599a2dd95SBruce Richardson {
69699a2dd95SBruce Richardson 	RTE_SET_USED(intr_handle);
69799a2dd95SBruce Richardson 	return 0;
69899a2dd95SBruce Richardson }
69999a2dd95SBruce Richardson 
70099a2dd95SBruce Richardson int
rte_epoll_wait(int epfd,struct rte_epoll_event * events,int maxevents,int timeout)70199a2dd95SBruce Richardson rte_epoll_wait(int epfd, struct rte_epoll_event *events,
70299a2dd95SBruce Richardson 		int maxevents, int timeout)
70399a2dd95SBruce Richardson {
70499a2dd95SBruce Richardson 	RTE_SET_USED(epfd);
70599a2dd95SBruce Richardson 	RTE_SET_USED(events);
70699a2dd95SBruce Richardson 	RTE_SET_USED(maxevents);
70799a2dd95SBruce Richardson 	RTE_SET_USED(timeout);
70899a2dd95SBruce Richardson 
70999a2dd95SBruce Richardson 	return -ENOTSUP;
71099a2dd95SBruce Richardson }
71199a2dd95SBruce Richardson 
71299a2dd95SBruce Richardson int
rte_epoll_wait_interruptible(int epfd,struct rte_epoll_event * events,int maxevents,int timeout)71399a2dd95SBruce Richardson rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events,
71499a2dd95SBruce Richardson 			     int maxevents, int timeout)
71599a2dd95SBruce Richardson {
71699a2dd95SBruce Richardson 	RTE_SET_USED(epfd);
71799a2dd95SBruce Richardson 	RTE_SET_USED(events);
71899a2dd95SBruce Richardson 	RTE_SET_USED(maxevents);
71999a2dd95SBruce Richardson 	RTE_SET_USED(timeout);
72099a2dd95SBruce Richardson 
72199a2dd95SBruce Richardson 	return -ENOTSUP;
72299a2dd95SBruce Richardson }
72399a2dd95SBruce Richardson 
72499a2dd95SBruce Richardson int
rte_epoll_ctl(int epfd,int op,int fd,struct rte_epoll_event * event)72599a2dd95SBruce Richardson rte_epoll_ctl(int epfd, int op, int fd, struct rte_epoll_event *event)
72699a2dd95SBruce Richardson {
72799a2dd95SBruce Richardson 	RTE_SET_USED(epfd);
72899a2dd95SBruce Richardson 	RTE_SET_USED(op);
72999a2dd95SBruce Richardson 	RTE_SET_USED(fd);
73099a2dd95SBruce Richardson 	RTE_SET_USED(event);
73199a2dd95SBruce Richardson 
73299a2dd95SBruce Richardson 	return -ENOTSUP;
73399a2dd95SBruce Richardson }
73499a2dd95SBruce Richardson 
73599a2dd95SBruce Richardson int
rte_intr_tls_epfd(void)73699a2dd95SBruce Richardson rte_intr_tls_epfd(void)
73799a2dd95SBruce Richardson {
73899a2dd95SBruce Richardson 	return -ENOTSUP;
73999a2dd95SBruce Richardson }
74099a2dd95SBruce Richardson 
74199a2dd95SBruce Richardson void
rte_intr_free_epoll_fd(struct rte_intr_handle * intr_handle)74299a2dd95SBruce Richardson rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle)
74399a2dd95SBruce Richardson {
74499a2dd95SBruce Richardson 	RTE_SET_USED(intr_handle);
74599a2dd95SBruce Richardson }
74699a2dd95SBruce Richardson 
rte_thread_is_intr(void)74799a2dd95SBruce Richardson int rte_thread_is_intr(void)
74899a2dd95SBruce Richardson {
7491c1abf17SThomas Monjalon 	return rte_thread_equal(intr_thread, rte_thread_self());
75099a2dd95SBruce Richardson }
751