summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNitin Saxena <nitin.saxena@cavium.com>2018-02-16 11:21:38 +0000
committerDamjan Marion <dmarion.lists@gmail.com>2018-02-19 20:14:51 +0000
commitfa957142beae75e4cf881f7e861cefd97f034a83 (patch)
tree59768ec6ffa1370dab537cf075b880b3eaa0a12c
parentc6969b55e40613479183141c01f057f9253f17a8 (diff)
dpdk: Fix MTU calc for NICs that support mtu<9216
Problem: rte_eth_dev_set_mtu() returns with failure from ThunderX NICVF DPDK PMD driver which supports MTU less than ETHERNET_MAX_PACKET_BYTES. rte_eth_dev_set_mtu() being called twice from dpdk_lib_init(): one via dpdk_device_setup() and second in dpdk_lib_init() itself. Currently dpdk_lib_init() passes vnet_hardware_interface->max_packet_bytes as an argument to rte_eth_dev_set_mtu() without consulting dev_info.max_rx_pktlen. NICs like i4oe, ixgbe can support MTU much greater than 9216 hence its not a problem for those NICS. Fix: This patch calculates dpdk_device->port_conf.rxmode.max_rx_pkt_len, vnet_hardware_interface->max_packet_bytes and MTU by consulting dev_info.max_rx_pktlen. Change-Id: If04bbfae49ee971dac0063ff1835e4a9c3087865 Signed-off-by: Nitin Saxena <nitin.saxena@cavium.com>
-rwxr-xr-xsrc/plugins/dpdk/device/init.c100
1 files changed, 66 insertions, 34 deletions
diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c
index cc30c8dcca1..d719d4b7153 100755
--- a/src/plugins/dpdk/device/init.c
+++ b/src/plugins/dpdk/device/init.c
@@ -180,6 +180,7 @@ static clib_error_t *
dpdk_lib_init (dpdk_main_t * dm)
{
u32 nports;
+ u32 mtu, max_rx_frame;
u32 nb_desc = 0;
int i;
clib_error_t *error;
@@ -466,39 +467,6 @@ dpdk_lib_init (dpdk_main_t * dm)
xd->nb_tx_desc = devconf->num_tx_desc;
}
- /*
- * 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.
- */
- if (ETHERNET_MAX_PACKET_BYTES > dev_info.max_rx_pktlen)
- {
- /*
- * This device does not support the platforms's max frame
- * size. Use it's advertised mru instead.
- */
- xd->port_conf.rxmode.max_rx_pkt_len = dev_info.max_rx_pktlen;
- }
- else
- {
- xd->port_conf.rxmode.max_rx_pkt_len = 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 ((dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4)) &&
- xd->port_conf.rxmode.hw_strip_crc)
- {
- /*
- * Allow additional 4 bytes (for Ethernet FCS). These bytes are
- * stripped by h/w and so will not consume any buffer memory.
- */
- xd->port_conf.rxmode.max_rx_pkt_len += 4;
- }
- }
-
if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
{
f64 now = vlib_time_now (vm);
@@ -583,6 +551,61 @@ 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 > dev_info.max_rx_pktlen)
+ {
+ /*
+ * This device does not support the platforms's max frame
+ * size. Use it's advertised mru instead.
+ */
+ max_rx_frame = dev_info.max_rx_pktlen;
+ mtu = dev_info.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 (dev_info.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 (xd->port_conf.rxmode.hw_strip_crc &&
+ (dev_info.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 (xd->port_conf.rxmode.hw_strip_crc &&
+ (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4)))
+ {
+ 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 (dm->vnet_main, xd->hw_if_index);
xd->vlib_sw_if_index = sw->sw_if_index;
vnet_hw_interface_set_input_node (dm->vnet_main, xd->hw_if_index,
@@ -606,8 +629,17 @@ dpdk_lib_init (dpdk_main_t * dm)
~1);
}
+ /*Get vnet hardware interface */
hi = vnet_get_hw_interface (dm->vnet_main, 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 = max_rx_frame;
+ hi->max_supported_packet_bytes = max_rx_frame;
+ }
+
if (dm->conf->no_tx_checksum_offload == 0)
if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD)
hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD;
@@ -658,7 +690,7 @@ dpdk_lib_init (dpdk_main_t * dm)
hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] =
xd->port_conf.rxmode.max_rx_pkt_len - sizeof (ethernet_header_t);
- rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
+ rte_eth_dev_set_mtu (xd->device_index, mtu);
}
if (nb_desc > dm->conf->num_mbufs)