net/mlx4: use a single interrupt handle

The reason one interrupt handle is currently used for RMV/LSC events and
another one for Rx traffic is because these come from distinct file
descriptors.

This can be simplified however as Rx interrupt file descriptors are stored
elsewhere and are registered separately.

Modifying the interrupt handle type to RTE_INTR_HANDLE_UNKNOWN has never
been necessary as disabling interrupts is actually done by unregistering
the associated callback (RMV/LSC) or emptying the EFD array (Rx). Instead,
make clear that the base handle file descriptor is invalid by setting it to
-1 when disabled.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
This commit is contained in:
Adrien Mazarguil 2017-09-01 10:06:50 +02:00 committed by Ferruh Yigit
parent 76df01ff62
commit 63c2f23c85
2 changed files with 21 additions and 14 deletions

View File

@ -2817,8 +2817,7 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
ERROR("rte_intr_callback_unregister failed with %d %s",
ret, strerror(rte_errno));
}
priv->intr_handle.fd = 0;
priv->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
priv->intr_handle.fd = -1;
return ret;
}
@ -2859,7 +2858,6 @@ priv_dev_interrupt_handler_install(struct priv *priv,
return -rte_errno;
} else {
priv->intr_handle.fd = priv->ctx->async_fd;
priv->intr_handle.type = RTE_INTR_HANDLE_EXT;
rc = rte_intr_callback_register(&priv->intr_handle,
mlx4_dev_interrupt_handler,
dev);
@ -2867,6 +2865,7 @@ priv_dev_interrupt_handler_install(struct priv *priv,
rte_errno = -rc;
ERROR("rte_intr_callback_register failed "
" (rte_errno: %s)", strerror(rte_errno));
priv->intr_handle.fd = -1;
return -rte_errno;
}
}
@ -2997,7 +2996,7 @@ priv_rx_intr_vec_enable(struct priv *priv)
unsigned int rxqs_n = priv->rxqs_n;
unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
unsigned int count = 0;
struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
struct rte_intr_handle *intr_handle = &priv->intr_handle;
if (!priv->dev->data->dev_conf.intr_conf.rxq)
return 0;
@ -3009,7 +3008,6 @@ priv_rx_intr_vec_enable(struct priv *priv)
" Rx interrupts will not be supported");
return -rte_errno;
}
intr_handle->type = RTE_INTR_HANDLE_EXT;
for (i = 0; i != n; ++i) {
struct rxq *rxq = (*priv->rxqs)[i];
int fd;
@ -3062,7 +3060,7 @@ priv_rx_intr_vec_enable(struct priv *priv)
static void
priv_rx_intr_vec_disable(struct priv *priv)
{
struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
struct rte_intr_handle *intr_handle = &priv->intr_handle;
rte_intr_free_epoll_fd(intr_handle);
free(intr_handle->intr_vec);
@ -3429,14 +3427,24 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
eth_dev->device = &pci_dev->device;
rte_eth_copy_pci_info(eth_dev, pci_dev);
eth_dev->device->driver = &mlx4_driver.driver;
/* Initialize local interrupt handle for current port. */
priv->intr_handle = (struct rte_intr_handle){
.fd = -1,
.type = RTE_INTR_HANDLE_EXT,
};
/*
* Copy and override interrupt handle to prevent it from
* being shared between all ethdev instances of a given PCI
* device. This is required to properly handle Rx interrupts
* on all ports.
* Override ethdev interrupt handle pointer with private
* handle instead of that of the parent PCI device used by
* default. This prevents it from being shared between all
* ports of the same PCI device since each of them is
* associated its own Verbs context.
*
* Rx interrupts in particular require this as the PMD has
* no control over the registration of queue interrupts
* besides setting up eth_dev->intr_handle, the rest is
* handled by rte_intr_rx_ctl().
*/
priv->intr_handle_dev = *eth_dev->intr_handle;
eth_dev->intr_handle = &priv->intr_handle_dev;
eth_dev->intr_handle = &priv->intr_handle;
priv->dev = eth_dev;
eth_dev->dev_ops = &mlx4_dev_ops;
eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;

View File

@ -169,8 +169,7 @@ struct priv {
unsigned int txqs_n; /* TX queues array size. */
struct rxq *(*rxqs)[]; /* RX queues. */
struct txq *(*txqs)[]; /* TX queues. */
struct rte_intr_handle intr_handle_dev; /* Device interrupt handler. */
struct rte_intr_handle intr_handle; /* Interrupt handler. */
struct rte_intr_handle intr_handle; /* Port interrupt handle. */
struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
LIST_HEAD(mlx4_flows, rte_flow) flows;
struct rte_intr_conf intr_conf; /* Active interrupt configuration. */