From: Michal Krawczyk <mk@semihalf.com>
To: dev@dpdk.org
Cc: ndagan@amazon.com, shaibran@amazon.com, upstream@semihalf.com,
Michal Krawczyk <mk@semihalf.com>, Artur Rojek <ar@semihalf.com>,
Igor Chauskin <igorch@amazon.com>,
Shay Agroskin <shayagr@amazon.com>
Subject: [dpdk-dev] [PATCH v4 4/6] net/ena: add support for Rx interrupts
Date: Fri, 23 Jul 2021 12:24:52 +0200 [thread overview]
Message-ID: <20210723102454.12206-5-mk@semihalf.com> (raw)
In-Reply-To: <20210723102454.12206-1-mk@semihalf.com>
In order to support asynchronous Rx in the applications, the driver has
to configure the event file descriptors and configure the HW.
This patch configures appropriate data structures for the rte_ethdev
layer, adds .rx_queue_intr_enable and .rx_queue_intr_disable API
handlers, and configures IO queues to work in the interrupt mode, if it
was requested by the application.
Signed-off-by: Michal Krawczyk <mk@semihalf.com>
Reviewed-by: Artur Rojek <ar@semihalf.com>
Reviewed-by: Igor Chauskin <igorch@amazon.com>
Reviewed-by: Shai Brandes <shaibran@amazon.com>
Reviewed-by: Shay Agroskin <shayagr@amazon.com>
---
doc/guides/nics/ena.rst | 12 ++
doc/guides/nics/features/ena.ini | 1 +
doc/guides/rel_notes/release_21_08.rst | 7 ++
drivers/net/ena/ena_ethdev.c | 146 +++++++++++++++++++++++--
4 files changed, 154 insertions(+), 12 deletions(-)
diff --git a/doc/guides/nics/ena.rst b/doc/guides/nics/ena.rst
index 0f1f63f722..63951098ea 100644
--- a/doc/guides/nics/ena.rst
+++ b/doc/guides/nics/ena.rst
@@ -141,6 +141,7 @@ Supported features
* LSC event notification
* Watchdog (requires handling of timers in the application)
* Device reset upon failure
+* Rx interrupts
Prerequisites
-------------
@@ -180,6 +181,17 @@ At this point the system should be ready to run DPDK applications. Once the
application runs to completion, the ENA can be detached from attached module if
necessary.
+**Rx interrupts support**
+
+ENA PMD supports Rx interrupts, which can be used to wake up lcores waiting for
+input. Please note that it won't work with ``igb_uio``, so to use this feature,
+the ``vfio-pci`` should be used.
+
+ENA handles admin interrupts and AENQ notifications on separate interrupt.
+There is possibility that there won't be enough event file descriptors to
+handle both admin and Rx interrupts. In that situation the Rx interrupt request
+will fail.
+
**Note about usage on \*.metal instances**
On AWS, the metal instances are supporting IOMMU for both arm64 and x86_64
diff --git a/doc/guides/nics/features/ena.ini b/doc/guides/nics/features/ena.ini
index 2595ff53f9..3976bbbda6 100644
--- a/doc/guides/nics/features/ena.ini
+++ b/doc/guides/nics/features/ena.ini
@@ -6,6 +6,7 @@
[Features]
Link status = Y
Link status event = Y
+Rx interrupt = Y
MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
diff --git a/doc/guides/rel_notes/release_21_08.rst b/doc/guides/rel_notes/release_21_08.rst
index 247e672f02..616e2cdea9 100644
--- a/doc/guides/rel_notes/release_21_08.rst
+++ b/doc/guides/rel_notes/release_21_08.rst
@@ -95,6 +95,13 @@ New Features
Added a new PMD driver for Wangxun 1 Gigabit Ethernet NICs.
See the :doc:`../nics/ngbe` for more details.
+* **Updated Amazon ENA PMD.**
+
+ The new driver version (v2.4.0) introduced bug fixes and improvements,
+ including:
+
+ * Added Rx interrupt support.
+
* **Added support for Marvell CNXK crypto driver.**
* Added cnxk crypto PMD which provides support for an integrated
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index 67cd91046a..72f9887797 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -213,11 +213,11 @@ static void ena_rx_queue_release_bufs(struct ena_ring *ring);
static void ena_tx_queue_release_bufs(struct ena_ring *ring);
static int ena_link_update(struct rte_eth_dev *dev,
int wait_to_complete);
-static int ena_create_io_queue(struct ena_ring *ring);
+static int ena_create_io_queue(struct rte_eth_dev *dev, struct ena_ring *ring);
static void ena_queue_stop(struct ena_ring *ring);
static void ena_queue_stop_all(struct rte_eth_dev *dev,
enum ena_ring_type ring_type);
-static int ena_queue_start(struct ena_ring *ring);
+static int ena_queue_start(struct rte_eth_dev *dev, struct ena_ring *ring);
static int ena_queue_start_all(struct rte_eth_dev *dev,
enum ena_ring_type ring_type);
static void ena_stats_restart(struct rte_eth_dev *dev);
@@ -249,6 +249,11 @@ static int ena_process_bool_devarg(const char *key,
static int ena_parse_devargs(struct ena_adapter *adapter,
struct rte_devargs *devargs);
static int ena_copy_eni_stats(struct ena_adapter *adapter);
+static int ena_setup_rx_intr(struct rte_eth_dev *dev);
+static int ena_rx_queue_intr_enable(struct rte_eth_dev *dev,
+ uint16_t queue_id);
+static int ena_rx_queue_intr_disable(struct rte_eth_dev *dev,
+ uint16_t queue_id);
static const struct eth_dev_ops ena_dev_ops = {
.dev_configure = ena_dev_configure,
@@ -269,6 +274,8 @@ static const struct eth_dev_ops ena_dev_ops = {
.dev_reset = ena_dev_reset,
.reta_update = ena_rss_reta_update,
.reta_query = ena_rss_reta_query,
+ .rx_queue_intr_enable = ena_rx_queue_intr_enable,
+ .rx_queue_intr_disable = ena_rx_queue_intr_disable,
};
void ena_rss_key_fill(void *key, size_t size)
@@ -829,7 +836,7 @@ static int ena_queue_start_all(struct rte_eth_dev *dev,
"Inconsistent state of Tx queues\n");
}
- rc = ena_queue_start(&queues[i]);
+ rc = ena_queue_start(dev, &queues[i]);
if (rc) {
PMD_INIT_LOG(ERR,
@@ -1074,6 +1081,10 @@ static int ena_start(struct rte_eth_dev *dev)
if (rc)
return rc;
+ rc = ena_setup_rx_intr(dev);
+ if (rc)
+ return rc;
+
rc = ena_queue_start_all(dev, ENA_RING_TYPE_RX);
if (rc)
return rc;
@@ -1114,6 +1125,8 @@ static int ena_stop(struct rte_eth_dev *dev)
{
struct ena_adapter *adapter = dev->data->dev_private;
struct ena_com_dev *ena_dev = &adapter->ena_dev;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int rc;
/* Cannot free memory in secondary process */
@@ -1132,6 +1145,16 @@ static int ena_stop(struct rte_eth_dev *dev)
PMD_DRV_LOG(ERR, "Device reset failed, rc: %d\n", rc);
}
+ rte_intr_disable(intr_handle);
+
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec != NULL) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+
+ rte_intr_enable(intr_handle);
+
++adapter->dev_stats.dev_stop;
adapter->state = ENA_ADAPTER_STATE_STOPPED;
dev->data->dev_started = 0;
@@ -1139,10 +1162,12 @@ static int ena_stop(struct rte_eth_dev *dev)
return 0;
}
-static int ena_create_io_queue(struct ena_ring *ring)
+static int ena_create_io_queue(struct rte_eth_dev *dev, struct ena_ring *ring)
{
- struct ena_adapter *adapter;
- struct ena_com_dev *ena_dev;
+ struct ena_adapter *adapter = ring->adapter;
+ struct ena_com_dev *ena_dev = &adapter->ena_dev;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ena_com_create_io_ctx ctx =
/* policy set to _HOST just to satisfy icc compiler */
{ ENA_ADMIN_PLACEMENT_POLICY_HOST,
@@ -1151,9 +1176,7 @@ static int ena_create_io_queue(struct ena_ring *ring)
unsigned int i;
int rc;
- adapter = ring->adapter;
- ena_dev = &adapter->ena_dev;
-
+ ctx.msix_vector = -1;
if (ring->type == ENA_RING_TYPE_TX) {
ena_qid = ENA_IO_TXQ_IDX(ring->id);
ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
@@ -1163,12 +1186,13 @@ static int ena_create_io_queue(struct ena_ring *ring)
} else {
ena_qid = ENA_IO_RXQ_IDX(ring->id);
ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX;
+ if (rte_intr_dp_is_en(intr_handle))
+ ctx.msix_vector = intr_handle->intr_vec[ring->id];
for (i = 0; i < ring->ring_size; i++)
ring->empty_rx_reqs[i] = i;
}
ctx.queue_size = ring->ring_size;
ctx.qid = ena_qid;
- ctx.msix_vector = -1; /* interrupts not used */
ctx.numa_node = ring->numa_socket_id;
rc = ena_com_create_io_queue(ena_dev, &ctx);
@@ -1193,6 +1217,10 @@ static int ena_create_io_queue(struct ena_ring *ring)
if (ring->type == ENA_RING_TYPE_TX)
ena_com_update_numa_node(ring->ena_com_io_cq, ctx.numa_node);
+ /* Start with Rx interrupts being masked. */
+ if (ring->type == ENA_RING_TYPE_RX && rte_intr_dp_is_en(intr_handle))
+ ena_rx_queue_intr_disable(dev, ring->id);
+
return 0;
}
@@ -1229,14 +1257,14 @@ static void ena_queue_stop_all(struct rte_eth_dev *dev,
ena_queue_stop(&queues[i]);
}
-static int ena_queue_start(struct ena_ring *ring)
+static int ena_queue_start(struct rte_eth_dev *dev, struct ena_ring *ring)
{
int rc, bufs_num;
ena_assert_msg(ring->configured == 1,
"Trying to start unconfigured queue\n");
- rc = ena_create_io_queue(ring);
+ rc = ena_create_io_queue(dev, ring);
if (rc) {
PMD_INIT_LOG(ERR, "Failed to create IO queue\n");
return rc;
@@ -2944,6 +2972,100 @@ static int ena_parse_devargs(struct ena_adapter *adapter,
return rc;
}
+static int ena_setup_rx_intr(struct rte_eth_dev *dev)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+ int rc;
+ uint16_t vectors_nb, i;
+ bool rx_intr_requested = dev->data->dev_conf.intr_conf.rxq;
+
+ if (!rx_intr_requested)
+ return 0;
+
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ PMD_DRV_LOG(ERR,
+ "Rx interrupt requested, but it isn't supported by the PCI driver\n");
+ return -ENOTSUP;
+ }
+
+ /* Disable interrupt mapping before the configuration starts. */
+ rte_intr_disable(intr_handle);
+
+ /* Verify if there are enough vectors available. */
+ vectors_nb = dev->data->nb_rx_queues;
+ if (vectors_nb > RTE_MAX_RXTX_INTR_VEC_ID) {
+ PMD_DRV_LOG(ERR,
+ "Too many Rx interrupts requested, maximum number: %d\n",
+ RTE_MAX_RXTX_INTR_VEC_ID);
+ rc = -ENOTSUP;
+ goto enable_intr;
+ }
+
+ intr_handle->intr_vec = rte_zmalloc("intr_vec",
+ dev->data->nb_rx_queues * sizeof(*intr_handle->intr_vec), 0);
+ if (intr_handle->intr_vec == NULL) {
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate interrupt vector for %d queues\n",
+ dev->data->nb_rx_queues);
+ rc = -ENOMEM;
+ goto enable_intr;
+ }
+
+ rc = rte_intr_efd_enable(intr_handle, vectors_nb);
+ if (rc != 0)
+ goto free_intr_vec;
+
+ if (!rte_intr_allow_others(intr_handle)) {
+ PMD_DRV_LOG(ERR,
+ "Not enough interrupts available to use both ENA Admin and Rx interrupts\n");
+ goto disable_intr_efd;
+ }
+
+ for (i = 0; i < vectors_nb; ++i)
+ intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + i;
+
+ rte_intr_enable(intr_handle);
+ return 0;
+
+disable_intr_efd:
+ rte_intr_efd_disable(intr_handle);
+free_intr_vec:
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+enable_intr:
+ rte_intr_enable(intr_handle);
+ return rc;
+}
+
+static void ena_rx_queue_intr_set(struct rte_eth_dev *dev,
+ uint16_t queue_id,
+ bool unmask)
+{
+ struct ena_adapter *adapter = dev->data->dev_private;
+ struct ena_ring *rxq = &adapter->rx_ring[queue_id];
+ struct ena_eth_io_intr_reg intr_reg;
+
+ ena_com_update_intr_reg(&intr_reg, 0, 0, unmask);
+ ena_com_unmask_intr(rxq->ena_com_io_cq, &intr_reg);
+}
+
+static int ena_rx_queue_intr_enable(struct rte_eth_dev *dev,
+ uint16_t queue_id)
+{
+ ena_rx_queue_intr_set(dev, queue_id, true);
+
+ return 0;
+}
+
+static int ena_rx_queue_intr_disable(struct rte_eth_dev *dev,
+ uint16_t queue_id)
+{
+ ena_rx_queue_intr_set(dev, queue_id, false);
+
+ return 0;
+}
+
/*********************************************************************
* PMD configuration
*********************************************************************/
--
2.25.1
next prev parent reply other threads:[~2021-07-23 10:27 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-13 15:41 [dpdk-dev] [PATCH 0/6] net/ena: v2.4.0 driver update Michal Krawczyk
2021-07-13 15:41 ` [dpdk-dev] [PATCH 1/6] net/ena: adjust driver logs Michal Krawczyk
2021-07-13 15:41 ` [dpdk-dev] [PATCH 2/6] net/ena: make use of the IO debug build option Michal Krawczyk
2021-07-13 15:41 ` [dpdk-dev] [PATCH 3/6] net/ena: trigger reset when Tx prepare fails Michal Krawczyk
2021-07-13 15:41 ` [dpdk-dev] [PATCH 4/6] net/ena: add support for Rx interrupts Michal Krawczyk
2021-07-13 15:41 ` [dpdk-dev] [PATCH 5/6] net/ena: rework RSS configuration Michal Krawczyk
2021-07-14 8:04 ` Vladimir Medvedkin
2021-07-14 8:20 ` Michał Krawczyk
2021-07-14 11:43 ` Vladimir Medvedkin
2021-07-14 12:07 ` Michał Krawczyk
2021-07-13 15:41 ` [dpdk-dev] [PATCH 6/6] net/ena: update version to v2.4.0 Michal Krawczyk
2021-07-14 10:34 ` [dpdk-dev] [PATCH v2 0/6] net/ena: v2.4.0 driver update Michal Krawczyk
2021-07-14 10:34 ` [dpdk-dev] [PATCH v2 1/6] net/ena: adjust driver logs Michal Krawczyk
2021-07-14 10:34 ` [dpdk-dev] [PATCH v2 2/6] net/ena: make use of the IO debug build option Michal Krawczyk
2021-07-14 10:34 ` [dpdk-dev] [PATCH v2 3/6] net/ena: trigger reset when Tx prepare fails Michal Krawczyk
2021-07-14 10:34 ` [dpdk-dev] [PATCH v2 4/6] net/ena: add support for Rx interrupts Michal Krawczyk
2021-07-14 10:34 ` [dpdk-dev] [PATCH v2 5/6] net/ena: rework RSS configuration Michal Krawczyk
2021-07-14 10:34 ` [dpdk-dev] [PATCH v2 6/6] net/ena: update version to v2.4.0 Michal Krawczyk
2021-07-14 10:43 ` [dpdk-dev] [PATCH v3 0/6] net/ena: v2.4.0 driver update Michal Krawczyk
2021-07-14 10:43 ` [dpdk-dev] [PATCH v3 1/6] net/ena: adjust driver logs Michal Krawczyk
2021-07-14 10:43 ` [dpdk-dev] [PATCH v3 2/6] net/ena: make use of the IO debug build option Michal Krawczyk
2021-07-14 10:43 ` [dpdk-dev] [PATCH v3 3/6] net/ena: trigger reset when Tx prepare fails Michal Krawczyk
2021-07-14 10:43 ` [dpdk-dev] [PATCH v3 4/6] net/ena: add support for Rx interrupts Michal Krawczyk
2021-07-14 10:43 ` [dpdk-dev] [PATCH v3 5/6] net/ena: rework RSS configuration Michal Krawczyk
2021-07-23 9:23 ` Thomas Monjalon
2021-07-23 9:39 ` Michał Krawczyk
2021-07-23 9:44 ` Thomas Monjalon
2021-07-23 9:49 ` Michał Krawczyk
2021-07-23 11:52 ` Thomas Monjalon
2021-07-23 13:19 ` Thomas Monjalon
2021-07-14 10:43 ` [dpdk-dev] [PATCH v3 6/6] net/ena: update version to v2.4.0 Michal Krawczyk
2021-07-23 10:24 ` [dpdk-dev] [PATCH v4 0/6] net/ena: v2.4.0 driver update Michal Krawczyk
2021-07-23 10:24 ` [dpdk-dev] [PATCH v4 1/6] net/ena: adjust driver logs Michal Krawczyk
2021-07-23 10:24 ` [dpdk-dev] [PATCH v4 2/6] net/ena: make use of the IO debug build option Michal Krawczyk
2021-07-23 10:24 ` [dpdk-dev] [PATCH v4 3/6] net/ena: trigger reset when Tx prepare fails Michal Krawczyk
2021-07-23 10:24 ` Michal Krawczyk [this message]
2021-07-23 10:24 ` [dpdk-dev] [PATCH v4 5/6] net/ena: rework RSS configuration Michal Krawczyk
2021-07-23 10:24 ` [dpdk-dev] [PATCH v4 6/6] net/ena: update version to v2.4.0 Michal Krawczyk
2021-07-23 15:46 ` [dpdk-dev] [PATCH v4 0/6] net/ena: v2.4.0 driver update Thomas Monjalon
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=20210723102454.12206-5-mk@semihalf.com \
--to=mk@semihalf.com \
--cc=ar@semihalf.com \
--cc=dev@dpdk.org \
--cc=igorch@amazon.com \
--cc=ndagan@amazon.com \
--cc=shaibran@amazon.com \
--cc=shayagr@amazon.com \
--cc=upstream@semihalf.com \
/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).