A new interrupt type, RTE_INTR_HANDLE_VDEV, is added to support lsc and rxq
interrupt for vdev.
For lsc interrupt, except from original EPOLLIN events, we also listen for
socket peer closed connection event (EPOLLRDHUP and EPOLLHUP).
For rxq interrupt, add a precondition to avoid invoking any vfio and uio
code.
For intr_handle initialization, let each vdev driver to do that.
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
#include <sys/ioctl.h>
#include <sys/eventfd.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <sys/eventfd.h>
#include <assert.h>
#include <rte_common.h>
#include <rte_interrupts.h>
#include <rte_common.h>
#include <rte_interrupts.h>
int
rte_intr_enable(const struct rte_intr_handle *intr_handle)
{
int
rte_intr_enable(const struct rte_intr_handle *intr_handle)
{
+ if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV)
+ return 0;
+
if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
return -1;
if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
return -1;
int
rte_intr_disable(const struct rte_intr_handle *intr_handle)
{
int
rte_intr_disable(const struct rte_intr_handle *intr_handle)
{
+ if (intr_handle && intr_handle->type == RTE_INTR_HANDLE_VDEV)
+ return 0;
+
if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
return -1;
if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
return -1;
static int
eal_intr_process_interrupts(struct epoll_event *events, int nfds)
{
static int
eal_intr_process_interrupts(struct epoll_event *events, int nfds)
{
int n, bytes_read;
struct rte_intr_source *src;
struct rte_intr_callback *cb;
int n, bytes_read;
struct rte_intr_source *src;
struct rte_intr_callback *cb;
bytes_read = sizeof(buf.vfio_intr_count);
break;
#endif
bytes_read = sizeof(buf.vfio_intr_count);
break;
#endif
+ case RTE_INTR_HANDLE_VDEV:
case RTE_INTR_HANDLE_EXT:
case RTE_INTR_HANDLE_EXT:
+ bytes_read = 0;
+ call = true;
+ break;
+
default:
bytes_read = 1;
break;
}
default:
bytes_read = 1;
break;
}
- if (src->intr_handle.type != RTE_INTR_HANDLE_EXT) {
/**
* read out to clear the ready-to-be-read flag
* for epoll_wait.
/**
* read out to clear the ready-to-be-read flag
* for epoll_wait.
} else if (bytes_read == 0)
RTE_LOG(ERR, EAL, "Read nothing from file "
"descriptor %d\n", events[n].data.fd);
} else if (bytes_read == 0)
RTE_LOG(ERR, EAL, "Read nothing from file "
"descriptor %d\n", events[n].data.fd);
}
/* grab a lock, again to call callbacks and update status. */
rte_spinlock_lock(&intr_lock);
}
/* grab a lock, again to call callbacks and update status. */
rte_spinlock_lock(&intr_lock);
/* Finally, call all callbacks. */
TAILQ_FOREACH(cb, &src->callbacks, next) {
/* Finally, call all callbacks. */
TAILQ_FOREACH(cb, &src->callbacks, next) {
TAILQ_FOREACH(src, &intr_sources, next) {
if (src->callbacks.tqh_first == NULL)
continue; /* skip those with no callbacks */
TAILQ_FOREACH(src, &intr_sources, next) {
if (src->callbacks.tqh_first == NULL)
continue; /* skip those with no callbacks */
- ev.events = EPOLLIN | EPOLLPRI;
+ ev.events = EPOLLIN | EPOLLPRI | EPOLLRDHUP | EPOLLHUP;
ev.data.fd = src->intr_handle.fd;
/**
ev.data.fd = src->intr_handle.fd;
/**
bytes_read = sizeof(buf.vfio_intr_count);
break;
#endif
bytes_read = sizeof(buf.vfio_intr_count);
break;
#endif
+ case RTE_INTR_HANDLE_VDEV:
+ /* for vdev, fd points to:
+ * a. eventfd which does not need to read out;
+ * b. datapath fd which needs PMD to read out.
+ */
+ return;
case RTE_INTR_HANDLE_EXT:
return;
default:
case RTE_INTR_HANDLE_EXT:
return;
default:
}
intr_handle->nb_efd = n;
intr_handle->max_intr = NB_OTHER_INTR + n;
}
intr_handle->nb_efd = n;
intr_handle->max_intr = NB_OTHER_INTR + n;
+ } else if (intr_handle->type == RTE_INTR_HANDLE_VDEV) {
+ /* do nothing, and let vdev driver to initialize this struct */
} else {
intr_handle->efds[0] = intr_handle->fd;
intr_handle->nb_efd = RTE_MIN(nb_efd, 1U);
} else {
intr_handle->efds[0] = intr_handle->fd;
intr_handle->nb_efd = RTE_MIN(nb_efd, 1U);
if (intr_handle->type == RTE_INTR_HANDLE_VFIO_MSIX)
return 1;
if (intr_handle->type == RTE_INTR_HANDLE_VFIO_MSIX)
return 1;
+ if (intr_handle->type == RTE_INTR_HANDLE_VDEV)
+ return 1;
+
RTE_INTR_HANDLE_VFIO_LEGACY, /**< vfio device handle (legacy) */
RTE_INTR_HANDLE_VFIO_MSI, /**< vfio device handle (MSI) */
RTE_INTR_HANDLE_VFIO_MSIX, /**< vfio device handle (MSIX) */
RTE_INTR_HANDLE_VFIO_LEGACY, /**< vfio device handle (legacy) */
RTE_INTR_HANDLE_VFIO_MSI, /**< vfio device handle (MSI) */
RTE_INTR_HANDLE_VFIO_MSIX, /**< vfio device handle (MSIX) */
- RTE_INTR_HANDLE_ALARM, /**< alarm handle */
- RTE_INTR_HANDLE_EXT, /**< external handler */
+ RTE_INTR_HANDLE_ALARM, /**< alarm handle */
+ RTE_INTR_HANDLE_EXT, /**< external handler */
+ RTE_INTR_HANDLE_VDEV, /**< virtual device */