aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2021-03-25 15:55:02 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2021-03-25 15:55:37 +0000
commit4e38478c595a9e6225b525890d7ee269a203c200 (patch)
treec50bf042b5674386a23bae28a77c20c784e7e1c4
parent31070b5bc77a499009a835650eb9d4bf2eceaa15 (diff)
downloadsrc-4e38478c595a9e6225b525890d7ee269a203c200.tar.gz
src-4e38478c595a9e6225b525890d7ee269a203c200.zip
ipoib: Fix incorrectly computed IPOIB_CM_RX_SG value.
The computed IPOIB_CM_RX_SG is too small. It doesn't account for fallback to mbuf clusters when jumbo frames are not available and it also doesn't account for the packet header and trailer mbuf. This causes a memory overwrite situation when IPOIB_CM is configured. While at it add a kernel assert to ensure the mapping array is not overwritten. PR: 254474 MFC after: 1 week Sponsored by: Mellanox Technologies // NVIDIA Networking
-rw-r--r--sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h7
-rw-r--r--sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c2
-rw-r--r--sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c7
3 files changed, 8 insertions, 8 deletions
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h
index 8a2b3333abb5..eb1cb87dc888 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -117,12 +117,11 @@ enum {
IPOIB_ENCAP_LEN = 4,
IPOIB_HEADER_LEN = IPOIB_ENCAP_LEN + INFINIBAND_ALEN,
IPOIB_UD_MAX_MTU = 4 * 1024,
-// IPOIB_UD_RX_SG = (IPOIB_UD_MAX_MTU / MJUMPAGESIZE),
- IPOIB_UD_RX_SG = 2,
+ IPOIB_UD_RX_SG = 2, /* packet header and one cluster */
IPOIB_UD_TX_SG = (IPOIB_UD_MAX_MTU / MCLBYTES) + 2,
IPOIB_CM_MAX_MTU = (64 * 1024),
IPOIB_CM_TX_SG = (IPOIB_CM_MAX_MTU / MCLBYTES) + 2,
- IPOIB_CM_RX_SG = (IPOIB_CM_MAX_MTU / MJUMPAGESIZE),
+ IPOIB_CM_RX_SG = (IPOIB_CM_MAX_MTU / MCLBYTES) + 2,
IPOIB_RX_RING_SIZE = 256,
IPOIB_TX_RING_SIZE = 128,
IPOIB_MAX_RX_SG = MAX(IPOIB_CM_RX_SG, IPOIB_UD_RX_SG),
@@ -529,7 +528,7 @@ int ipoib_poll_tx(struct ipoib_dev_priv *priv, bool do_start);
void ipoib_dma_unmap_rx(struct ipoib_dev_priv *priv, struct ipoib_rx_buf *rx_req);
void ipoib_dma_mb(struct ipoib_dev_priv *priv, struct mbuf *mb, unsigned int length);
-struct mbuf *ipoib_alloc_map_mb(struct ipoib_dev_priv *priv, struct ipoib_rx_buf *rx_req, int align, int size);
+struct mbuf *ipoib_alloc_map_mb(struct ipoib_dev_priv *priv, struct ipoib_rx_buf *rx_req, int align, int size, int max_frags);
void ipoib_set_ethtool_ops(struct ifnet *dev);
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 50c9a4f305e9..b61ebfd1495a 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -153,7 +153,7 @@ static struct mbuf *
ipoib_cm_alloc_rx_mb(struct ipoib_dev_priv *priv, struct ipoib_cm_rx_buf *rx_req)
{
return ipoib_alloc_map_mb(priv, (struct ipoib_rx_buf *)rx_req,
- sizeof(struct ipoib_pseudoheader), priv->cm.max_cm_mtu);
+ sizeof(struct ipoib_pseudoheader), priv->cm.max_cm_mtu, IPOIB_CM_RX_SG);
}
static void ipoib_cm_free_rx_ring(struct ipoib_dev_priv *priv,
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index cb52e3db75a4..a5db9a256204 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -112,7 +112,7 @@ ipoib_dma_mb(struct ipoib_dev_priv *priv, struct mbuf *mb, unsigned int length)
struct mbuf *
ipoib_alloc_map_mb(struct ipoib_dev_priv *priv, struct ipoib_rx_buf *rx_req,
- int align, int size)
+ int align, int size, int max_frags)
{
struct mbuf *mb, *m;
int i, j;
@@ -122,6 +122,8 @@ ipoib_alloc_map_mb(struct ipoib_dev_priv *priv, struct ipoib_rx_buf *rx_req,
if (mb == NULL)
return (NULL);
for (i = 0, m = mb; m != NULL; m = m->m_next, i++) {
+ MPASS(i < max_frags);
+
m->m_len = M_SIZE(m) - align;
m->m_data += align;
align = 0;
@@ -174,9 +176,8 @@ static int ipoib_ib_post_receive(struct ipoib_dev_priv *priv, int id)
static struct mbuf *
ipoib_alloc_rx_mb(struct ipoib_dev_priv *priv, int id)
{
-
return ipoib_alloc_map_mb(priv, &priv->rx_ring[id],
- 0, priv->max_ib_mtu + IB_GRH_BYTES);
+ 0, priv->max_ib_mtu + IB_GRH_BYTES, IPOIB_UD_RX_SG);
}
static int ipoib_ib_post_receives(struct ipoib_dev_priv *priv)