From 632ea7089f404186cc7209bdfb2644b24593a2df Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Wed, 5 Jan 2022 23:25:12 +0100 Subject: [PATCH] dpdk: cleanup MTU handling Type: improvement Change-Id: I4b929693f3671be8ee63a58afcbac75a27d99d57 Signed-off-by: Damjan Marion --- src/plugins/dpdk/device/common.c | 23 ++++++++- src/plugins/dpdk/device/dpdk.h | 2 + src/plugins/dpdk/device/init.c | 105 +++------------------------------------ 3 files changed, 31 insertions(+), 99 deletions(-) diff --git a/src/plugins/dpdk/device/common.c b/src/plugins/dpdk/device/common.c index f77e377e14c..c32382a55c6 100644 --- a/src/plugins/dpdk/device/common.c +++ b/src/plugins/dpdk/device/common.c @@ -48,6 +48,7 @@ dpdk_device_setup (dpdk_device_t * xd) vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, xd->hw_if_index); struct rte_eth_dev_info dev_info; u64 bitmap; + u16 mtu; int rv; int j; @@ -89,6 +90,12 @@ dpdk_device_setup (dpdk_device_t * xd) xd->port_conf.rxmode.offloads ^= bitmap; } + if (xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) + xd->port_conf.rxmode.max_rx_pkt_len = + clib_min (ETHERNET_MAX_PACKET_BYTES, dev_info.max_rx_pktlen); + else + xd->port_conf.rxmode.max_rx_pkt_len = 0; + rv = rte_eth_dev_configure (xd->port_id, xd->conf.n_rx_queues, xd->conf.n_tx_queues, &xd->port_conf); @@ -98,6 +105,21 @@ dpdk_device_setup (dpdk_device_t * xd) goto error; } + rte_eth_dev_get_mtu (xd->port_id, &mtu); + dpdk_log_debug ("[%u] device default mtu %u", xd->port_id, mtu); + + hi->max_supported_packet_bytes = mtu; + if (hi->max_packet_bytes > mtu) + { + vnet_hw_interface_set_mtu (vnm, xd->hw_if_index, mtu); + } + else + { + rte_eth_dev_set_mtu (xd->port_id, hi->max_packet_bytes); + dpdk_log_debug ("[%u] port mtu set to %u", xd->port_id, + hi->max_packet_bytes); + } + vec_validate_aligned (xd->tx_queues, xd->conf.n_tx_queues - 1, CLIB_CACHE_LINE_BYTES); for (j = 0; j < xd->conf.n_tx_queues; j++) @@ -144,7 +166,6 @@ dpdk_device_setup (dpdk_device_t * xd) if (vec_len (xd->errors)) goto error; - rte_eth_dev_set_mtu (xd->port_id, hi->max_packet_bytes); xd->buffer_flags = (VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_EXT_HDR_VALID); diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index 3026734c39f..ff2bf6f9c50 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -420,6 +420,8 @@ typedef enum vlib_log(VLIB_LOG_LEVEL_NOTICE, dpdk_main.log_default, __VA_ARGS__) #define dpdk_log_info(...) \ vlib_log(VLIB_LOG_LEVEL_INFO, dpdk_main.log_default, __VA_ARGS__) +#define dpdk_log_debug(...) \ + vlib_log (VLIB_LOG_LEVEL_DEBUG, dpdk_main.log_default, __VA_ARGS__) void dpdk_update_link_state (dpdk_device_t * xd, f64 now); diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 1ee03323d61..fd1c9115954 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -97,8 +97,13 @@ dpdk_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags) xd->flags |= DPDK_DEVICE_FLAG_PROMISC; break; case ETHERNET_INTERFACE_FLAG_MTU: - xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes; - dpdk_device_setup (xd); + if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) + rte_eth_dev_stop (xd->port_id); + rte_eth_dev_set_mtu (xd->port_id, hi->max_packet_bytes); + if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) + rte_eth_dev_start (xd->port_id); + dpdk_log_debug ("[%u] mtu changed to %u", xd->port_id, + hi->max_packet_bytes); return 0; default: return ~0; @@ -115,12 +120,6 @@ dpdk_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags) return old; } -static int -dpdk_port_crc_strip_enabled (dpdk_device_t * xd) -{ - return !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC); -} - /* The function check_l3cache helps check if Level 3 cache exists or not on current CPUs return value 1: exist. return value 0: not exist. @@ -176,7 +175,6 @@ dpdk_lib_init (dpdk_main_t * dm) { vnet_main_t *vnm = vnet_get_main (); u32 nports; - u32 mtu, max_rx_frame; u16 port_id; clib_error_t *error; vlib_main_t *vm = vlib_get_main (); @@ -652,80 +650,6 @@ dpdk_lib_init (dpdk_main_t * dm) if (error) return error; - /* - * Ensure default mtu is not > the mtu read from the hardware. - * Otherwise rte_eth_dev_configure() will fail and the port will - * not be available. - * Calculate max_frame_size and mtu supported by NIC - */ - if (ETHERNET_MAX_PACKET_BYTES > di.max_rx_pktlen) - { - /* - * This device does not support the platforms's max frame - * size. Use it's advertised mru instead. - */ - max_rx_frame = di.max_rx_pktlen; - mtu = di.max_rx_pktlen - sizeof (ethernet_header_t); - } - else - { - /* VPP treats MTU and max_rx_pktlen both equal to - * ETHERNET_MAX_PACKET_BYTES, if dev_info.max_rx_pktlen >= - * ETHERNET_MAX_PACKET_BYTES + sizeof(ethernet_header_t) - */ - if (di.max_rx_pktlen >= - (ETHERNET_MAX_PACKET_BYTES + sizeof (ethernet_header_t))) - { - mtu = ETHERNET_MAX_PACKET_BYTES; - max_rx_frame = ETHERNET_MAX_PACKET_BYTES; - - /* - * Some platforms do not account for Ethernet FCS (4 bytes) in - * MTU calculations. To interop with them increase mru but only - * if the device's settings can support it. - */ - if (dpdk_port_crc_strip_enabled (xd) && - (di.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + - sizeof (ethernet_header_t) + 4))) - { - max_rx_frame += 4; - } - } - else - { - max_rx_frame = ETHERNET_MAX_PACKET_BYTES; - mtu = ETHERNET_MAX_PACKET_BYTES - sizeof (ethernet_header_t); - - if (dpdk_port_crc_strip_enabled (xd) && - (di.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4))) - { - max_rx_frame += 4; - } - } - } - - if (xd->pmd == VNET_DPDK_PMD_FAILSAFE) - { - /* failsafe device numerables are reported with active device only, - * need to query the mtu for current device setup to overwrite - * reported value. - */ - uint16_t dev_mtu; - if (!rte_eth_dev_get_mtu (port_id, &dev_mtu)) - { - mtu = dev_mtu; - max_rx_frame = mtu + sizeof (ethernet_header_t); - - if (dpdk_port_crc_strip_enabled (xd)) - { - max_rx_frame += 4; - } - } - } - - /*Set port rxmode config */ - xd->port_conf.rxmode.max_rx_pkt_len = max_rx_frame; - sw = vnet_get_hw_sw_interface (vnm, xd->hw_if_index); xd->sw_if_index = sw->sw_if_index; vnet_hw_if_set_input_node (vnm, xd->hw_if_index, dpdk_input_node.index); @@ -754,12 +678,8 @@ dpdk_lib_init (dpdk_main_t * dm) /*Get vnet hardware interface */ hi = vnet_get_hw_interface (vnm, xd->hw_if_index); - /*Override default max_packet_bytes and max_supported_bytes set in - * ethernet_register_interface() above*/ if (hi) { - hi->max_packet_bytes = mtu; - hi->max_supported_packet_bytes = max_rx_frame; hi->numa_node = xd->cpu_socket; /* Indicate ability to support L3 DMAC filtering and @@ -819,17 +739,6 @@ dpdk_lib_init (dpdk_main_t * dm) dpdk_log_err ("setup failed for device %U. Errors:\n %U", format_dpdk_device_name, port_id, format_dpdk_device_errors, xd); - - if (hi) - hi->max_packet_bytes = - xd->port_conf.rxmode.max_rx_pkt_len - sizeof (ethernet_header_t); - else - dpdk_log_warn ("hi NULL"); - - if (xd->conf.no_multi_seg) - mtu = mtu > ETHER_MAX_LEN ? ETHER_MAX_LEN : mtu; - - rte_eth_dev_set_mtu (xd->port_id, mtu); } return 0; -- 2.16.6