From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 40/51] net/mlx4: separate interrupt handling
Date: Fri, 1 Sep 2017 10:06:55 +0200 [thread overview]
Message-ID: <334d02cb454d6e15eda65f6b2be7a075bdf34cde.1504252977.git.adrien.mazarguil@6wind.com> (raw)
In-Reply-To: <cover.1504252977.git.adrien.mazarguil@6wind.com>
Private functions are now prefixed with "mlx4_" to prevent them from
conflicting with their mlx5 PMD counterparts at link time.
No impact on functionality.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
drivers/net/mlx4/Makefile | 1 +
drivers/net/mlx4/mlx4.c | 340 +---------------------------------
drivers/net/mlx4/mlx4.h | 11 ++
drivers/net/mlx4/mlx4_intr.c | 376 ++++++++++++++++++++++++++++++++++++++
4 files changed, 392 insertions(+), 336 deletions(-)
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index 8a03154..f6e3001 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -37,6 +37,7 @@ LIB = librte_pmd_mlx4.a
# Sources.
SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_utils.c
# Basic CFLAGS.
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index a997a63..667ba2b 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -58,7 +58,6 @@
#include <rte_mempool.h>
#include <rte_prefetch.h>
#include <rte_malloc.h>
-#include <rte_alarm.h>
#include <rte_memory.h>
#include <rte_flow.h>
#include <rte_kvargs.h>
@@ -88,18 +87,6 @@ const char *pmd_mlx4_init_params[] = {
NULL,
};
-static int
-mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx);
-
-static int
-mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx);
-
-static int
-priv_rx_intr_vec_enable(struct priv *priv);
-
-static void
-priv_rx_intr_vec_disable(struct priv *priv);
-
/* Allocate a buffer on the stack and fill it with a printf format string. */
#define MKSTR(name, ...) \
char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \
@@ -1977,9 +1964,6 @@ mlx4_rx_queue_release(void *dpdk_rxq)
rte_free(rxq);
}
-static int priv_intr_uninstall(struct priv *priv);
-static int priv_intr_install(struct priv *priv);
-
/**
* DPDK callback to start the device.
*
@@ -2004,7 +1988,7 @@ mlx4_dev_start(struct rte_eth_dev *dev)
ret = priv_mac_addr_add(priv);
if (ret)
goto err;
- ret = priv_intr_install(priv);
+ ret = mlx4_intr_install(priv);
if (ret) {
ERROR("%p: interrupt handler installation failed",
(void *)dev);
@@ -2042,7 +2026,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);
+ mlx4_intr_uninstall(priv);
priv_mac_addr_del(priv);
}
@@ -2158,7 +2142,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)
claim_zero(ibv_close_device(priv->ctx));
} else
assert(priv->ctx == NULL);
- priv_intr_uninstall(priv);
+ mlx4_intr_uninstall(priv);
memset(priv, 0, sizeof(*priv));
}
@@ -2370,7 +2354,7 @@ mlx4_stats_reset(struct rte_eth_dev *dev)
* @return
* 0 on success, negative errno value otherwise and rte_errno is set.
*/
-static int
+int
mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
{
const struct priv *priv = dev->data->dev_private;
@@ -2645,322 +2629,6 @@ priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
return 0;
}
-static void mlx4_link_status_alarm(struct priv *priv);
-
-/**
- * Collect interrupt events.
- *
- * @param priv
- * Pointer to private structure.
- * @param events
- * Pointer to event flags holder.
- *
- * @return
- * Number of events.
- */
-static int
-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;
- /* Read all message and acknowledge them. */
- for (;;) {
- if (ibv_get_async_event(priv->ctx, &event))
- break;
- if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
- event.event_type == IBV_EVENT_PORT_ERR) &&
- intr_conf->lsc) {
- port_change = 1;
- ret++;
- } else if (event.event_type == IBV_EVENT_DEVICE_FATAL &&
- intr_conf->rmv) {
- *events |= (1 << RTE_ETH_EVENT_INTR_RMV);
- ret++;
- } else
- DEBUG("event type %d on port %d not handled",
- event.event_type, event.element.port_num);
- ibv_ack_async_event(&event);
- }
- if (!port_change)
- return ret;
- mlx4_link_update(priv->dev, 0);
- if (((link->link_speed == 0) && link->link_status) ||
- ((link->link_speed != 0) && !link->link_status)) {
- if (!priv->intr_alarm) {
- /* Inconsistent status, check again later. */
- priv->intr_alarm = 1;
- rte_eal_alarm_set(MLX4_INTR_ALARM_TIMEOUT,
- (void (*)(void *))
- mlx4_link_status_alarm,
- priv);
- }
- } else {
- *events |= (1 << RTE_ETH_EVENT_INTR_LSC);
- }
- return ret;
-}
-
-/**
- * Process scheduled link status check.
- *
- * @param priv
- * Pointer to private structure.
- */
-static void
-mlx4_link_status_alarm(struct priv *priv)
-{
- uint32_t events;
- int ret;
-
- assert(priv->intr_alarm == 1);
- priv->intr_alarm = 0;
- ret = priv_collect_interrupt_events(priv, &events);
- if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
- _rte_eth_dev_callback_process(priv->dev,
- RTE_ETH_EVENT_INTR_LSC,
- NULL, NULL);
-}
-
-/**
- * Handle interrupts from the NIC.
- *
- * @param priv
- * Pointer to private structure.
- */
-static void
-mlx4_interrupt_handler(struct priv *priv)
-{
- int ret;
- uint32_t ev;
- int i;
-
- ret = priv_collect_interrupt_events(priv, &ev);
- if (ret > 0) {
- for (i = RTE_ETH_EVENT_UNKNOWN;
- i < RTE_ETH_EVENT_MAX;
- i++) {
- if (ev & (1 << i)) {
- ev &= ~(1 << i);
- _rte_eth_dev_callback_process(priv->dev, i,
- NULL, NULL);
- ret--;
- }
- }
- if (ret)
- WARN("%d event%s not processed", ret,
- (ret > 1 ? "s were" : " was"));
- }
-}
-
-/**
- * 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_intr_uninstall(struct priv *priv)
-{
- int err = rte_errno; /* Make sure rte_errno remains unchanged. */
-
- if (priv->intr_handle.fd != -1) {
- rte_intr_callback_unregister(&priv->intr_handle,
- (void (*)(void *))
- mlx4_interrupt_handler,
- priv);
- priv->intr_handle.fd = -1;
- }
- 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;
-}
-
-/**
- * Install interrupt handler.
- *
- * @param priv
- * Pointer to private structure.
- *
- * @return
- * 0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-priv_intr_install(struct priv *priv)
-{
- const struct rte_intr_conf *const intr_conf =
- &priv->dev->data->dev_conf.intr_conf;
- int rc;
-
- 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;
- }
- }
- return 0;
-error:
- priv_intr_uninstall(priv);
- return -rte_errno;
-}
-
-/**
- * Allocate queue vector and fill epoll fd list for Rx interrupts.
- *
- * @param priv
- * Pointer to private structure.
- *
- * @return
- * 0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-priv_rx_intr_vec_enable(struct priv *priv)
-{
- unsigned int i;
- 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->intr_handle;
-
- priv_rx_intr_vec_disable(priv);
- intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n]));
- if (intr_handle->intr_vec == NULL) {
- rte_errno = ENOMEM;
- ERROR("failed to allocate memory for interrupt vector,"
- " Rx interrupts will not be supported");
- return -rte_errno;
- }
- for (i = 0; i != n; ++i) {
- struct rxq *rxq = (*priv->rxqs)[i];
-
- /* Skip queues that cannot request interrupts. */
- if (!rxq || !rxq->channel) {
- /* Use invalid intr_vec[] index to disable entry. */
- intr_handle->intr_vec[i] =
- RTE_INTR_VEC_RXTX_OFFSET +
- RTE_MAX_RXTX_INTR_VEC_ID;
- continue;
- }
- if (count >= RTE_MAX_RXTX_INTR_VEC_ID) {
- rte_errno = E2BIG;
- ERROR("too many Rx queues for interrupt vector size"
- " (%d), Rx interrupts cannot be enabled",
- RTE_MAX_RXTX_INTR_VEC_ID);
- priv_rx_intr_vec_disable(priv);
- return -rte_errno;
- }
- intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + count;
- intr_handle->efds[count] = rxq->channel->fd;
- count++;
- }
- if (!count)
- priv_rx_intr_vec_disable(priv);
- else
- intr_handle->nb_efd = count;
- return 0;
-}
-
-/**
- * Clean up Rx interrupts handler.
- *
- * @param priv
- * Pointer to private structure.
- */
-static void
-priv_rx_intr_vec_disable(struct priv *priv)
-{
- struct rte_intr_handle *intr_handle = &priv->intr_handle;
-
- rte_intr_free_epoll_fd(intr_handle);
- free(intr_handle->intr_vec);
- intr_handle->nb_efd = 0;
- intr_handle->intr_vec = NULL;
-}
-
-/**
- * DPDK callback for Rx queue interrupt enable.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param idx
- * Rx queue index.
- *
- * @return
- * 0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
-{
- struct priv *priv = dev->data->dev_private;
- struct rxq *rxq = (*priv->rxqs)[idx];
- int ret;
-
- if (!rxq || !rxq->channel)
- ret = EINVAL;
- else
- ret = ibv_req_notify_cq(rxq->cq, 0);
- if (ret) {
- rte_errno = ret;
- WARN("unable to arm interrupt on rx queue %d", idx);
- }
- return -ret;
-}
-
-/**
- * DPDK callback for Rx queue interrupt disable.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param idx
- * Rx queue index.
- *
- * @return
- * 0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
-{
- struct priv *priv = dev->data->dev_private;
- struct rxq *rxq = (*priv->rxqs)[idx];
- struct ibv_cq *ev_cq;
- void *ev_ctx;
- int ret;
-
- if (!rxq || !rxq->channel) {
- ret = EINVAL;
- } else {
- ret = ibv_get_cq_event(rxq->cq->channel, &ev_cq, &ev_ctx);
- if (ret || ev_cq != rxq->cq)
- ret = EINVAL;
- }
- if (ret) {
- rte_errno = ret;
- WARN("unable to disable interrupt on rx queue %d",
- idx);
- } else {
- ibv_ack_cq_events(rxq->cq, 1);
- }
- return -ret;
-}
-
/**
* Verify and store value for device argument.
*
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index a35a94e..6852c4c 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -178,4 +178,15 @@ struct priv {
LIST_HEAD(mlx4_flows, rte_flow) flows;
};
+/* mlx4.c */
+
+int mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+
+/* mlx4_intr.c */
+
+int mlx4_intr_uninstall(struct priv *priv);
+int mlx4_intr_install(struct priv *priv);
+int mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx);
+int mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx);
+
#endif /* RTE_PMD_MLX4_H_ */
diff --git a/drivers/net/mlx4/mlx4_intr.c b/drivers/net/mlx4/mlx4_intr.c
new file mode 100644
index 0000000..bcf4d59
--- /dev/null
+++ b/drivers/net/mlx4/mlx4_intr.c
@@ -0,0 +1,376 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright 2017 6WIND S.A.
+ * Copyright 2017 Mellanox
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of 6WIND S.A. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * Interrupts handling for mlx4 driver.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Verbs headers do not support -pedantic. */
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+#include <infiniband/verbs.h>
+#ifdef PEDANTIC
+#pragma GCC diagnostic error "-Wpedantic"
+#endif
+
+#include <rte_alarm.h>
+#include <rte_errno.h>
+#include <rte_ethdev.h>
+#include <rte_interrupts.h>
+
+#include "mlx4.h"
+#include "mlx4_utils.h"
+
+static void mlx4_link_status_alarm(struct priv *priv);
+
+/**
+ * Clean up Rx interrupts handler.
+ *
+ * @param priv
+ * Pointer to private structure.
+ */
+static void
+mlx4_rx_intr_vec_disable(struct priv *priv)
+{
+ struct rte_intr_handle *intr_handle = &priv->intr_handle;
+
+ rte_intr_free_epoll_fd(intr_handle);
+ free(intr_handle->intr_vec);
+ intr_handle->nb_efd = 0;
+ intr_handle->intr_vec = NULL;
+}
+
+/**
+ * Allocate queue vector and fill epoll fd list for Rx interrupts.
+ *
+ * @param priv
+ * Pointer to private structure.
+ *
+ * @return
+ * 0 on success, negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx4_rx_intr_vec_enable(struct priv *priv)
+{
+ unsigned int i;
+ 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->intr_handle;
+
+ mlx4_rx_intr_vec_disable(priv);
+ intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n]));
+ if (intr_handle->intr_vec == NULL) {
+ rte_errno = ENOMEM;
+ ERROR("failed to allocate memory for interrupt vector,"
+ " Rx interrupts will not be supported");
+ return -rte_errno;
+ }
+ for (i = 0; i != n; ++i) {
+ struct rxq *rxq = (*priv->rxqs)[i];
+
+ /* Skip queues that cannot request interrupts. */
+ if (!rxq || !rxq->channel) {
+ /* Use invalid intr_vec[] index to disable entry. */
+ intr_handle->intr_vec[i] =
+ RTE_INTR_VEC_RXTX_OFFSET +
+ RTE_MAX_RXTX_INTR_VEC_ID;
+ continue;
+ }
+ if (count >= RTE_MAX_RXTX_INTR_VEC_ID) {
+ rte_errno = E2BIG;
+ ERROR("too many Rx queues for interrupt vector size"
+ " (%d), Rx interrupts cannot be enabled",
+ RTE_MAX_RXTX_INTR_VEC_ID);
+ mlx4_rx_intr_vec_disable(priv);
+ return -rte_errno;
+ }
+ intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + count;
+ intr_handle->efds[count] = rxq->channel->fd;
+ count++;
+ }
+ if (!count)
+ mlx4_rx_intr_vec_disable(priv);
+ else
+ intr_handle->nb_efd = count;
+ return 0;
+}
+
+/**
+ * Collect interrupt events.
+ *
+ * @param priv
+ * Pointer to private structure.
+ * @param events
+ * Pointer to event flags holder.
+ *
+ * @return
+ * Number of events.
+ */
+static int
+mlx4_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;
+ /* Read all message and acknowledge them. */
+ for (;;) {
+ if (ibv_get_async_event(priv->ctx, &event))
+ break;
+ if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
+ event.event_type == IBV_EVENT_PORT_ERR) &&
+ intr_conf->lsc) {
+ port_change = 1;
+ ret++;
+ } else if (event.event_type == IBV_EVENT_DEVICE_FATAL &&
+ intr_conf->rmv) {
+ *events |= (1 << RTE_ETH_EVENT_INTR_RMV);
+ ret++;
+ } else {
+ DEBUG("event type %d on port %d not handled",
+ event.event_type, event.element.port_num);
+ }
+ ibv_ack_async_event(&event);
+ }
+ if (!port_change)
+ return ret;
+ mlx4_link_update(priv->dev, 0);
+ if (((link->link_speed == 0) && link->link_status) ||
+ ((link->link_speed != 0) && !link->link_status)) {
+ if (!priv->intr_alarm) {
+ /* Inconsistent status, check again later. */
+ priv->intr_alarm = 1;
+ rte_eal_alarm_set(MLX4_INTR_ALARM_TIMEOUT,
+ (void (*)(void *))
+ mlx4_link_status_alarm,
+ priv);
+ }
+ } else {
+ *events |= (1 << RTE_ETH_EVENT_INTR_LSC);
+ }
+ return ret;
+}
+
+/**
+ * Process scheduled link status check.
+ *
+ * @param priv
+ * Pointer to private structure.
+ */
+static void
+mlx4_link_status_alarm(struct priv *priv)
+{
+ uint32_t events;
+ int ret;
+
+ assert(priv->intr_alarm == 1);
+ priv->intr_alarm = 0;
+ ret = mlx4_collect_interrupt_events(priv, &events);
+ if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
+ _rte_eth_dev_callback_process(priv->dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL, NULL);
+}
+
+/**
+ * Handle interrupts from the NIC.
+ *
+ * @param priv
+ * Pointer to private structure.
+ */
+static void
+mlx4_interrupt_handler(struct priv *priv)
+{
+ int ret;
+ uint32_t ev;
+ int i;
+
+ ret = mlx4_collect_interrupt_events(priv, &ev);
+ if (ret > 0) {
+ for (i = RTE_ETH_EVENT_UNKNOWN;
+ i < RTE_ETH_EVENT_MAX;
+ i++) {
+ if (ev & (1 << i)) {
+ ev &= ~(1 << i);
+ _rte_eth_dev_callback_process(priv->dev, i,
+ NULL, NULL);
+ ret--;
+ }
+ }
+ if (ret)
+ WARN("%d event%s not processed", ret,
+ (ret > 1 ? "s were" : " was"));
+ }
+}
+
+/**
+ * Uninstall interrupt handler.
+ *
+ * @param priv
+ * Pointer to private structure.
+ *
+ * @return
+ * 0 on success, negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx4_intr_uninstall(struct priv *priv)
+{
+ int err = rte_errno; /* Make sure rte_errno remains unchanged. */
+
+ if (priv->intr_handle.fd != -1) {
+ rte_intr_callback_unregister(&priv->intr_handle,
+ (void (*)(void *))
+ mlx4_interrupt_handler,
+ priv);
+ priv->intr_handle.fd = -1;
+ }
+ rte_eal_alarm_cancel((void (*)(void *))mlx4_link_status_alarm, priv);
+ priv->intr_alarm = 0;
+ mlx4_rx_intr_vec_disable(priv);
+ rte_errno = err;
+ return 0;
+}
+
+/**
+ * Install interrupt handler.
+ *
+ * @param priv
+ * Pointer to private structure.
+ *
+ * @return
+ * 0 on success, negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx4_intr_install(struct priv *priv)
+{
+ const struct rte_intr_conf *const intr_conf =
+ &priv->dev->data->dev_conf.intr_conf;
+ int rc;
+
+ mlx4_intr_uninstall(priv);
+ if (intr_conf->rxq && mlx4_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;
+ }
+ }
+ return 0;
+error:
+ mlx4_intr_uninstall(priv);
+ return -rte_errno;
+}
+
+/**
+ * DPDK callback for Rx queue interrupt disable.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param idx
+ * Rx queue index.
+ *
+ * @return
+ * 0 on success, negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
+{
+ struct priv *priv = dev->data->dev_private;
+ struct rxq *rxq = (*priv->rxqs)[idx];
+ struct ibv_cq *ev_cq;
+ void *ev_ctx;
+ int ret;
+
+ if (!rxq || !rxq->channel) {
+ ret = EINVAL;
+ } else {
+ ret = ibv_get_cq_event(rxq->cq->channel, &ev_cq, &ev_ctx);
+ if (ret || ev_cq != rxq->cq)
+ ret = EINVAL;
+ }
+ if (ret) {
+ rte_errno = ret;
+ WARN("unable to disable interrupt on rx queue %d",
+ idx);
+ } else {
+ ibv_ack_cq_events(rxq->cq, 1);
+ }
+ return -ret;
+}
+
+/**
+ * DPDK callback for Rx queue interrupt enable.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param idx
+ * Rx queue index.
+ *
+ * @return
+ * 0 on success, negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
+{
+ struct priv *priv = dev->data->dev_private;
+ struct rxq *rxq = (*priv->rxqs)[idx];
+ int ret;
+
+ if (!rxq || !rxq->channel)
+ ret = EINVAL;
+ else
+ ret = ibv_req_notify_cq(rxq->cq, 0);
+ if (ret) {
+ rte_errno = ret;
+ WARN("unable to arm interrupt on rx queue %d", idx);
+ }
+ return -ret;
+}
--
2.1.4
next prev parent reply other threads:[~2017-09-01 8:08 UTC|newest]
Thread overview: 110+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-01 16:53 [dpdk-dev] [PATCH v1 00/48] net/mlx4: trim and refactor entire PMD Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 01/48] net/mlx4: add consistency to copyright notices Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 02/48] net/mlx4: remove limitation on number of instances Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 03/48] net/mlx4: check max number of ports dynamically Adrien Mazarguil
2017-08-01 17:35 ` Legacy, Allain
2017-08-02 7:52 ` Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 04/48] net/mlx4: remove useless compilation checks Adrien Mazarguil
2017-08-18 13:39 ` Ferruh Yigit
2017-09-01 10:19 ` Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 05/48] net/mlx4: remove secondary process support Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 06/48] net/mlx4: remove useless code Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 07/48] net/mlx4: remove soft counters compilation option Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 08/48] net/mlx4: remove scatter mode " Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 09/48] net/mlx4: remove Tx inline " Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 10/48] net/mlx4: remove allmulti and promisc support Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 11/48] net/mlx4: remove VLAN filter support Adrien Mazarguil
2017-08-01 16:53 ` [dpdk-dev] [PATCH v1 12/48] net/mlx4: remove MAC address configuration support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 13/48] net/mlx4: drop MAC flows affecting all Rx queues Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 14/48] net/mlx4: revert flow API RSS support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 15/48] net/mlx4: revert RSS parent queue refactoring Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 16/48] net/mlx4: drop RSS support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 17/48] net/mlx4: drop checksum offloads support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 18/48] net/mlx4: drop packet type recognition support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 19/48] net/mlx4: drop scatter/gather support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 20/48] net/mlx4: drop inline receive support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 21/48] net/mlx4: use standard QP attributes Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 22/48] net/mlx4: revert resource domain support Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 23/48] net/mlx4: revert multicast echo prevention Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 24/48] net/mlx4: revert fast Verbs interface for Tx Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 25/48] net/mlx4: revert fast Verbs interface for Rx Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 26/48] net/mlx4: simplify link update function Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 27/48] net/mlx4: standardize on negative errno values Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 28/48] net/mlx4: clean up coding style inconsistencies Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 29/48] net/mlx4: remove control path locks Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 30/48] net/mlx4: remove unnecessary wrapper functions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 31/48] net/mlx4: remove mbuf macro definitions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 32/48] net/mlx4: use standard macro to get array size Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 33/48] net/mlx4: separate debugging macros Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 34/48] net/mlx4: use a single interrupt handle Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 35/48] net/mlx4: rename alarm field Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 36/48] net/mlx4: refactor interrupt FD settings Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 37/48] net/mlx4: clean up interrupt functions prototypes Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 38/48] net/mlx4: compact interrupt functions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 39/48] net/mlx4: separate interrupt handling Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 40/48] net/mlx4: separate Rx/Tx definitions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 41/48] net/mlx4: separate Rx/Tx functions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 42/48] net/mlx4: separate device control functions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 43/48] net/mlx4: separate Tx configuration functions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 44/48] net/mlx4: separate Rx " Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 45/48] net/mlx4: group flow API handlers in common file Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 46/48] net/mlx4: rename private functions in flow API Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 47/48] net/mlx4: separate memory management functions Adrien Mazarguil
2017-08-01 16:54 ` [dpdk-dev] [PATCH v1 48/48] net/mlx4: clean up includes and comments Adrien Mazarguil
2017-08-18 13:28 ` [dpdk-dev] [PATCH v1 00/48] net/mlx4: trim and refactor entire PMD Ferruh Yigit
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 00/51] " Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 01/51] net/mlx4: add consistency to copyright notices Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 02/51] net/mlx4: remove limitation on number of instances Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 03/51] net/mlx4: check max number of ports dynamically Adrien Mazarguil
2017-09-01 10:57 ` Legacy, Allain
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 04/51] net/mlx4: remove useless compilation checks Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 05/51] net/mlx4: remove secondary process support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 06/51] net/mlx4: remove useless code Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 07/51] net/mlx4: remove soft counters compilation option Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 08/51] net/mlx4: remove scatter mode " Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 09/51] net/mlx4: remove Tx inline " Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 10/51] net/mlx4: remove allmulti and promisc support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 11/51] net/mlx4: remove VLAN filter support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 12/51] net/mlx4: remove MAC address configuration support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 13/51] net/mlx4: drop MAC flows affecting all Rx queues Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 14/51] net/mlx4: revert flow API RSS support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 15/51] net/mlx4: revert RSS parent queue refactoring Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 16/51] net/mlx4: drop RSS support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 17/51] net/mlx4: drop checksum offloads support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 18/51] net/mlx4: drop packet type recognition support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 19/51] net/mlx4: drop scatter/gather support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 20/51] net/mlx4: drop inline receive support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 21/51] net/mlx4: use standard QP attributes Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 22/51] net/mlx4: revert resource domain support Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 23/51] net/mlx4: revert multicast echo prevention Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 24/51] net/mlx4: revert fast Verbs interface for Tx Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 25/51] net/mlx4: revert fast Verbs interface for Rx Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 26/51] net/mlx4: simplify Rx buffer handling Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 27/51] net/mlx4: simplify link update function Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 28/51] net/mlx4: standardize on negative errno values Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 29/51] net/mlx4: clean up coding style inconsistencies Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 30/51] net/mlx4: remove control path locks Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 31/51] net/mlx4: remove unnecessary wrapper functions Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 32/51] net/mlx4: remove mbuf macro definitions Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 33/51] net/mlx4: use standard macro to get array size Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 34/51] net/mlx4: separate debugging macros Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 35/51] net/mlx4: use a single interrupt handle Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 36/51] net/mlx4: rename alarm field Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 37/51] net/mlx4: refactor interrupt FD settings Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 38/51] net/mlx4: clean up interrupt functions prototypes Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 39/51] net/mlx4: compact interrupt functions Adrien Mazarguil
2017-09-01 8:06 ` Adrien Mazarguil [this message]
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 41/51] net/mlx4: separate Rx/Tx definitions Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 42/51] net/mlx4: separate Rx/Tx functions Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 43/51] net/mlx4: separate device control functions Adrien Mazarguil
2017-09-01 8:06 ` [dpdk-dev] [PATCH v2 44/51] net/mlx4: separate Tx configuration functions Adrien Mazarguil
2017-09-01 8:07 ` [dpdk-dev] [PATCH v2 45/51] net/mlx4: separate Rx " Adrien Mazarguil
2017-09-01 8:07 ` [dpdk-dev] [PATCH v2 46/51] net/mlx4: group flow API handlers in common file Adrien Mazarguil
2017-09-01 8:07 ` [dpdk-dev] [PATCH v2 47/51] net/mlx4: rename private functions in flow API Adrien Mazarguil
2017-09-01 8:07 ` [dpdk-dev] [PATCH v2 48/51] net/mlx4: separate memory management functions Adrien Mazarguil
2017-09-01 8:07 ` [dpdk-dev] [PATCH v2 49/51] net/mlx4: clean up includes and comments Adrien Mazarguil
2017-09-01 8:07 ` [dpdk-dev] [PATCH v2 50/51] net/mlx4: remove isolated mode constraint Adrien Mazarguil
2017-09-01 8:07 ` [dpdk-dev] [PATCH v2 51/51] net/mlx4: rely on ethdev for Tx/Rx queue arrays Adrien Mazarguil
2017-09-01 11:24 ` [dpdk-dev] [PATCH v2 00/51] net/mlx4: trim and refactor entire PMD Ferruh Yigit
2017-09-01 11:56 ` Adrien Mazarguil
2017-09-05 9:59 ` Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=334d02cb454d6e15eda65f6b2be7a075bdf34cde.1504252977.git.adrien.mazarguil@6wind.com \
--to=adrien.mazarguil@6wind.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).