From: Moti Haimovsky Date: Sun, 28 Jan 2018 10:45:35 +0000 (+0200) Subject: net/tap: support Rx interrupt X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=4870a8cdd9687c62b2c9bf71584b445b4a4257e8;p=dpdk.git net/tap: support Rx interrupt This patch adds support for registering and waiting for Rx interrupts. This allows applications to wait for Rx events from the PMD using the DPDK rte_epoll subsystem. Signed-off-by: Moti Haimovsky Acked-by: Pascal Mazon --- diff --git a/doc/guides/nics/features/tap.ini b/doc/guides/nics/features/tap.ini index f0e893d63f..8bc51875cd 100644 --- a/doc/guides/nics/features/tap.ini +++ b/doc/guides/nics/features/tap.ini @@ -7,6 +7,7 @@ Speed capabilities = P Link status = Y Link status event = Y +Rx interrupt = Y Jumbo frame = Y Promiscuous mode = Y Allmulticast mode = Y diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile index 315c6bd402..ccc5c5fc07 100644 --- a/drivers/net/tap/Makefile +++ b/drivers/net/tap/Makefile @@ -36,6 +36,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_api.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_intr.c include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index fd425726aa..29d635613c 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -1218,7 +1218,7 @@ tap_dev_intr_handler(void *cb_arg) } static int -tap_intr_handle_set(struct rte_eth_dev *dev, int set) +tap_lsc_intr_handle_set(struct rte_eth_dev *dev, int set) { struct pmd_internals *pmd = dev->data->dev_private; @@ -1243,6 +1243,20 @@ tap_intr_handle_set(struct rte_eth_dev *dev, int set) tap_dev_intr_handler, dev); } +static int +tap_intr_handle_set(struct rte_eth_dev *dev, int set) +{ + int err; + + err = tap_lsc_intr_handle_set(dev, set); + if (err) + return err; + err = tap_rx_intr_vec_set(dev, set); + if (err && set) + tap_lsc_intr_handle_set(dev, 0); + return err; +} + static const uint32_t* tap_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused) { @@ -1375,6 +1389,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name, pmd->intr_handle.type = RTE_INTR_HANDLE_EXT; pmd->intr_handle.fd = -1; + dev->intr_handle = &pmd->intr_handle; /* Presetup the fds to -1 as being not valid */ for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) { diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index d4f1e6c55c..ed85244364 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -106,4 +106,8 @@ struct pmd_internals { struct rte_intr_handle intr_handle; /* LSC interrupt handle. */ }; +/* tap_intr.c */ + +int tap_rx_intr_vec_set(struct rte_eth_dev *dev, int set); + #endif /* _RTE_ETH_TAP_H_ */ diff --git a/drivers/net/tap/tap_intr.c b/drivers/net/tap/tap_intr.c new file mode 100644 index 0000000000..b0e1991471 --- /dev/null +++ b/drivers/net/tap/tap_intr.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 Mellanox Technologies, Ltd. + */ + +/** + * @file + * Interrupts handling for tap driver. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/** + * Unregister Rx interrupts free the queue interrupt vector. + * + * @param dev + * Pointer to the tap rte_eth_dev structure. + */ +static void +tap_rx_intr_vec_uninstall(struct rte_eth_dev *dev) +{ + struct pmd_internals *pmd = dev->data->dev_private; + struct rte_intr_handle *intr_handle = &pmd->intr_handle; + + rte_intr_free_epoll_fd(intr_handle); + free(intr_handle->intr_vec); + intr_handle->intr_vec = NULL; + intr_handle->nb_efd = 0; +} + +/** + * Allocate Rx queue interrupt vector and register Rx interrupts. + * + * @param dev + * Pointer to the tap rte_eth_dev device structure. + * + * @return + * 0 on success, negative errno value otherwise and rte_errno is set. + */ +static int +tap_rx_intr_vec_install(struct rte_eth_dev *dev) +{ + struct pmd_internals *pmd = dev->data->dev_private; + unsigned int rxqs_n = pmd->dev->data->nb_rx_queues; + struct rte_intr_handle *intr_handle = &pmd->intr_handle; + unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID); + unsigned int i; + unsigned int count = 0; + + if (!dev->data->dev_conf.intr_conf.rxq) + return 0; + intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n])); + if (intr_handle->intr_vec == NULL) { + rte_errno = ENOMEM; + RTE_LOG(ERR, PMD, + "failed to allocate memory for interrupt vector," + " Rx interrupts will not be supported"); + return -rte_errno; + } + for (i = 0; i < n; i++) { + struct rx_queue *rxq = pmd->dev->data->rx_queues[i]; + + /* Skip queues that cannot request interrupts. */ + if (!rxq || rxq->fd <= 0) { + /* 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; + } + intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + count; + intr_handle->efds[count] = rxq->fd; + count++; + } + if (!count) + tap_rx_intr_vec_uninstall(dev); + else + intr_handle->nb_efd = count; + return 0; +} + +/** + * Register or unregister the Rx interrupts. + * + * @param dev + * Pointer to the tap rte_eth_dev device structure. + * @param set + * should the operation be register or unregister the interrupts. + * + * @return + * 0 on success, negative errno value otherwise and rte_errno is set. + */ +int +tap_rx_intr_vec_set(struct rte_eth_dev *dev, int set) +{ + tap_rx_intr_vec_uninstall(dev); + if (set) + return tap_rx_intr_vec_install(dev); + return 0; +}