From a6e8b01c3c26a87c4bbe7f9687f780642bc9ecc9 Mon Sep 17 00:00:00 2001 From: Adrien Mazarguil Date: Fri, 1 Sep 2017 10:06:54 +0200 Subject: [PATCH] net/mlx4: compact interrupt functions Link status (LSC) and removal (RMV) interrupts share a common handler and are toggled simultaneously from common install/uninstall functions. Four additional wrapper functions (two for each interrupt type) are currently necessary because the PMD maintains an internal configuration state for interrupts (priv->intr_conf). This complexity can be avoided entirely since the PMD does not disable interrupts configuration parameters in case of error anymore. With this commit, only two functions are necessary to toggle interrupts (including Rx) during start/stop cycles. Signed-off-by: Adrien Mazarguil --- drivers/net/mlx4/mlx4.c | 199 +++++++++------------------------------- drivers/net/mlx4/mlx4.h | 1 - 2 files changed, 41 insertions(+), 159 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index 0fcd4f0d98..a997a63073 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -1977,9 +1977,8 @@ mlx4_rx_queue_release(void *dpdk_rxq) rte_free(rxq); } -static int priv_interrupt_handler_install(struct priv *priv); -static int priv_removal_interrupt_handler_install(struct priv *priv); -static int priv_link_interrupt_handler_install(struct priv *priv); +static int priv_intr_uninstall(struct priv *priv); +static int priv_intr_install(struct priv *priv); /** * DPDK callback to start the device. @@ -2005,24 +2004,12 @@ mlx4_dev_start(struct rte_eth_dev *dev) ret = priv_mac_addr_add(priv); if (ret) goto err; - ret = priv_link_interrupt_handler_install(priv); + ret = priv_intr_install(priv); if (ret) { - ERROR("%p: LSC handler install failed", + ERROR("%p: interrupt handler installation failed", (void *)dev); goto err; } - ret = priv_removal_interrupt_handler_install(priv); - if (ret) { - ERROR("%p: RMV handler install failed", - (void *)dev); - goto err; - } - ret = priv_rx_intr_vec_enable(priv); - if (ret) { - ERROR("%p: Rx interrupt vector creation failed", - (void *)dev); - goto err; - } ret = mlx4_priv_flow_start(priv); if (ret) { ERROR("%p: flow start failed: %s", @@ -2055,6 +2042,7 @@ mlx4_dev_stop(struct rte_eth_dev *dev) DEBUG("%p: detaching flows from all RX queues", (void *)dev); priv->started = 0; mlx4_priv_flow_stop(priv); + priv_intr_uninstall(priv); priv_mac_addr_del(priv); } @@ -2108,10 +2096,6 @@ removed_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) return 0; } -static int priv_interrupt_handler_uninstall(struct priv *priv); -static int priv_removal_interrupt_handler_uninstall(struct priv *priv); -static int priv_link_interrupt_handler_uninstall(struct priv *priv); - /** * DPDK callback to close the device. * @@ -2174,9 +2158,7 @@ mlx4_dev_close(struct rte_eth_dev *dev) claim_zero(ibv_close_device(priv->ctx)); } else assert(priv->ctx == NULL); - priv_removal_interrupt_handler_uninstall(priv); - priv_link_interrupt_handler_uninstall(priv); - priv_rx_intr_vec_disable(priv); + priv_intr_uninstall(priv); memset(priv, 0, sizeof(*priv)); } @@ -2682,6 +2664,8 @@ priv_collect_interrupt_events(struct priv *priv, uint32_t *events) struct ibv_async_event event; int port_change = 0; struct rte_eth_link *link = &priv->dev->data->dev_link; + const struct rte_intr_conf *const intr_conf = + &priv->dev->data->dev_conf.intr_conf; int ret = 0; *events = 0; @@ -2691,11 +2675,11 @@ priv_collect_interrupt_events(struct priv *priv, uint32_t *events) break; if ((event.event_type == IBV_EVENT_PORT_ACTIVE || event.event_type == IBV_EVENT_PORT_ERR) && - (priv->intr_conf.lsc == 1)) { + intr_conf->lsc) { port_change = 1; ret++; } else if (event.event_type == IBV_EVENT_DEVICE_FATAL && - priv->intr_conf.rmv == 1) { + intr_conf->rmv) { *events |= (1 << RTE_ETH_EVENT_INTR_RMV); ret++; } else @@ -2784,24 +2768,22 @@ mlx4_interrupt_handler(struct priv *priv) * 0 on success, negative errno value otherwise and rte_errno is set. */ static int -priv_interrupt_handler_uninstall(struct priv *priv) +priv_intr_uninstall(struct priv *priv) { - int ret; + int err = rte_errno; /* Make sure rte_errno remains unchanged. */ - if (priv->intr_conf.lsc || - priv->intr_conf.rmv) - return 0; - ret = rte_intr_callback_unregister(&priv->intr_handle, - (void (*)(void *)) - mlx4_interrupt_handler, - priv); - if (ret < 0) { - rte_errno = ret; - ERROR("rte_intr_callback_unregister failed with %d %s", - ret, strerror(rte_errno)); + if (priv->intr_handle.fd != -1) { + rte_intr_callback_unregister(&priv->intr_handle, + (void (*)(void *)) + mlx4_interrupt_handler, + priv); + priv->intr_handle.fd = -1; } - priv->intr_handle.fd = -1; - return ret; + rte_eal_alarm_cancel((void (*)(void *))mlx4_link_status_alarm, priv); + priv->intr_alarm = 0; + priv_rx_intr_vec_disable(priv); + rte_errno = err; + return 0; } /** @@ -2814,127 +2796,30 @@ priv_interrupt_handler_uninstall(struct priv *priv) * 0 on success, negative errno value otherwise and rte_errno is set. */ static int -priv_interrupt_handler_install(struct priv *priv) +priv_intr_install(struct priv *priv) { + const struct rte_intr_conf *const intr_conf = + &priv->dev->data->dev_conf.intr_conf; int rc; - /* - * Check whether the interrupt handler has already been installed - * for either type of interrupt. - */ - if (priv->intr_conf.lsc && - priv->intr_conf.rmv && - priv->intr_handle.fd) - return 0; - priv->intr_handle.fd = priv->ctx->async_fd; - rc = rte_intr_callback_register(&priv->intr_handle, - (void (*)(void *)) - mlx4_interrupt_handler, - priv); - if (!rc) - return 0; - rte_errno = -rc; - ERROR("rte_intr_callback_register failed (rte_errno: %s)", - strerror(rte_errno)); - priv->intr_handle.fd = -1; - return -rte_errno; -} - -/** - * Uninstall interrupt handler. - * - * @param priv - * Pointer to private structure. - * - * @return - * 0 on success, negative errno value otherwise and rte_errno is set. - */ -static int -priv_removal_interrupt_handler_uninstall(struct priv *priv) -{ - if (priv->dev->data->dev_conf.intr_conf.rmv) { - priv->intr_conf.rmv = 0; - return priv_interrupt_handler_uninstall(priv); - } - return 0; -} - -/** - * Uninstall interrupt handler. - * - * @param priv - * Pointer to private structure. - * - * @return - * 0 on success, negative errno value otherwise and rte_errno is set. - */ -static int -priv_link_interrupt_handler_uninstall(struct priv *priv) -{ - int ret = 0; - - if (priv->dev->data->dev_conf.intr_conf.lsc) { - priv->intr_conf.lsc = 0; - ret = priv_interrupt_handler_uninstall(priv); - if (ret) - return ret; - } - if (priv->intr_alarm) - if (rte_eal_alarm_cancel((void (*)(void *)) - mlx4_link_status_alarm, - priv)) { - ERROR("rte_eal_alarm_cancel failed " - " (rte_errno: %s)", strerror(rte_errno)); - return -rte_errno; + priv_intr_uninstall(priv); + if (intr_conf->rxq && priv_rx_intr_vec_enable(priv) < 0) + goto error; + if (intr_conf->lsc | intr_conf->rmv) { + priv->intr_handle.fd = priv->ctx->async_fd; + rc = rte_intr_callback_register(&priv->intr_handle, + (void (*)(void *)) + mlx4_interrupt_handler, + priv); + if (rc < 0) { + rte_errno = -rc; + goto error; } - priv->intr_alarm = 0; - return 0; -} - -/** - * Install link interrupt handler. - * - * @param priv - * Pointer to private structure. - * - * @return - * 0 on success, negative errno value otherwise and rte_errno is set. - */ -static int -priv_link_interrupt_handler_install(struct priv *priv) -{ - int ret; - - if (priv->dev->data->dev_conf.intr_conf.lsc) { - ret = priv_interrupt_handler_install(priv); - if (ret) - return ret; - priv->intr_conf.lsc = 1; - } - return 0; -} - -/** - * Install removal interrupt handler. - * - * @param priv - * Pointer to private structure. - * - * @return - * 0 on success, negative errno value otherwise and rte_errno is set. - */ -static int -priv_removal_interrupt_handler_install(struct priv *priv) -{ - int ret; - - if (priv->dev->data->dev_conf.intr_conf.rmv) { - ret = priv_interrupt_handler_install(priv); - if (ret) - return ret; - priv->intr_conf.rmv = 1; } return 0; +error: + priv_intr_uninstall(priv); + return -rte_errno; } /** @@ -2955,8 +2840,6 @@ priv_rx_intr_vec_enable(struct priv *priv) unsigned int count = 0; struct rte_intr_handle *intr_handle = &priv->intr_handle; - if (!priv->dev->data->dev_conf.intr_conf.rxq) - return 0; priv_rx_intr_vec_disable(priv); intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n])); if (intr_handle->intr_vec == NULL) { diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index b61f5f2d56..a35a94e04b 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -176,7 +176,6 @@ struct priv { 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. */ }; #endif /* RTE_PMD_MLX4_H_ */ -- 2.20.1