IB/core: Fix calculation of maximum RoCE MTU
authorParav Pandit <parav@mellanox.com>
Mon, 16 Oct 2017 05:45:16 +0000 (08:45 +0300)
committerDoug Ledford <dledford@redhat.com>
Wed, 18 Oct 2017 16:11:36 +0000 (12:11 -0400)
The original code only took into consideration the largest header
possible after the IB_BTH_BYTES.  This was incorrect, as the largest
possible header size is the largest possible combination of headers we
might run into.  The new code accounts for all possible headers in the
largest possible combination and subtracts that from the MTU to make
sure that all packets will fit on the wire.

Link: https://www.spinics.net/lists/linux-rdma/msg54558.html
Fixes: 3c86aa70bf67 ("RDMA/cm: Add RDMA CM support for IBoE devices")
Signed-off-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Daniel Jurgens <danielj@mellanox.com>
Reported-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
include/rdma/ib_addr.h
include/rdma/ib_pack.h

index ec5008cf5d51d20c2a8813565da2adf4e2feb118..8815989301ab0c66cb45c4bcfc999aea05f7ffc1 100644 (file)
@@ -245,10 +245,11 @@ static inline void rdma_addr_set_dgid(struct rdma_dev_addr *dev_addr, union ib_g
 static inline enum ib_mtu iboe_get_mtu(int mtu)
 {
        /*
-        * reduce IB headers from effective IBoE MTU. 28 stands for
-        * atomic header which is the biggest possible header after BTH
+        * Reduce IB headers from effective IBoE MTU.
         */
-       mtu = mtu - IB_GRH_BYTES - IB_BTH_BYTES - 28;
+       mtu = mtu - (IB_GRH_BYTES + IB_UDP_BYTES + IB_BTH_BYTES +
+                    IB_EXT_XRC_BYTES + IB_EXT_ATOMICETH_BYTES +
+                    IB_ICRC_BYTES);
 
        if (mtu >= ib_mtu_enum_to_int(IB_MTU_4096))
                return IB_MTU_4096;
index 36655899ee028d568257f2b2cc8764b136ab0e20..7ea1382ad0e59b8280834b77221a089e88e0e433 100644 (file)
 #include <uapi/linux/if_ether.h>
 
 enum {
-       IB_LRH_BYTES  = 8,
-       IB_ETH_BYTES  = 14,
-       IB_VLAN_BYTES = 4,
-       IB_GRH_BYTES  = 40,
-       IB_IP4_BYTES  = 20,
-       IB_UDP_BYTES  = 8,
-       IB_BTH_BYTES  = 12,
-       IB_DETH_BYTES = 8
+       IB_LRH_BYTES            = 8,
+       IB_ETH_BYTES            = 14,
+       IB_VLAN_BYTES           = 4,
+       IB_GRH_BYTES            = 40,
+       IB_IP4_BYTES            = 20,
+       IB_UDP_BYTES            = 8,
+       IB_BTH_BYTES            = 12,
+       IB_DETH_BYTES           = 8,
+       IB_EXT_ATOMICETH_BYTES  = 28,
+       IB_EXT_XRC_BYTES        = 4,
+       IB_ICRC_BYTES           = 4
 };
 
 struct ib_field {