From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT: drivers/infiniband/ulp/ipoib/ipoib_cm.c

Change-Id: I931ba64b05dedee321abcb58730ef8fc3c5c413a
---
 drivers/infiniband/ulp/ipoib/ipoib_cm.c | 47 +++++++++++++++++++++----
 1 file changed, 40 insertions(+), 7 deletions(-)

--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -39,7 +39,9 @@
 #include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
 #include <linux/sched/signal.h>
+#ifdef HAVE_MEMALLOC_NOIO_SAVE
 #include <linux/sched/mm.h>
+#endif
 
 #include "ipoib.h"
 
@@ -466,7 +468,11 @@ static int ipoib_cm_req_handler(struct i
 		goto err_qp;
 	}
 
+#ifdef HAVE_GET_RANDOM_U32
+	psn = get_random_u32() & 0xffffff;
+#else
 	psn = prandom_u32() & 0xffffff;
+#endif
 	ret = ipoib_cm_modify_rx_qp(dev, cm_id, p->qp, psn);
 	if (ret)
 		goto err_modify;
@@ -1079,7 +1085,11 @@ static struct ib_qp *ipoib_cm_create_tx_
 		.sq_sig_type		= IB_SIGNAL_ALL_WR,
 		.qp_type		= IB_QPT_RC,
 		.qp_context		= tx,
+#ifdef HAVE_MEMALLOC_NOIO_SAVE
 		.create_flags		= 0
+#else
+		.create_flags		= IB_QP_CREATE_USE_GFP_NOIO
+#endif
 	};
 	struct ib_qp *tx_qp;
 
@@ -1088,6 +1098,12 @@ static struct ib_qp *ipoib_cm_create_tx_
 					      MAX_SKB_FRAGS + 1);
 
 	tx_qp = ib_create_qp(priv->pd, &attr);
+#ifndef HAVE_MEMALLOC_NOIO_SAVE
+	if (PTR_ERR(tx_qp)) {
+		attr.create_flags &= ~IB_QP_CREATE_USE_GFP_NOIO;
+		tx_qp = ib_create_qp(priv->pd, &attr);
+	}
+#endif
 	tx->max_send_sge = attr.cap.max_send_sge;
 	return tx_qp;
 }
@@ -1154,19 +1170,30 @@ static int ipoib_cm_tx_init(struct ipoib
 			    struct sa_path_rec *pathrec)
 {
 	struct ipoib_dev_priv *priv = ipoib_priv(p->dev);
-	unsigned int noio_flag;
-	int ret;
+#ifdef HAVE_MEMALLOC_NOIO_SAVE
+       unsigned int noio_flag;
+#endif
+       int ret;
 
-	noio_flag = memalloc_noio_save();
-	p->tx_ring = vzalloc(array_size(priv->sendq_size, sizeof(*p->tx_ring)));
+#ifdef HAVE_MEMALLOC_NOIO_SAVE
+       noio_flag = memalloc_noio_save();
+       p->tx_ring = vzalloc(array_size(priv->sendq_size, sizeof(*p->tx_ring)));
+#else
+	p->tx_ring = __vmalloc(priv->sendq_size * sizeof(*p->tx_ring),
+			       GFP_NOIO, PAGE_KERNEL);
+#endif
 	if (!p->tx_ring) {
-		memalloc_noio_restore(noio_flag);
+#ifdef HAVE_MEMALLOC_NOIO_SAVE
+	       	memalloc_noio_restore(noio_flag);
+#endif
 		ret = -ENOMEM;
 		goto err_tx;
 	}
 
 	p->qp = ipoib_cm_create_tx_qp(p->dev, p);
-	memalloc_noio_restore(noio_flag);
+#ifdef HAVE_MEMALLOC_NOIO_SAVE
+       memalloc_noio_restore(noio_flag);
+#endif
 	if (IS_ERR(p->qp)) {
 		ret = PTR_ERR(p->qp);
 		ipoib_warn(priv, "failed to create tx qp: %d\n", ret);
@@ -1630,7 +1657,9 @@ int ipoib_cm_dev_init(struct net_device
 {
 	struct ipoib_dev_priv *priv = ipoib_priv(dev);
 	int max_srq_sge, i;
+#ifdef HAVE_DEV_ADDR_MOD
 	u8 addr;
+#endif
 
 	INIT_LIST_HEAD(&priv->cm.passive_ids);
 	INIT_LIST_HEAD(&priv->cm.reap_list);
@@ -1684,8 +1713,12 @@ int ipoib_cm_dev_init(struct net_device
 		}
 	}
 
+#ifdef HAVE_DEV_ADDR_MOD
 	addr = IPOIB_FLAGS_RC;
 	dev_addr_mod(dev, 0, &addr, 1);
+#else
+	priv->dev->dev_addr[0] = IPOIB_FLAGS_RC;
+#endif
 	return 0;
 }
 
