From 1cd0e5dd533f4209dde453eaa43215e52cd42985 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Mon, 17 Jan 2022 14:49:17 +0100 Subject: vnet: distinguish between max_frame_size and MTU Type: improvement Change-Id: I3659de6599f402c92e3855e3bf0e5e3388f2bea0 Signed-off-by: Damjan Marion --- src/plugins/dpdk/device/common.c | 63 +++++++++++++++++++++------------------- src/plugins/dpdk/device/dpdk.h | 7 +++++ src/plugins/dpdk/device/format.c | 4 +-- src/plugins/dpdk/device/init.c | 26 +++++++++++++++-- 4 files changed, 65 insertions(+), 35 deletions(-) (limited to 'src/plugins/dpdk') diff --git a/src/plugins/dpdk/device/common.c b/src/plugins/dpdk/device/common.c index 3eca847de79..0f54a616773 100644 --- a/src/plugins/dpdk/device/common.c +++ b/src/plugins/dpdk/device/common.c @@ -61,6 +61,7 @@ dpdk_device_setup (dpdk_device_t * xd) vlib_thread_main_t *tm = vlib_get_thread_main (); vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, xd->sw_if_index); vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, xd->hw_if_index); + u16 buf_sz = vlib_buffer_get_default_data_size (vm); vnet_hw_if_caps_change_t caps = {}; struct rte_eth_dev_info dev_info; struct rte_eth_conf conf = {}; @@ -161,49 +162,51 @@ dpdk_device_setup (dpdk_device_t * xd) #if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) if (rxo & DEV_RX_OFFLOAD_JUMBO_FRAME) - conf.rxmode.max_rx_pkt_len = - clib_min (ETHERNET_MAX_PACKET_BYTES, dev_info.max_rx_pktlen); + { + conf.rxmode.max_rx_pkt_len = dev_info.max_rx_pktlen; + xd->max_supported_frame_size = dev_info.max_rx_pktlen; + mtu = xd->max_supported_frame_size - xd->driver_frame_overhead; + } + else + { + mtu = 1500; + xd->max_supported_frame_size = mtu + xd->driver_frame_overhead; + } #else - dpdk_log_debug ("[%u] min_mtu: %u, max_mtu: %u, min_rx_bufsize: %u, " - "max_rx_pktlen: %u, max_lro_pkt_size: %u", - xd->port_id, dev_info.min_mtu, dev_info.max_mtu, - dev_info.min_rx_bufsize, dev_info.max_rx_pktlen, - dev_info.max_lro_pkt_size); - - mtu = xd->conf.disable_multi_seg ? 2000 : ETHERNET_MAX_PACKET_BYTES; - conf.rxmode.mtu = clib_min (mtu, dev_info.max_rx_pktlen); + if (xd->conf.disable_multi_seg) + xd->max_supported_frame_size = clib_min (dev_info.max_rx_pktlen, buf_sz); + else + xd->max_supported_frame_size = dev_info.max_rx_pktlen; +#endif + + mtu = clib_min (xd->max_supported_frame_size - xd->driver_frame_overhead, + ethernet_main.default_mtu); + mtu = mtu + hi->frame_overhead - xd->driver_frame_overhead; + +#if RTE_VERSION >= RTE_VERSION_NUM(21, 11, 0, 0) + conf.rxmode.mtu = mtu; #endif retry: rv = rte_eth_dev_configure (xd->port_id, xd->conf.n_rx_queues, xd->conf.n_tx_queues, &conf); - if (rv < 0 && conf.intr_conf.rxq) { conf.intr_conf.rxq = 0; goto retry; } - if (rv < 0) - { - dpdk_device_error (xd, "rte_eth_dev_configure", rv); - goto error; - } - - rte_eth_dev_get_mtu (xd->port_id, &mtu); - dpdk_log_debug ("[%u] device default mtu %u", xd->port_id, mtu); +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + rte_eth_dev_set_mtu (xd->port_id, mtu); +#endif - 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); - } + hi->max_frame_size = 0; + vnet_hw_interface_set_max_frame_size (vnm, xd->hw_if_index, + mtu + hi->frame_overhead); + dpdk_log_debug ("[%u] mtu %u max_frame_size %u max max_frame_size %u " + "driver_frame_overhead %u", + xd->port_id, mtu, hi->max_frame_size, + xd->max_supported_frame_size, xd->driver_frame_overhead); vec_validate_aligned (xd->tx_queues, xd->conf.n_tx_queues - 1, CLIB_CACHE_LINE_BYTES); diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index f1cd17da1cd..196f68f9756 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -200,6 +200,13 @@ typedef struct /* mac address */ u8 *default_mac_address; + /* maximum supported max frame size */ + u16 max_supported_frame_size; + + /* due to lack of API to get ethernet max_frame_size we store information + * deducted from device info */ + u8 driver_frame_overhead; + /* error string */ clib_error_t *errors; dpdk_port_conf_t conf; diff --git a/src/plugins/dpdk/device/format.c b/src/plugins/dpdk/device/format.c index 4a4b4110b9f..4ef22729532 100644 --- a/src/plugins/dpdk/device/format.c +++ b/src/plugins/dpdk/device/format.c @@ -199,8 +199,8 @@ format_dpdk_link_status (u8 * s, va_list * args) s = format (s, "%s duplex ", (l->link_duplex == ETH_LINK_FULL_DUPLEX) ? "full" : "half"); - s = format (s, "mtu %d %s\n", hi->max_packet_bytes, promisc ? - " promisc" : ""); + s = format (s, "max-frame-size %d %s\n", hi->max_frame_size, + promisc ? " promisc" : ""); } else s = format (s, "\n"); diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 4faf6290dba..096b8d382fe 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -70,11 +70,15 @@ const struct }; static clib_error_t * -dpdk_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 mtu) +dpdk_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi, + u32 frame_size) { dpdk_main_t *dm = &dpdk_main; dpdk_device_t *xd = vec_elt_at_index (dm->devices, hi->dev_instance); int rv; + u32 mtu; + + mtu = frame_size - xd->driver_frame_overhead; rv = rte_eth_dev_set_mtu (xd->port_id, mtu); @@ -99,7 +103,8 @@ dpdk_set_mtu (vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 mtu) } } else - dpdk_log_debug ("[%u] mtu set to %u", xd->port_id, mtu); + dpdk_log_debug ("[%u] max_frame_size set to %u by setting MTU to %u", + xd->port_id, frame_size, mtu); return 0; } @@ -376,6 +381,21 @@ dpdk_lib_init (dpdk_main_t * dm) xd->conf.rss_hf &= di.flow_type_rss_offloads; } + xd->driver_frame_overhead = + RTE_ETHER_HDR_LEN + 2 * RTE_VLAN_HLEN + RTE_ETHER_CRC_LEN; +#if RTE_VERSION >= RTE_VERSION_NUM(21, 11, 0, 0) + q = di.max_rx_pktlen - di.max_mtu; + + if (q < xd->driver_frame_overhead && q > 0) + xd->driver_frame_overhead = q; + dpdk_log_debug ("[%u] min_mtu: %u, max_mtu: %u, min_rx_bufsize: %u, " + "max_rx_pktlen: %u, max_lro_pkt_size: %u", + xd->port_id, di.min_mtu, di.max_mtu, di.min_rx_bufsize, + di.max_rx_pktlen, di.max_lro_pkt_size); +#endif + dpdk_log_debug ("[%u] driver frame overhead is %u", port_id, + xd->driver_frame_overhead); + /* number of RX and TX tescriptors */ if (devconf->num_rx_desc) xd->conf.n_rx_desc = devconf->num_rx_desc; @@ -397,7 +417,7 @@ dpdk_lib_init (dpdk_main_t * dm) eir.dev_instance = xd->device_index; eir.address = addr; eir.cb.flag_change = dpdk_flag_change; - eir.cb.set_mtu = dpdk_set_mtu; + eir.cb.set_max_frame_size = dpdk_set_max_frame_size; xd->hw_if_index = vnet_eth_register_interface (vnm, &eir); hi = vnet_get_hw_interface (vnm, xd->hw_if_index); hi->numa_node = xd->cpu_socket = (i8) rte_eth_dev_socket_id (port_id); -- cgit 1.2.3-korg