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

Change-Id: I1993203fe38cac08d9afdc90491564162237eb4d
---
 drivers/infiniband/core/cma.c | 97 +++++++++++++++++++++++++++++++++--
 1 file changed, 92 insertions(+), 5 deletions(-)

--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -43,6 +43,9 @@
 MODULE_AUTHOR("Sean Hefty");
 MODULE_DESCRIPTION("Generic RDMA CM Agent");
 MODULE_LICENSE("Dual BSD/GPL");
+#ifdef RETPOLINE_MLNX
+MODULE_INFO(retpoline, "Y");
+#endif
 
 #define CMA_CM_RESPONSE_TIMEOUT 22
 #define CMA_MAX_CM_RETRIES 15
@@ -242,6 +245,7 @@ static struct rdma_bind_list *cma_ps_fin
 	struct xarray *xa = cma_pernet_xa(net, ps);
 
 	return xa_load(xa, snum);
+ 
 }
 
 static void cma_ps_remove(struct net *net, enum rdma_ucm_port_space ps,
@@ -593,7 +597,9 @@ static void _cma_attach_to_dev(struct rd
 		rdma_node_get_transport(cma_dev->device->node_type);
 	list_add_tail(&id_priv->device_item, &cma_dev->id_list);
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_id_attach(id_priv, cma_dev->device);
+#endif
 }
 
 static void cma_attach_to_dev(struct rdma_id_private *id_priv,
@@ -732,7 +738,10 @@ cma_validate_port(struct ib_device *devi
 	}
 
 	sgid_attr = rdma_find_gid_by_port(device, gid, gid_type, port, ndev);
-	dev_put(ndev);
+#ifndef HAVE_NETDEV_PUT
+	if (ndev)
+#endif
+ 	dev_put(ndev);
 out:
 	return sgid_attr;
 }
@@ -1127,12 +1136,16 @@ int rdma_create_qp(struct rdma_cm_id *id
 	id->qp = qp;
 	id_priv->qp_num = qp->qp_num;
 	id_priv->srq = (qp->srq != NULL);
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_qp_create(id_priv, pd, qp_init_attr, 0);
+#endif
 	return 0;
 out_destroy:
 	ib_destroy_qp(qp);
 out_err:
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_qp_create(id_priv, pd, qp_init_attr, ret);
+#endif
 	return ret;
 }
 EXPORT_SYMBOL(rdma_create_qp);
@@ -1142,7 +1155,9 @@ void rdma_destroy_qp(struct rdma_cm_id *
 	struct rdma_id_private *id_priv;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_qp_destroy(id_priv);
+#endif
 	mutex_lock(&id_priv->qp_mutex);
 	ib_destroy_qp(id_priv->id.qp);
 	id_priv->id.qp = NULL;
@@ -1592,6 +1607,7 @@ static bool validate_ipv4_net_dev(struct
 	fl4.saddr = saddr;
 
 	rcu_read_lock();
+
 	err = fib_lookup(dev_net(net_dev), &fl4, &res, 0);
 	ret = err == 0 && FIB_RES_DEV(res) == net_dev;
 	rcu_read_unlock();
@@ -1794,13 +1810,14 @@ static struct rdma_id_private *cma_find_
 		const struct net_device *net_dev)
 {
 	struct rdma_id_private *id_priv, *id_priv_dev;
+	COMPAT_HL_NODE
 
 	lockdep_assert_held(&lock);
 
 	if (!bind_list)
 		return ERR_PTR(-EINVAL);
 
-	hlist_for_each_entry(id_priv, &bind_list->owners, node) {
+	compat_hlist_for_each_entry(id_priv, &bind_list->owners, node) {
 		if (cma_match_private_data(id_priv, ib_event->private_data)) {
 			if (id_priv->id.device == cm_id->device &&
 			    cma_match_net_dev(&id_priv->id, net_dev, req))
@@ -2011,6 +2028,9 @@ static void destroy_mc(struct rdma_id_pr
 					  gid_type);
 			cma_igmp_send(ndev, &mgid, false);
 		}
+#ifndef HAVE_NETDEV_PUT
+		if (ndev)
+#endif
 		dev_put(ndev);
 
 		cancel_work_sync(&mc->iboe_join.work);
@@ -2074,7 +2094,9 @@ static void destroy_id_handler_unlock(st
 	enum rdma_cm_state state;
 	unsigned long flags;
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_id_destroy(id_priv);
+#endif
 
 	/*
 	 * Setting the state to destroyed under the handler mutex provides a
@@ -2113,7 +2135,9 @@ static int cma_rep_recv(struct rdma_id_p
 	if (ret)
 		goto reject;
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_send_rtu(id_priv);
+#endif
 	ret = ib_send_cm_rtu(id_priv->cm_id.ib, NULL, 0);
 	if (ret)
 		goto reject;
@@ -2122,7 +2146,9 @@ static int cma_rep_recv(struct rdma_id_p
 reject:
 	pr_debug_ratelimited("RDMA CM: CONNECT_ERROR: failed to handle reply. status %d\n", ret);
 	cma_modify_qp_err(id_priv);
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_send_rej(id_priv);
+#endif
 	ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED,
 		       NULL, 0, NULL, 0);
 	return ret;
@@ -2152,9 +2178,13 @@ static int cma_cm_event_handler(struct r
 
 	lockdep_assert_held(&id_priv->handler_mutex);
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_event_handler(id_priv, event);
+#endif
 	ret = id_priv->id.event_handler(&id_priv->id, event);
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_event_done(id_priv, event, ret);
+#endif
 	return ret;
 }
 
@@ -2183,7 +2213,9 @@ static int cma_ib_handler(struct ib_cm_i
 	case IB_CM_REP_RECEIVED:
 		if (state == RDMA_CM_CONNECT &&
 		    (id_priv->id.qp_type != IB_QPT_UD)) {
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 			trace_cm_send_mra(id_priv);
+#endif
 			ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
 		}
 		if (id_priv->id.qp) {
@@ -2394,7 +2426,9 @@ static int cma_ib_req_handler(struct ib_
 	if (IS_ERR(listen_id))
 		return PTR_ERR(listen_id);
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_req_handler(listen_id, ib_event->event);
+#endif
 	if (!cma_ib_check_req_qp_type(&listen_id->id, ib_event)) {
 		ret = -EINVAL;
 		goto net_dev_put;
@@ -2445,7 +2479,9 @@ static int cma_ib_req_handler(struct ib_
 
 	if (READ_ONCE(conn_id->state) == RDMA_CM_CONNECT &&
 	    conn_id->id.qp_type != IB_QPT_UD) {
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 		trace_cm_send_mra(cm_id->context);
+#endif
 		ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
 	}
 	mutex_unlock(&conn_id->handler_mutex);
@@ -2454,6 +2490,9 @@ err_unlock:
 	mutex_unlock(&listen_id->handler_mutex);
 
 net_dev_put:
+#ifndef HAVE_NETDEV_PUT
+	if (net_dev)
+#endif
 	dev_put(net_dev);
 
 	return ret;
@@ -2688,7 +2727,9 @@ static int cma_listen_handler(struct rdm
 
 	id->context = id_priv->id.context;
 	id->event_handler = id_priv->id.event_handler;
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_event_handler(id_priv, event);
+#endif
 	return id_priv->id.event_handler(id, event);
 }
 
@@ -3207,9 +3248,17 @@ struct iboe_prio_tc_map {
 };
 
 static int get_lower_vlan_dev_tc(struct net_device *dev,
-				 struct netdev_nested_priv *priv)
+#ifdef HAVE_NETDEV_NESTED_PRIV_STRUCT
+					struct netdev_nested_priv *priv)
+#else
+					void *data)
+#endif
 {
+#ifdef HAVE_NETDEV_NESTED_PRIV_STRUCT
 	struct iboe_prio_tc_map *map = (struct iboe_prio_tc_map *)priv->data;
+#else
+	struct iboe_prio_tc_map *map = data;
+#endif
 
 	if (is_vlan_dev(dev))
 		map->output_tc = get_vlan_ndev_tc(dev, map->input_prio);
@@ -3228,18 +3277,26 @@ static int iboe_tos_to_sl(struct net_dev
 {
 	struct iboe_prio_tc_map prio_tc_map = {};
 	int prio = rt_tos2priority(tos);
+#ifdef HAVE_NETDEV_NESTED_PRIV_STRUCT
 	struct netdev_nested_priv priv;
+#endif
 
 	/* If VLAN device, get it directly from the VLAN netdev */
 	if (is_vlan_dev(ndev))
 		return get_vlan_ndev_tc(ndev, prio);
 
 	prio_tc_map.input_prio = prio;
+#ifdef HAVE_NETDEV_NESTED_PRIV_STRUCT
 	priv.data = (void *)&prio_tc_map;
+#endif
 	rcu_read_lock();
 	netdev_walk_all_lower_dev_rcu(ndev,
 				      get_lower_vlan_dev_tc,
+#ifdef HAVE_NETDEV_NESTED_PRIV_STRUCT
 				      &priv);
+#else
+				      &prio_tc_map);
+#endif
 	rcu_read_unlock();
 	/* If map is found from lower device, use it; Otherwise
 	 * continue with the current netdevice to get priority to tc map.
@@ -3680,10 +3737,11 @@ static int cma_port_is_unique(struct rdm
 	struct sockaddr  *daddr = cma_dst_addr(id_priv);
 	struct sockaddr  *saddr = cma_src_addr(id_priv);
 	__be16 dport = cma_port(daddr);
+	COMPAT_HL_NODE
 
 	lockdep_assert_held(&lock);
 
-	hlist_for_each_entry(cur_id, &bind_list->owners, node) {
+	compat_hlist_for_each_entry(cur_id, &bind_list->owners, node) {
 		struct sockaddr  *cur_daddr = cma_dst_addr(cur_id);
 		struct sockaddr  *cur_saddr = cma_src_addr(cur_id);
 		__be16 cur_dport = cma_port(cur_daddr);
@@ -3726,7 +3784,11 @@ static int cma_alloc_any_port(enum rdma_
 
 	inet_get_local_port_range(net, &low, &high);
 	remaining = (high - low) + 1;
+#ifdef HAVE_GET_RANDOM_U32_INCLUSIVE
 	rover = get_random_u32_inclusive(low, remaining + low - 1);
+#else
+	rover = prandom_u32_max(remaining) + low;
+#endif
 retry:
 	if (last_used_port != rover) {
 		struct rdma_bind_list *bind_list;
@@ -3770,11 +3832,12 @@ static int cma_check_port(struct rdma_bi
 {
 	struct rdma_id_private *cur_id;
 	struct sockaddr *addr, *cur_addr;
+	COMPAT_HL_NODE
 
 	lockdep_assert_held(&lock);
 
 	addr = cma_src_addr(id_priv);
-	hlist_for_each_entry(cur_id, &bind_list->owners, node) {
+	compat_hlist_for_each_entry(cur_id, &bind_list->owners, node) {
 		if (id_priv == cur_id)
 			continue;
 
@@ -4302,7 +4365,9 @@ static int cma_resolve_ib_udp(struct rdm
 	req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8);
 	req.max_cm_retries = CMA_MAX_CM_RETRIES;
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_send_sidr_req(id_priv);
+#endif
 	ret = ib_send_cm_sidr_req(id_priv->cm_id.ib, &req);
 	if (ret) {
 		ib_destroy_cm_id(id_priv->cm_id.ib);
@@ -4379,7 +4444,9 @@ static int cma_connect_ib(struct rdma_id
 	req.ece.vendor_id = id_priv->ece.vendor_id;
 	req.ece.attr_mod = id_priv->ece.attr_mod;
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_send_req(id_priv);
+#endif
 	ret = ib_send_cm_req(id_priv->cm_id.ib, &req);
 out:
 	if (ret && !IS_ERR(id)) {
@@ -4553,7 +4620,9 @@ static int cma_accept_ib(struct rdma_id_
 	rep.ece.vendor_id = id_priv->ece.vendor_id;
 	rep.ece.attr_mod = id_priv->ece.attr_mod;
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_send_rep(id_priv);
+#endif
 	ret = ib_send_cm_rep(id_priv->cm_id.ib, &rep);
 out:
 	return ret;
@@ -4610,7 +4679,9 @@ static int cma_send_sidr_rep(struct rdma
 	rep.private_data = private_data;
 	rep.private_data_len = private_data_len;
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_send_sidr_rep(id_priv);
+#endif
 	return ib_send_cm_sidr_rep(id_priv->cm_id.ib, &rep);
 }
 
@@ -4747,7 +4818,9 @@ int rdma_reject(struct rdma_cm_id *id, c
 			ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT, 0,
 						private_data, private_data_len);
 		} else {
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 			trace_cm_send_rej(id_priv);
+#endif
 			ret = ib_send_cm_rej(id_priv->cm_id.ib, reason, NULL, 0,
 					     private_data, private_data_len);
 		}
@@ -4776,6 +4849,7 @@ int rdma_disconnect(struct rdma_cm_id *i
 		if (ret)
 			goto out;
 		/* Initiate or respond to a disconnect. */
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 		trace_cm_disconnect(id_priv);
 		if (ib_send_cm_dreq(id_priv->cm_id.ib, NULL, 0)) {
 			if (!ib_send_cm_drep(id_priv->cm_id.ib, NULL, 0))
@@ -4783,6 +4857,10 @@ int rdma_disconnect(struct rdma_cm_id *i
 		} else {
 			trace_cm_sent_dreq(id_priv);
 		}
+#else
+		if (ib_send_cm_dreq(id_priv->cm_id.ib, NULL, 0))
+			ib_send_cm_drep(id_priv->cm_id.ib, NULL, 0);
+#endif
 	} else if (rdma_cap_iw_cm(id->device, id->port_num)) {
 		ret = iw_cm_disconnect(id_priv->cm_id.iw, 0);
 	} else
@@ -4833,6 +4911,9 @@ static void cma_make_mc_event(int status
 	event->param.ud.qkey = id_priv->qkey;
 
 out:
+#ifndef HAVE_NETDEV_PUT
+	if (ndev)
+#endif
 	dev_put(ndev);
 }
 
@@ -5256,7 +5337,9 @@ static void cma_send_device_removal_put(
 		 */
 		cma_id_put(id_priv);
 		mutex_unlock(&id_priv->handler_mutex);
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 		trace_cm_id_destroy(id_priv);
+#endif
 		_destroy_id(id_priv, state);
 		return;
 	}
@@ -5362,7 +5445,9 @@ static int cma_add_one(struct ib_device
 	}
 	mutex_unlock(&lock);
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_add_one(device);
+#endif
 	return 0;
 
 free_listen:
@@ -5384,7 +5469,9 @@ static void cma_remove_one(struct ib_dev
 {
 	struct cma_device *cma_dev = client_data;
 
+#if !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_remove_one(device);
+#endif
 
 	mutex_lock(&lock);
 	list_del(&cma_dev->list);
