diff options
author | Mohammed Hawari <mohammed@hawari.fr> | 2021-02-10 09:20:51 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2021-03-15 17:31:10 +0000 |
commit | 19ff0c3699342b512c03362b3815df684a661f49 (patch) | |
tree | becd8952d4be2e9d6a18d9450e2e03e155f968b2 /src | |
parent | 4376ab2a926b36c1131588069a8a9cdd2520073d (diff) |
dpdk: implement interrupt mode
Change-Id: I6ababc99ecf559327a4370914580c98d32680175
Type: feature
Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/dpdk/device/common.c | 77 | ||||
-rw-r--r-- | src/plugins/dpdk/device/device.c | 20 | ||||
-rw-r--r-- | src/plugins/dpdk/device/dpdk.h | 25 | ||||
-rw-r--r-- | src/plugins/dpdk/device/init.c | 6 |
4 files changed, 116 insertions, 12 deletions
diff --git a/src/plugins/dpdk/device/common.c b/src/plugins/dpdk/device/common.c index e9b033ec1af..a837714e75b 100644 --- a/src/plugins/dpdk/device/common.c +++ b/src/plugins/dpdk/device/common.c @@ -16,6 +16,8 @@ #include <vnet/vnet.h> #include <vppinfra/vec.h> #include <vppinfra/format.h> +#include <vppinfra/file.h> +#include <vlib/unix/unix.h> #include <assert.h> #include <vnet/ip/ip.h> @@ -160,6 +162,79 @@ error: sw->flags |= VNET_SW_INTERFACE_FLAG_ERROR; } +static clib_error_t * +dpdk_rx_read_ready (clib_file_t *uf) +{ + vnet_main_t *vnm = vnet_get_main (); + dpdk_main_t *dm = &dpdk_main; + u32 qidx = uf->private_data; + vnet_hw_if_rx_queue_t *rxq = vnet_hw_if_get_rx_queue (vnm, qidx); + dpdk_device_t *xd = vec_elt_at_index (dm->devices, rxq->dev_instance); + + u64 b; + CLIB_UNUSED (ssize_t size) = read (uf->file_descriptor, &b, sizeof (b)); + if (rxq->mode != VNET_HW_IF_RX_MODE_POLLING) + { + vnet_hw_if_rx_queue_set_int_pending (vnm, uf->private_data); + rte_eth_dev_rx_intr_enable (xd->port_id, rxq->queue_id); + } + + return 0; +} + +static void +dpdk_setup_interrupts (dpdk_device_t *xd) +{ + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, xd->hw_if_index); + if (!hi) + return; + + if (!xd->port_conf.intr_conf.rxq) + return; + + /* Probe for interrupt support */ + if (rte_eth_dev_rx_intr_enable (xd->port_id, 0)) + { + dpdk_log_info ("probe for interrupt mode for device %U. Failed.\n", + format_dpdk_device_name, xd->port_id); + } + else + { + xd->flags |= DPDK_DEVICE_FLAG_INT_SUPPORTED; + rte_eth_dev_rx_intr_disable (xd->port_id, 0); + dpdk_log_info ("Probe for interrupt mode for device %U. Success.\n", + format_dpdk_device_name, xd->port_id); + } + + if (xd->flags & DPDK_DEVICE_FLAG_INT_SUPPORTED) + { + hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE; + for (int q = 0; q < xd->rx_q_used; q++) + { + dpdk_rx_queue_t *rxq = vec_elt_at_index (xd->rx_queues, q); + clib_file_t f = { 0 }; + rxq->efd = rte_eth_dev_rx_intr_ctl_q_get_fd (xd->port_id, q); + if (rxq->efd < 0) + { + xd->flags &= ~DPDK_DEVICE_FLAG_INT_SUPPORTED; + hi->flags &= ~VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE; + break; + } + f.read_function = dpdk_rx_read_ready; + f.flags = UNIX_FILE_EVENT_EDGE_TRIGGERED; + f.file_descriptor = rxq->efd; + f.private_data = rxq->queue_index; + f.description = + format (0, "%U queue %u", format_dpdk_device_name, xd->port_id, q); + rxq->clib_file_index = clib_file_add (&file_main, &f); + vnet_hw_if_set_rx_queue_file_index (vnm, rxq->queue_index, + rxq->clib_file_index); + } + } + vnet_hw_if_update_runtime_data (vnm, xd->hw_if_index); +} + void dpdk_device_start (dpdk_device_t * xd) { @@ -176,6 +251,8 @@ dpdk_device_start (dpdk_device_t * xd) return; } + dpdk_setup_interrupts (xd); + if (xd->default_mac_address) rv = rte_eth_dev_default_mac_addr_set (xd->port_id, (void *) xd->default_mac_address); diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index 6466b443633..95678e9b0e2 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -694,6 +694,25 @@ done: return err; } +static clib_error_t * +dpdk_interface_rx_mode_change (vnet_main_t *vnm, u32 hw_if_index, u32 qid, + vnet_hw_if_rx_mode mode) +{ + dpdk_main_t *xm = &dpdk_main; + vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index); + dpdk_device_t *xd = vec_elt_at_index (xm->devices, hw->dev_instance); + int rv = 0; + if (!(xd->flags & DPDK_DEVICE_FLAG_INT_SUPPORTED)) + return clib_error_return (0, "unsupported op (is the interface up?)", rv); + if (mode == VNET_HW_IF_RX_MODE_POLLING) + rv = rte_eth_dev_rx_intr_disable (xd->port_id, qid); + else + rv = rte_eth_dev_rx_intr_enable (xd->port_id, qid); + if (rv) + return clib_error_return (0, "dpdk_interface_rx_mode_change err %d", rv); + return 0; +} + /* *INDENT-OFF* */ VNET_DEVICE_CLASS (dpdk_device_class) = { .name = "dpdk", @@ -711,6 +730,7 @@ VNET_DEVICE_CLASS (dpdk_device_class) = { .format_flow = format_dpdk_flow, .flow_ops_function = dpdk_flow_ops_fn, .set_rss_queues_function = dpdk_interface_set_rss_queues, + .rx_mode_change_function = dpdk_interface_rx_mode_change, }; /* *INDENT-ON* */ diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index be8c47b5128..e63b2b7c56b 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -128,17 +128,18 @@ typedef enum typedef uint16_t dpdk_portid_t; -#define foreach_dpdk_device_flags \ - _( 0, ADMIN_UP, "admin-up") \ - _( 1, PROMISC, "promisc") \ - _( 2, PMD, "pmd") \ - _( 3, PMD_INIT_FAIL, "pmd-init-fail") \ - _( 4, MAYBE_MULTISEG, "maybe-multiseg") \ - _( 5, HAVE_SUBIF, "subif") \ - _( 9, TX_OFFLOAD, "tx-offload") \ - _(10, INTEL_PHDR_CKSUM, "intel-phdr-cksum") \ - _(11, RX_FLOW_OFFLOAD, "rx-flow-offload") \ - _(12, RX_IP4_CKSUM, "rx-ip4-cksum") +#define foreach_dpdk_device_flags \ + _ (0, ADMIN_UP, "admin-up") \ + _ (1, PROMISC, "promisc") \ + _ (2, PMD, "pmd") \ + _ (3, PMD_INIT_FAIL, "pmd-init-fail") \ + _ (4, MAYBE_MULTISEG, "maybe-multiseg") \ + _ (5, HAVE_SUBIF, "subif") \ + _ (9, TX_OFFLOAD, "tx-offload") \ + _ (10, INTEL_PHDR_CKSUM, "intel-phdr-cksum") \ + _ (11, RX_FLOW_OFFLOAD, "rx-flow-offload") \ + _ (12, RX_IP4_CKSUM, "rx-ip4-cksum") \ + _ (13, INT_SUPPORTED, "int-supported") enum { @@ -166,6 +167,8 @@ typedef struct CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); u8 buffer_pool_index; u32 queue_index; + int efd; + uword clib_file_index; } dpdk_rx_queue_t; typedef struct diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 2874167665f..78374af4b0f 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -470,6 +470,7 @@ dpdk_lib_init (dpdk_main_t * dm) DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM; } + xd->port_conf.intr_conf.rxq = 1; break; case VNET_DPDK_PMD_CXGBE: @@ -493,6 +494,7 @@ dpdk_lib_init (dpdk_main_t * dm) DPDK_DEVICE_FLAG_TX_OFFLOAD | DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM; } + /*xd->port_conf.intr_conf.rxq = 1;*/ break; /* iAVF */ @@ -512,7 +514,8 @@ dpdk_lib_init (dpdk_main_t * dm) DPDK_DEVICE_FLAG_TX_OFFLOAD | DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM; } - break; + xd->port_conf.intr_conf.rxq = 1; + break; case VNET_DPDK_PMD_THUNDERX: xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF; @@ -528,6 +531,7 @@ dpdk_lib_init (dpdk_main_t * dm) case VNET_DPDK_PMD_ENA: xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF; xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_SCATTER; + xd->port_conf.intr_conf.rxq = 1; break; case VNET_DPDK_PMD_DPAA2: |