Imported Upstream version 16.04
[deb_dpdk.git] / lib / librte_eal / linuxapp / eal / eal_interrupts.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <stdint.h>
36 #include <stdlib.h>
37 #include <pthread.h>
38 #include <sys/queue.h>
39 #include <stdarg.h>
40 #include <unistd.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <inttypes.h>
44 #include <sys/epoll.h>
45 #include <sys/signalfd.h>
46 #include <sys/ioctl.h>
47 #include <sys/eventfd.h>
48 #include <assert.h>
49
50 #include <rte_common.h>
51 #include <rte_interrupts.h>
52 #include <rte_memory.h>
53 #include <rte_memzone.h>
54 #include <rte_launch.h>
55 #include <rte_eal.h>
56 #include <rte_per_lcore.h>
57 #include <rte_lcore.h>
58 #include <rte_atomic.h>
59 #include <rte_branch_prediction.h>
60 #include <rte_ring.h>
61 #include <rte_debug.h>
62 #include <rte_log.h>
63 #include <rte_mempool.h>
64 #include <rte_pci.h>
65 #include <rte_malloc.h>
66 #include <rte_errno.h>
67 #include <rte_spinlock.h>
68
69 #include "eal_private.h"
70 #include "eal_vfio.h"
71 #include "eal_thread.h"
72
73 #define EAL_INTR_EPOLL_WAIT_FOREVER (-1)
74 #define NB_OTHER_INTR               1
75
76 static RTE_DEFINE_PER_LCORE(int, _epfd) = -1; /**< epoll fd per thread */
77
78 /**
79  * union for pipe fds.
80  */
81 union intr_pipefds{
82         struct {
83                 int pipefd[2];
84         };
85         struct {
86                 int readfd;
87                 int writefd;
88         };
89 };
90
91 /**
92  * union buffer for reading on different devices
93  */
94 union rte_intr_read_buffer {
95         int uio_intr_count;              /* for uio device */
96 #ifdef VFIO_PRESENT
97         uint64_t vfio_intr_count;        /* for vfio device */
98 #endif
99         uint64_t timerfd_num;            /* for timerfd */
100         char charbuf[16];                /* for others */
101 };
102
103 TAILQ_HEAD(rte_intr_cb_list, rte_intr_callback);
104 TAILQ_HEAD(rte_intr_source_list, rte_intr_source);
105
106 struct rte_intr_callback {
107         TAILQ_ENTRY(rte_intr_callback) next;
108         rte_intr_callback_fn cb_fn;  /**< callback address */
109         void *cb_arg;                /**< parameter for callback */
110 };
111
112 struct rte_intr_source {
113         TAILQ_ENTRY(rte_intr_source) next;
114         struct rte_intr_handle intr_handle; /**< interrupt handle */
115         struct rte_intr_cb_list callbacks;  /**< user callbacks */
116         uint32_t active;
117 };
118
119 /* global spinlock for interrupt data operation */
120 static rte_spinlock_t intr_lock = RTE_SPINLOCK_INITIALIZER;
121
122 /* union buffer for pipe read/write */
123 static union intr_pipefds intr_pipe;
124
125 /* interrupt sources list */
126 static struct rte_intr_source_list intr_sources;
127
128 /* interrupt handling thread */
129 static pthread_t intr_thread;
130
131 /* VFIO interrupts */
132 #ifdef VFIO_PRESENT
133
134 #define IRQ_SET_BUF_LEN  (sizeof(struct vfio_irq_set) + sizeof(int))
135 /* irq set buffer length for queue interrupts and LSC interrupt */
136 #define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
137                               sizeof(int) * (RTE_MAX_RXTX_INTR_VEC_ID + 1))
138
139 /* enable legacy (INTx) interrupts */
140 static int
141 vfio_enable_intx(struct rte_intr_handle *intr_handle) {
142         struct vfio_irq_set *irq_set;
143         char irq_set_buf[IRQ_SET_BUF_LEN];
144         int len, ret;
145         int *fd_ptr;
146
147         len = sizeof(irq_set_buf);
148
149         /* enable INTx */
150         irq_set = (struct vfio_irq_set *) irq_set_buf;
151         irq_set->argsz = len;
152         irq_set->count = 1;
153         irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
154         irq_set->index = VFIO_PCI_INTX_IRQ_INDEX;
155         irq_set->start = 0;
156         fd_ptr = (int *) &irq_set->data;
157         *fd_ptr = intr_handle->fd;
158
159         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
160
161         if (ret) {
162                 RTE_LOG(ERR, EAL, "Error enabling INTx interrupts for fd %d\n",
163                                                 intr_handle->fd);
164                 return -1;
165         }
166
167         /* unmask INTx after enabling */
168         memset(irq_set, 0, len);
169         len = sizeof(struct vfio_irq_set);
170         irq_set->argsz = len;
171         irq_set->count = 1;
172         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK;
173         irq_set->index = VFIO_PCI_INTX_IRQ_INDEX;
174         irq_set->start = 0;
175
176         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
177
178         if (ret) {
179                 RTE_LOG(ERR, EAL, "Error unmasking INTx interrupts for fd %d\n",
180                                                 intr_handle->fd);
181                 return -1;
182         }
183         return 0;
184 }
185
186 /* disable legacy (INTx) interrupts */
187 static int
188 vfio_disable_intx(struct rte_intr_handle *intr_handle) {
189         struct vfio_irq_set *irq_set;
190         char irq_set_buf[IRQ_SET_BUF_LEN];
191         int len, ret;
192
193         len = sizeof(struct vfio_irq_set);
194
195         /* mask interrupts before disabling */
196         irq_set = (struct vfio_irq_set *) irq_set_buf;
197         irq_set->argsz = len;
198         irq_set->count = 1;
199         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK;
200         irq_set->index = VFIO_PCI_INTX_IRQ_INDEX;
201         irq_set->start = 0;
202
203         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
204
205         if (ret) {
206                 RTE_LOG(ERR, EAL, "Error unmasking INTx interrupts for fd %d\n",
207                                                 intr_handle->fd);
208                 return -1;
209         }
210
211         /* disable INTx*/
212         memset(irq_set, 0, len);
213         irq_set->argsz = len;
214         irq_set->count = 0;
215         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
216         irq_set->index = VFIO_PCI_INTX_IRQ_INDEX;
217         irq_set->start = 0;
218
219         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
220
221         if (ret) {
222                 RTE_LOG(ERR, EAL,
223                         "Error disabling INTx interrupts for fd %d\n", intr_handle->fd);
224                 return -1;
225         }
226         return 0;
227 }
228
229 /* enable MSI interrupts */
230 static int
231 vfio_enable_msi(struct rte_intr_handle *intr_handle) {
232         int len, ret;
233         char irq_set_buf[IRQ_SET_BUF_LEN];
234         struct vfio_irq_set *irq_set;
235         int *fd_ptr;
236
237         len = sizeof(irq_set_buf);
238
239         irq_set = (struct vfio_irq_set *) irq_set_buf;
240         irq_set->argsz = len;
241         irq_set->count = 1;
242         irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
243         irq_set->index = VFIO_PCI_MSI_IRQ_INDEX;
244         irq_set->start = 0;
245         fd_ptr = (int *) &irq_set->data;
246         *fd_ptr = intr_handle->fd;
247
248         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
249
250         if (ret) {
251                 RTE_LOG(ERR, EAL, "Error enabling MSI interrupts for fd %d\n",
252                                                 intr_handle->fd);
253                 return -1;
254         }
255         return 0;
256 }
257
258 /* disable MSI interrupts */
259 static int
260 vfio_disable_msi(struct rte_intr_handle *intr_handle) {
261         struct vfio_irq_set *irq_set;
262         char irq_set_buf[IRQ_SET_BUF_LEN];
263         int len, ret;
264
265         len = sizeof(struct vfio_irq_set);
266
267         irq_set = (struct vfio_irq_set *) irq_set_buf;
268         irq_set->argsz = len;
269         irq_set->count = 0;
270         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
271         irq_set->index = VFIO_PCI_MSI_IRQ_INDEX;
272         irq_set->start = 0;
273
274         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
275
276         if (ret)
277                 RTE_LOG(ERR, EAL,
278                         "Error disabling MSI interrupts for fd %d\n", intr_handle->fd);
279
280         return ret;
281 }
282
283 /* enable MSI-X interrupts */
284 static int
285 vfio_enable_msix(struct rte_intr_handle *intr_handle) {
286         int len, ret;
287         char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
288         struct vfio_irq_set *irq_set;
289         int *fd_ptr;
290
291         len = sizeof(irq_set_buf);
292
293         irq_set = (struct vfio_irq_set *) irq_set_buf;
294         irq_set->argsz = len;
295         if (!intr_handle->max_intr)
296                 intr_handle->max_intr = 1;
297         else if (intr_handle->max_intr > RTE_MAX_RXTX_INTR_VEC_ID)
298                 intr_handle->max_intr = RTE_MAX_RXTX_INTR_VEC_ID + 1;
299
300         irq_set->count = intr_handle->max_intr;
301         irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
302         irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
303         irq_set->start = 0;
304         fd_ptr = (int *) &irq_set->data;
305         /* INTR vector offset 0 reserve for non-efds mapping */
306         fd_ptr[RTE_INTR_VEC_ZERO_OFFSET] = intr_handle->fd;
307         memcpy(&fd_ptr[RTE_INTR_VEC_RXTX_OFFSET], intr_handle->efds,
308                 sizeof(*intr_handle->efds) * intr_handle->nb_efd);
309
310         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
311
312         if (ret) {
313                 RTE_LOG(ERR, EAL, "Error enabling MSI-X interrupts for fd %d\n",
314                                                 intr_handle->fd);
315                 return -1;
316         }
317
318         return 0;
319 }
320
321 /* disable MSI-X interrupts */
322 static int
323 vfio_disable_msix(struct rte_intr_handle *intr_handle) {
324         struct vfio_irq_set *irq_set;
325         char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
326         int len, ret;
327
328         len = sizeof(struct vfio_irq_set);
329
330         irq_set = (struct vfio_irq_set *) irq_set_buf;
331         irq_set->argsz = len;
332         irq_set->count = 0;
333         irq_set->flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER;
334         irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
335         irq_set->start = 0;
336
337         ret = ioctl(intr_handle->vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
338
339         if (ret)
340                 RTE_LOG(ERR, EAL,
341                         "Error disabling MSI-X interrupts for fd %d\n", intr_handle->fd);
342
343         return ret;
344 }
345 #endif
346
347 static int
348 uio_intx_intr_disable(struct rte_intr_handle *intr_handle)
349 {
350         unsigned char command_high;
351
352         /* use UIO config file descriptor for uio_pci_generic */
353         if (pread(intr_handle->uio_cfg_fd, &command_high, 1, 5) != 1) {
354                 RTE_LOG(ERR, EAL,
355                         "Error reading interrupts status for fd %d\n",
356                         intr_handle->uio_cfg_fd);
357                 return -1;
358         }
359         /* disable interrupts */
360         command_high |= 0x4;
361         if (pwrite(intr_handle->uio_cfg_fd, &command_high, 1, 5) != 1) {
362                 RTE_LOG(ERR, EAL,
363                         "Error disabling interrupts for fd %d\n",
364                         intr_handle->uio_cfg_fd);
365                 return -1;
366         }
367
368         return 0;
369 }
370
371 static int
372 uio_intx_intr_enable(struct rte_intr_handle *intr_handle)
373 {
374         unsigned char command_high;
375
376         /* use UIO config file descriptor for uio_pci_generic */
377         if (pread(intr_handle->uio_cfg_fd, &command_high, 1, 5) != 1) {
378                 RTE_LOG(ERR, EAL,
379                         "Error reading interrupts status for fd %d\n",
380                         intr_handle->uio_cfg_fd);
381                 return -1;
382         }
383         /* enable interrupts */
384         command_high &= ~0x4;
385         if (pwrite(intr_handle->uio_cfg_fd, &command_high, 1, 5) != 1) {
386                 RTE_LOG(ERR, EAL,
387                         "Error enabling interrupts for fd %d\n",
388                         intr_handle->uio_cfg_fd);
389                 return -1;
390         }
391
392         return 0;
393 }
394
395 static int
396 uio_intr_disable(struct rte_intr_handle *intr_handle)
397 {
398         const int value = 0;
399
400         if (write(intr_handle->fd, &value, sizeof(value)) < 0) {
401                 RTE_LOG(ERR, EAL,
402                         "Error disabling interrupts for fd %d (%s)\n",
403                         intr_handle->fd, strerror(errno));
404                 return -1;
405         }
406         return 0;
407 }
408
409 static int
410 uio_intr_enable(struct rte_intr_handle *intr_handle)
411 {
412         const int value = 1;
413
414         if (write(intr_handle->fd, &value, sizeof(value)) < 0) {
415                 RTE_LOG(ERR, EAL,
416                         "Error enabling interrupts for fd %d (%s)\n",
417                         intr_handle->fd, strerror(errno));
418                 return -1;
419         }
420         return 0;
421 }
422
423 int
424 rte_intr_callback_register(struct rte_intr_handle *intr_handle,
425                         rte_intr_callback_fn cb, void *cb_arg)
426 {
427         int ret, wake_thread;
428         struct rte_intr_source *src;
429         struct rte_intr_callback *callback;
430
431         wake_thread = 0;
432
433         /* first do parameter checking */
434         if (intr_handle == NULL || intr_handle->fd < 0 || cb == NULL) {
435                 RTE_LOG(ERR, EAL,
436                         "Registering with invalid input parameter\n");
437                 return -EINVAL;
438         }
439
440         /* allocate a new interrupt callback entity */
441         callback = rte_zmalloc("interrupt callback list",
442                                 sizeof(*callback), 0);
443         if (callback == NULL) {
444                 RTE_LOG(ERR, EAL, "Can not allocate memory\n");
445                 return -ENOMEM;
446         }
447         callback->cb_fn = cb;
448         callback->cb_arg = cb_arg;
449
450         rte_spinlock_lock(&intr_lock);
451
452         /* check if there is at least one callback registered for the fd */
453         TAILQ_FOREACH(src, &intr_sources, next) {
454                 if (src->intr_handle.fd == intr_handle->fd) {
455                         /* we had no interrupts for this */
456                         if TAILQ_EMPTY(&src->callbacks)
457                                 wake_thread = 1;
458
459                         TAILQ_INSERT_TAIL(&(src->callbacks), callback, next);
460                         ret = 0;
461                         break;
462                 }
463         }
464
465         /* no existing callbacks for this - add new source */
466         if (src == NULL) {
467                 if ((src = rte_zmalloc("interrupt source list",
468                                 sizeof(*src), 0)) == NULL) {
469                         RTE_LOG(ERR, EAL, "Can not allocate memory\n");
470                         rte_free(callback);
471                         ret = -ENOMEM;
472                 } else {
473                         src->intr_handle = *intr_handle;
474                         TAILQ_INIT(&src->callbacks);
475                         TAILQ_INSERT_TAIL(&(src->callbacks), callback, next);
476                         TAILQ_INSERT_TAIL(&intr_sources, src, next);
477                         wake_thread = 1;
478                         ret = 0;
479                 }
480         }
481
482         rte_spinlock_unlock(&intr_lock);
483
484         /**
485          * check if need to notify the pipe fd waited by epoll_wait to
486          * rebuild the wait list.
487          */
488         if (wake_thread)
489                 if (write(intr_pipe.writefd, "1", 1) < 0)
490                         return -EPIPE;
491
492         return ret;
493 }
494
495 int
496 rte_intr_callback_unregister(struct rte_intr_handle *intr_handle,
497                         rte_intr_callback_fn cb_fn, void *cb_arg)
498 {
499         int ret;
500         struct rte_intr_source *src;
501         struct rte_intr_callback *cb, *next;
502
503         /* do parameter checking first */
504         if (intr_handle == NULL || intr_handle->fd < 0) {
505                 RTE_LOG(ERR, EAL,
506                 "Unregistering with invalid input parameter\n");
507                 return -EINVAL;
508         }
509
510         rte_spinlock_lock(&intr_lock);
511
512         /* check if the insterrupt source for the fd is existent */
513         TAILQ_FOREACH(src, &intr_sources, next)
514                 if (src->intr_handle.fd == intr_handle->fd)
515                         break;
516
517         /* No interrupt source registered for the fd */
518         if (src == NULL) {
519                 ret = -ENOENT;
520
521         /* interrupt source has some active callbacks right now. */
522         } else if (src->active != 0) {
523                 ret = -EAGAIN;
524
525         /* ok to remove. */
526         } else {
527                 ret = 0;
528
529                 /*walk through the callbacks and remove all that match. */
530                 for (cb = TAILQ_FIRST(&src->callbacks); cb != NULL; cb = next) {
531
532                         next = TAILQ_NEXT(cb, next);
533
534                         if (cb->cb_fn == cb_fn && (cb_arg == (void *)-1 ||
535                                         cb->cb_arg == cb_arg)) {
536                                 TAILQ_REMOVE(&src->callbacks, cb, next);
537                                 rte_free(cb);
538                                 ret++;
539                         }
540                 }
541
542                 /* all callbacks for that source are removed. */
543                 if (TAILQ_EMPTY(&src->callbacks)) {
544                         TAILQ_REMOVE(&intr_sources, src, next);
545                         rte_free(src);
546                 }
547         }
548
549         rte_spinlock_unlock(&intr_lock);
550
551         /* notify the pipe fd waited by epoll_wait to rebuild the wait list */
552         if (ret >= 0 && write(intr_pipe.writefd, "1", 1) < 0) {
553                 ret = -EPIPE;
554         }
555
556         return ret;
557 }
558
559 int
560 rte_intr_enable(struct rte_intr_handle *intr_handle)
561 {
562         if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
563                 return -1;
564
565         switch (intr_handle->type){
566         /* write to the uio fd to enable the interrupt */
567         case RTE_INTR_HANDLE_UIO:
568                 if (uio_intr_enable(intr_handle))
569                         return -1;
570                 break;
571         case RTE_INTR_HANDLE_UIO_INTX:
572                 if (uio_intx_intr_enable(intr_handle))
573                         return -1;
574                 break;
575         /* not used at this moment */
576         case RTE_INTR_HANDLE_ALARM:
577                 return -1;
578 #ifdef VFIO_PRESENT
579         case RTE_INTR_HANDLE_VFIO_MSIX:
580                 if (vfio_enable_msix(intr_handle))
581                         return -1;
582                 break;
583         case RTE_INTR_HANDLE_VFIO_MSI:
584                 if (vfio_enable_msi(intr_handle))
585                         return -1;
586                 break;
587         case RTE_INTR_HANDLE_VFIO_LEGACY:
588                 if (vfio_enable_intx(intr_handle))
589                         return -1;
590                 break;
591 #endif
592         /* unknown handle type */
593         default:
594                 RTE_LOG(ERR, EAL,
595                         "Unknown handle type of fd %d\n",
596                                         intr_handle->fd);
597                 return -1;
598         }
599
600         return 0;
601 }
602
603 int
604 rte_intr_disable(struct rte_intr_handle *intr_handle)
605 {
606         if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
607                 return -1;
608
609         switch (intr_handle->type){
610         /* write to the uio fd to disable the interrupt */
611         case RTE_INTR_HANDLE_UIO:
612                 if (uio_intr_disable(intr_handle))
613                         return -1;
614                 break;
615         case RTE_INTR_HANDLE_UIO_INTX:
616                 if (uio_intx_intr_disable(intr_handle))
617                         return -1;
618                 break;
619         /* not used at this moment */
620         case RTE_INTR_HANDLE_ALARM:
621                 return -1;
622 #ifdef VFIO_PRESENT
623         case RTE_INTR_HANDLE_VFIO_MSIX:
624                 if (vfio_disable_msix(intr_handle))
625                         return -1;
626                 break;
627         case RTE_INTR_HANDLE_VFIO_MSI:
628                 if (vfio_disable_msi(intr_handle))
629                         return -1;
630                 break;
631         case RTE_INTR_HANDLE_VFIO_LEGACY:
632                 if (vfio_disable_intx(intr_handle))
633                         return -1;
634                 break;
635 #endif
636         /* unknown handle type */
637         default:
638                 RTE_LOG(ERR, EAL,
639                         "Unknown handle type of fd %d\n",
640                                         intr_handle->fd);
641                 return -1;
642         }
643
644         return 0;
645 }
646
647 static int
648 eal_intr_process_interrupts(struct epoll_event *events, int nfds)
649 {
650         int n, bytes_read;
651         struct rte_intr_source *src;
652         struct rte_intr_callback *cb;
653         union rte_intr_read_buffer buf;
654         struct rte_intr_callback active_cb;
655
656         for (n = 0; n < nfds; n++) {
657
658                 /**
659                  * if the pipe fd is ready to read, return out to
660                  * rebuild the wait list.
661                  */
662                 if (events[n].data.fd == intr_pipe.readfd){
663                         int r = read(intr_pipe.readfd, buf.charbuf,
664                                         sizeof(buf.charbuf));
665                         RTE_SET_USED(r);
666                         return -1;
667                 }
668                 rte_spinlock_lock(&intr_lock);
669                 TAILQ_FOREACH(src, &intr_sources, next)
670                         if (src->intr_handle.fd ==
671                                         events[n].data.fd)
672                                 break;
673                 if (src == NULL){
674                         rte_spinlock_unlock(&intr_lock);
675                         continue;
676                 }
677
678                 /* mark this interrupt source as active and release the lock. */
679                 src->active = 1;
680                 rte_spinlock_unlock(&intr_lock);
681
682                 /* set the length to be read dor different handle type */
683                 switch (src->intr_handle.type) {
684                 case RTE_INTR_HANDLE_UIO:
685                 case RTE_INTR_HANDLE_UIO_INTX:
686                         bytes_read = sizeof(buf.uio_intr_count);
687                         break;
688                 case RTE_INTR_HANDLE_ALARM:
689                         bytes_read = sizeof(buf.timerfd_num);
690                         break;
691 #ifdef VFIO_PRESENT
692                 case RTE_INTR_HANDLE_VFIO_MSIX:
693                 case RTE_INTR_HANDLE_VFIO_MSI:
694                 case RTE_INTR_HANDLE_VFIO_LEGACY:
695                         bytes_read = sizeof(buf.vfio_intr_count);
696                         break;
697 #endif
698                 case RTE_INTR_HANDLE_EXT:
699                 default:
700                         bytes_read = 1;
701                         break;
702                 }
703
704                 if (src->intr_handle.type != RTE_INTR_HANDLE_EXT) {
705                         /**
706                          * read out to clear the ready-to-be-read flag
707                          * for epoll_wait.
708                          */
709                         bytes_read = read(events[n].data.fd, &buf, bytes_read);
710                         if (bytes_read < 0) {
711                                 if (errno == EINTR || errno == EWOULDBLOCK)
712                                         continue;
713
714                                 RTE_LOG(ERR, EAL, "Error reading from file "
715                                         "descriptor %d: %s\n",
716                                         events[n].data.fd,
717                                         strerror(errno));
718                         } else if (bytes_read == 0)
719                                 RTE_LOG(ERR, EAL, "Read nothing from file "
720                                         "descriptor %d\n", events[n].data.fd);
721                 }
722
723                 /* grab a lock, again to call callbacks and update status. */
724                 rte_spinlock_lock(&intr_lock);
725
726                 if (bytes_read > 0) {
727
728                         /* Finally, call all callbacks. */
729                         TAILQ_FOREACH(cb, &src->callbacks, next) {
730
731                                 /* make a copy and unlock. */
732                                 active_cb = *cb;
733                                 rte_spinlock_unlock(&intr_lock);
734
735                                 /* call the actual callback */
736                                 active_cb.cb_fn(&src->intr_handle,
737                                         active_cb.cb_arg);
738
739                                 /*get the lock back. */
740                                 rte_spinlock_lock(&intr_lock);
741                         }
742                 }
743
744                 /* we done with that interrupt source, release it. */
745                 src->active = 0;
746                 rte_spinlock_unlock(&intr_lock);
747         }
748
749         return 0;
750 }
751
752 /**
753  * It handles all the interrupts.
754  *
755  * @param pfd
756  *  epoll file descriptor.
757  * @param totalfds
758  *  The number of file descriptors added in epoll.
759  *
760  * @return
761  *  void
762  */
763 static void
764 eal_intr_handle_interrupts(int pfd, unsigned totalfds)
765 {
766         struct epoll_event events[totalfds];
767         int nfds = 0;
768
769         for(;;) {
770                 nfds = epoll_wait(pfd, events, totalfds,
771                         EAL_INTR_EPOLL_WAIT_FOREVER);
772                 /* epoll_wait fail */
773                 if (nfds < 0) {
774                         if (errno == EINTR)
775                                 continue;
776                         RTE_LOG(ERR, EAL,
777                                 "epoll_wait returns with fail\n");
778                         return;
779                 }
780                 /* epoll_wait timeout, will never happens here */
781                 else if (nfds == 0)
782                         continue;
783                 /* epoll_wait has at least one fd ready to read */
784                 if (eal_intr_process_interrupts(events, nfds) < 0)
785                         return;
786         }
787 }
788
789 /**
790  * It builds/rebuilds up the epoll file descriptor with all the
791  * file descriptors being waited on. Then handles the interrupts.
792  *
793  * @param arg
794  *  pointer. (unused)
795  *
796  * @return
797  *  never return;
798  */
799 static __attribute__((noreturn)) void *
800 eal_intr_thread_main(__rte_unused void *arg)
801 {
802         struct epoll_event ev;
803
804         /* host thread, never break out */
805         for (;;) {
806                 /* build up the epoll fd with all descriptors we are to
807                  * wait on then pass it to the handle_interrupts function
808                  */
809                 static struct epoll_event pipe_event = {
810                         .events = EPOLLIN | EPOLLPRI,
811                 };
812                 struct rte_intr_source *src;
813                 unsigned numfds = 0;
814
815                 /* create epoll fd */
816                 int pfd = epoll_create(1);
817                 if (pfd < 0)
818                         rte_panic("Cannot create epoll instance\n");
819
820                 pipe_event.data.fd = intr_pipe.readfd;
821                 /**
822                  * add pipe fd into wait list, this pipe is used to
823                  * rebuild the wait list.
824                  */
825                 if (epoll_ctl(pfd, EPOLL_CTL_ADD, intr_pipe.readfd,
826                                                 &pipe_event) < 0) {
827                         rte_panic("Error adding fd to %d epoll_ctl, %s\n",
828                                         intr_pipe.readfd, strerror(errno));
829                 }
830                 numfds++;
831
832                 rte_spinlock_lock(&intr_lock);
833
834                 TAILQ_FOREACH(src, &intr_sources, next) {
835                         if (src->callbacks.tqh_first == NULL)
836                                 continue; /* skip those with no callbacks */
837                         ev.events = EPOLLIN | EPOLLPRI;
838                         ev.data.fd = src->intr_handle.fd;
839
840                         /**
841                          * add all the uio device file descriptor
842                          * into wait list.
843                          */
844                         if (epoll_ctl(pfd, EPOLL_CTL_ADD,
845                                         src->intr_handle.fd, &ev) < 0){
846                                 rte_panic("Error adding fd %d epoll_ctl, %s\n",
847                                         src->intr_handle.fd, strerror(errno));
848                         }
849                         else
850                                 numfds++;
851                 }
852                 rte_spinlock_unlock(&intr_lock);
853                 /* serve the interrupt */
854                 eal_intr_handle_interrupts(pfd, numfds);
855
856                 /**
857                  * when we return, we need to rebuild the
858                  * list of fds to monitor.
859                  */
860                 close(pfd);
861         }
862 }
863
864 int
865 rte_eal_intr_init(void)
866 {
867         int ret = 0, ret_1 = 0;
868         char thread_name[RTE_MAX_THREAD_NAME_LEN];
869
870         /* init the global interrupt source head */
871         TAILQ_INIT(&intr_sources);
872
873         /**
874          * create a pipe which will be waited by epoll and notified to
875          * rebuild the wait list of epoll.
876          */
877         if (pipe(intr_pipe.pipefd) < 0)
878                 return -1;
879
880         /* create the host thread to wait/handle the interrupt */
881         ret = pthread_create(&intr_thread, NULL,
882                         eal_intr_thread_main, NULL);
883         if (ret != 0) {
884                 RTE_LOG(ERR, EAL,
885                         "Failed to create thread for interrupt handling\n");
886         } else {
887                 /* Set thread_name for aid in debugging. */
888                 snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
889                         "eal-intr-thread");
890                 ret_1 = rte_thread_setname(intr_thread, thread_name);
891                 if (ret_1 != 0)
892                         RTE_LOG(ERR, EAL,
893                         "Failed to set thread name for interrupt handling\n");
894         }
895
896         return -ret;
897 }
898
899 static void
900 eal_intr_proc_rxtx_intr(int fd, const struct rte_intr_handle *intr_handle)
901 {
902         union rte_intr_read_buffer buf;
903         int bytes_read = 1;
904         int nbytes;
905
906         switch (intr_handle->type) {
907         case RTE_INTR_HANDLE_UIO:
908         case RTE_INTR_HANDLE_UIO_INTX:
909                 bytes_read = sizeof(buf.uio_intr_count);
910                 break;
911 #ifdef VFIO_PRESENT
912         case RTE_INTR_HANDLE_VFIO_MSIX:
913         case RTE_INTR_HANDLE_VFIO_MSI:
914         case RTE_INTR_HANDLE_VFIO_LEGACY:
915                 bytes_read = sizeof(buf.vfio_intr_count);
916                 break;
917 #endif
918         default:
919                 bytes_read = 1;
920                 RTE_LOG(INFO, EAL, "unexpected intr type\n");
921                 break;
922         }
923
924         /**
925          * read out to clear the ready-to-be-read flag
926          * for epoll_wait.
927          */
928         do {
929                 nbytes = read(fd, &buf, bytes_read);
930                 if (nbytes < 0) {
931                         if (errno == EINTR || errno == EWOULDBLOCK ||
932                             errno == EAGAIN)
933                                 continue;
934                         RTE_LOG(ERR, EAL,
935                                 "Error reading from fd %d: %s\n",
936                                 fd, strerror(errno));
937                 } else if (nbytes == 0)
938                         RTE_LOG(ERR, EAL, "Read nothing from fd %d\n", fd);
939                 return;
940         } while (1);
941 }
942
943 static int
944 eal_epoll_process_event(struct epoll_event *evs, unsigned int n,
945                         struct rte_epoll_event *events)
946 {
947         unsigned int i, count = 0;
948         struct rte_epoll_event *rev;
949
950         for (i = 0; i < n; i++) {
951                 rev = evs[i].data.ptr;
952                 if (!rev || !rte_atomic32_cmpset(&rev->status, RTE_EPOLL_VALID,
953                                                  RTE_EPOLL_EXEC))
954                         continue;
955
956                 events[count].status        = RTE_EPOLL_VALID;
957                 events[count].fd            = rev->fd;
958                 events[count].epfd          = rev->epfd;
959                 events[count].epdata.event  = rev->epdata.event;
960                 events[count].epdata.data   = rev->epdata.data;
961                 if (rev->epdata.cb_fun)
962                         rev->epdata.cb_fun(rev->fd,
963                                            rev->epdata.cb_arg);
964
965                 rte_compiler_barrier();
966                 rev->status = RTE_EPOLL_VALID;
967                 count++;
968         }
969         return count;
970 }
971
972 static inline int
973 eal_init_tls_epfd(void)
974 {
975         int pfd = epoll_create(255);
976
977         if (pfd < 0) {
978                 RTE_LOG(ERR, EAL,
979                         "Cannot create epoll instance\n");
980                 return -1;
981         }
982         return pfd;
983 }
984
985 int
986 rte_intr_tls_epfd(void)
987 {
988         if (RTE_PER_LCORE(_epfd) == -1)
989                 RTE_PER_LCORE(_epfd) = eal_init_tls_epfd();
990
991         return RTE_PER_LCORE(_epfd);
992 }
993
994 int
995 rte_epoll_wait(int epfd, struct rte_epoll_event *events,
996                int maxevents, int timeout)
997 {
998         struct epoll_event evs[maxevents];
999         int rc;
1000
1001         if (!events) {
1002                 RTE_LOG(ERR, EAL, "rte_epoll_event can't be NULL\n");
1003                 return -1;
1004         }
1005
1006         /* using per thread epoll fd */
1007         if (epfd == RTE_EPOLL_PER_THREAD)
1008                 epfd = rte_intr_tls_epfd();
1009
1010         while (1) {
1011                 rc = epoll_wait(epfd, evs, maxevents, timeout);
1012                 if (likely(rc > 0)) {
1013                         /* epoll_wait has at least one fd ready to read */
1014                         rc = eal_epoll_process_event(evs, rc, events);
1015                         break;
1016                 } else if (rc < 0) {
1017                         if (errno == EINTR)
1018                                 continue;
1019                         /* epoll_wait fail */
1020                         RTE_LOG(ERR, EAL, "epoll_wait returns with fail %s\n",
1021                                 strerror(errno));
1022                         rc = -1;
1023                         break;
1024                 } else {
1025                         /* rc == 0, epoll_wait timed out */
1026                         break;
1027                 }
1028         }
1029
1030         return rc;
1031 }
1032
1033 static inline void
1034 eal_epoll_data_safe_free(struct rte_epoll_event *ev)
1035 {
1036         while (!rte_atomic32_cmpset(&ev->status, RTE_EPOLL_VALID,
1037                                     RTE_EPOLL_INVALID))
1038                 while (ev->status != RTE_EPOLL_VALID)
1039                         rte_pause();
1040         memset(&ev->epdata, 0, sizeof(ev->epdata));
1041         ev->fd = -1;
1042         ev->epfd = -1;
1043 }
1044
1045 int
1046 rte_epoll_ctl(int epfd, int op, int fd,
1047               struct rte_epoll_event *event)
1048 {
1049         struct epoll_event ev;
1050
1051         if (!event) {
1052                 RTE_LOG(ERR, EAL, "rte_epoll_event can't be NULL\n");
1053                 return -1;
1054         }
1055
1056         /* using per thread epoll fd */
1057         if (epfd == RTE_EPOLL_PER_THREAD)
1058                 epfd = rte_intr_tls_epfd();
1059
1060         if (op == EPOLL_CTL_ADD) {
1061                 event->status = RTE_EPOLL_VALID;
1062                 event->fd = fd;  /* ignore fd in event */
1063                 event->epfd = epfd;
1064                 ev.data.ptr = (void *)event;
1065         }
1066
1067         ev.events = event->epdata.event;
1068         if (epoll_ctl(epfd, op, fd, &ev) < 0) {
1069                 RTE_LOG(ERR, EAL, "Error op %d fd %d epoll_ctl, %s\n",
1070                         op, fd, strerror(errno));
1071                 if (op == EPOLL_CTL_ADD)
1072                         /* rollback status when CTL_ADD fail */
1073                         event->status = RTE_EPOLL_INVALID;
1074                 return -1;
1075         }
1076
1077         if (op == EPOLL_CTL_DEL && event->status != RTE_EPOLL_INVALID)
1078                 eal_epoll_data_safe_free(event);
1079
1080         return 0;
1081 }
1082
1083 int
1084 rte_intr_rx_ctl(struct rte_intr_handle *intr_handle, int epfd,
1085                 int op, unsigned int vec, void *data)
1086 {
1087         struct rte_epoll_event *rev;
1088         struct rte_epoll_data *epdata;
1089         int epfd_op;
1090         unsigned int efd_idx;
1091         int rc = 0;
1092
1093         efd_idx = (vec >= RTE_INTR_VEC_RXTX_OFFSET) ?
1094                 (vec - RTE_INTR_VEC_RXTX_OFFSET) : vec;
1095
1096         if (!intr_handle || intr_handle->nb_efd == 0 ||
1097             efd_idx >= intr_handle->nb_efd) {
1098                 RTE_LOG(ERR, EAL, "Wrong intr vector number.\n");
1099                 return -EPERM;
1100         }
1101
1102         switch (op) {
1103         case RTE_INTR_EVENT_ADD:
1104                 epfd_op = EPOLL_CTL_ADD;
1105                 rev = &intr_handle->elist[efd_idx];
1106                 if (rev->status != RTE_EPOLL_INVALID) {
1107                         RTE_LOG(INFO, EAL, "Event already been added.\n");
1108                         return -EEXIST;
1109                 }
1110
1111                 /* attach to intr vector fd */
1112                 epdata = &rev->epdata;
1113                 epdata->event  = EPOLLIN | EPOLLPRI | EPOLLET;
1114                 epdata->data   = data;
1115                 epdata->cb_fun = (rte_intr_event_cb_t)eal_intr_proc_rxtx_intr;
1116                 epdata->cb_arg = (void *)intr_handle;
1117                 rc = rte_epoll_ctl(epfd, epfd_op,
1118                                    intr_handle->efds[efd_idx], rev);
1119                 if (!rc)
1120                         RTE_LOG(DEBUG, EAL,
1121                                 "efd %d associated with vec %d added on epfd %d"
1122                                 "\n", rev->fd, vec, epfd);
1123                 else
1124                         rc = -EPERM;
1125                 break;
1126         case RTE_INTR_EVENT_DEL:
1127                 epfd_op = EPOLL_CTL_DEL;
1128                 rev = &intr_handle->elist[efd_idx];
1129                 if (rev->status == RTE_EPOLL_INVALID) {
1130                         RTE_LOG(INFO, EAL, "Event does not exist.\n");
1131                         return -EPERM;
1132                 }
1133
1134                 rc = rte_epoll_ctl(rev->epfd, epfd_op, rev->fd, rev);
1135                 if (rc)
1136                         rc = -EPERM;
1137                 break;
1138         default:
1139                 RTE_LOG(ERR, EAL, "event op type mismatch\n");
1140                 rc = -EPERM;
1141         }
1142
1143         return rc;
1144 }
1145
1146 int
1147 rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
1148 {
1149         uint32_t i;
1150         int fd;
1151         uint32_t n = RTE_MIN(nb_efd, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
1152
1153         assert(nb_efd != 0);
1154
1155         if (intr_handle->type == RTE_INTR_HANDLE_VFIO_MSIX) {
1156                 for (i = 0; i < n; i++) {
1157                         fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
1158                         if (fd < 0) {
1159                                 RTE_LOG(ERR, EAL,
1160                                         "can't setup eventfd, error %i (%s)\n",
1161                                         errno, strerror(errno));
1162                                 return -1;
1163                         }
1164                         intr_handle->efds[i] = fd;
1165                 }
1166                 intr_handle->nb_efd   = n;
1167                 intr_handle->max_intr = NB_OTHER_INTR + n;
1168         } else {
1169                 intr_handle->efds[0]  = intr_handle->fd;
1170                 intr_handle->nb_efd   = RTE_MIN(nb_efd, 1U);
1171                 intr_handle->max_intr = NB_OTHER_INTR;
1172         }
1173
1174         return 0;
1175 }
1176
1177 void
1178 rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
1179 {
1180         uint32_t i;
1181         struct rte_epoll_event *rev;
1182
1183         for (i = 0; i < intr_handle->nb_efd; i++) {
1184                 rev = &intr_handle->elist[i];
1185                 if (rev->status == RTE_EPOLL_INVALID)
1186                         continue;
1187                 if (rte_epoll_ctl(rev->epfd, EPOLL_CTL_DEL, rev->fd, rev)) {
1188                         /* force free if the entry valid */
1189                         eal_epoll_data_safe_free(rev);
1190                         rev->status = RTE_EPOLL_INVALID;
1191                 }
1192         }
1193
1194         if (intr_handle->max_intr > intr_handle->nb_efd) {
1195                 for (i = 0; i < intr_handle->nb_efd; i++)
1196                         close(intr_handle->efds[i]);
1197         }
1198         intr_handle->nb_efd = 0;
1199         intr_handle->max_intr = 0;
1200 }
1201
1202 int
1203 rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
1204 {
1205         return !(!intr_handle->nb_efd);
1206 }
1207
1208 int
1209 rte_intr_allow_others(struct rte_intr_handle *intr_handle)
1210 {
1211         if (!rte_intr_dp_is_en(intr_handle))
1212                 return 1;
1213         else
1214                 return !!(intr_handle->max_intr - intr_handle->nb_efd);
1215 }
1216
1217 int
1218 rte_intr_cap_multiple(struct rte_intr_handle *intr_handle)
1219 {
1220         if (intr_handle->type == RTE_INTR_HANDLE_VFIO_MSIX)
1221                 return 1;
1222
1223         return 0;
1224 }