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

Change-Id: I57ffea877bd35e565e93dbfd51fc81a8ff594de8
---
 drivers/infiniband/core/cma.c | 103 ++++++++++++++++++++++++++++++++--
 1 file changed, 97 insertions(+), 6 deletions(-)

--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -39,11 +39,16 @@
 
 #include "core_priv.h"
 #include "cma_priv.h"
+#ifdef HAVE_TRACE_EVENTS_H
 #include "cma_trace.h"
+#endif
 
 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
@@ -175,6 +180,7 @@ static struct rb_root id_table = RB_ROOT
 /* Serialize operations of id_table tree */
 static DEFINE_SPINLOCK(id_table_lock);
 static struct workqueue_struct *cma_wq;
+
 static struct workqueue_struct *cma_netevent_wq;
 static unsigned int cma_pernet_id;
 
@@ -244,6 +250,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,
@@ -602,7 +609,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(HAVE_TRACE_EVENTS_H) && !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,
@@ -1114,12 +1123,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(HAVE_TRACE_EVENTS_H) && !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(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_qp_create(id_priv, pd, qp_init_attr, ret);
+#endif
 	return ret;
 }
 EXPORT_SYMBOL(rdma_create_qp);
@@ -1129,7 +1142,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(HAVE_TRACE_EVENTS_H) && !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;
@@ -1579,7 +1594,12 @@ static bool validate_ipv4_net_dev(struct
 	fl4.saddr = saddr;
 
 	rcu_read_lock();
+
+#ifdef HAVE_FIB_LOOKUP_4_PARAMS
 	err = fib_lookup(dev_net(net_dev), &fl4, &res, 0);
+#else
+	err = fib_lookup(dev_net(net_dev), &fl4, &res);
+#endif
 	ret = err == 0 && FIB_RES_DEV(res) == net_dev;
 	rcu_read_unlock();
 
@@ -1595,7 +1615,11 @@ static bool validate_ipv6_net_dev(struct
 			   IPV6_ADDR_LINKLOCAL;
 	struct rt6_info *rt = rt6_lookup(dev_net(net_dev), &dst_addr->sin6_addr,
 					 &src_addr->sin6_addr, net_dev->ifindex,
+#ifdef HAVE_RT6_LOOKUP_TAKES_6_PARAMS
 					 NULL, strict);
+#else
+					 strict);
+#endif
 	bool ret;
 
 	if (!rt)
@@ -1781,13 +1805,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))
@@ -2061,7 +2086,9 @@ static void destroy_id_handler_unlock(st
 	enum rdma_cm_state state;
 	unsigned long flags;
 
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_id_destroy(id_priv);
+#endif
 
 	/*
 	 * Setting the state to destroyed under the handler mutex provides a
@@ -2100,7 +2127,9 @@ static int cma_rep_recv(struct rdma_id_p
 	if (ret)
 		goto reject;
 
+#if defined(HAVE_TRACE_EVENTS_H) && !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;
@@ -2109,7 +2138,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(HAVE_TRACE_EVENTS_H) && !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;
@@ -2139,9 +2170,13 @@ static int cma_cm_event_handler(struct r
 
 	lockdep_assert_held(&id_priv->handler_mutex);
 
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_event_handler(id_priv, event);
+#endif
 	ret = id_priv->id.event_handler(&id_priv->id, event);
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_event_done(id_priv, event, ret);
+#endif
 	return ret;
 }
 
@@ -2170,7 +2205,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(HAVE_TRACE_EVENTS_H) && !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) {
@@ -2381,7 +2418,9 @@ static int cma_ib_req_handler(struct ib_
 	if (IS_ERR(listen_id))
 		return PTR_ERR(listen_id);
 
+#if defined(HAVE_TRACE_EVENTS_H) && !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;
@@ -2432,7 +2471,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(HAVE_TRACE_EVENTS_H) && !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);
@@ -2676,7 +2717,9 @@ static int cma_listen_handler(struct rdm
 
 	id->context = id_priv->id.context;
 	id->event_handler = id_priv->id.event_handler;
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_event_handler(id_priv, event);
+#endif
 	return id_priv->id.event_handler(id, event);
 }
 
@@ -3190,10 +3233,19 @@ struct iboe_prio_tc_map {
 	bool found;
 };
 
+#ifdef HAVE_NETDEV_WALK_ALL_LOWER_DEV_RCU
 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);
@@ -3207,24 +3259,36 @@ static int get_lower_vlan_dev_tc(struct
 	map->found = true;
 	return 1;
 }
+#endif
 
 static int iboe_tos_to_sl(struct net_device *ndev, int tos)
 {
 	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))
+	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
+#ifdef HAVE_NETDEV_WALK_ALL_LOWER_DEV_RCU
 	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();
+#endif
 	/* If map is found from lower device, use it; Otherwise
 	 * continue with the current netdevice to get priority to tc map.
 	 */
@@ -3779,10 +3843,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);
@@ -3825,7 +3890,11 @@ static int cma_alloc_any_port(enum rdma_
 
 	inet_get_local_port_range(net, &low, &high);
 	remaining = (high - low) + 1;
-	rover = prandom_u32() % remaining + low;
+#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;
@@ -3869,11 +3938,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;
 
@@ -4277,7 +4347,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(HAVE_TRACE_EVENTS_H) && !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);
@@ -4354,7 +4426,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(HAVE_TRACE_EVENTS_H) && !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)) {
@@ -4528,7 +4602,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(HAVE_TRACE_EVENTS_H) && !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;
@@ -4582,7 +4658,9 @@ static int cma_send_sidr_rep(struct rdma
 	rep.private_data = private_data;
 	rep.private_data_len = private_data_len;
 
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_send_sidr_rep(id_priv);
+#endif
 	return ib_send_cm_sidr_rep(id_priv->cm_id.ib, &rep);
 }
 
@@ -4719,7 +4797,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(HAVE_TRACE_EVENTS_H) && !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);
 		}
@@ -4748,6 +4828,7 @@ int rdma_disconnect(struct rdma_cm_id *i
 		if (ret)
 			goto out;
 		/* Initiate or respond to a disconnect. */
+#if defined(HAVE_TRACE_EVENTS_H) && !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))
@@ -4755,6 +4836,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
@@ -5231,7 +5316,9 @@ static void cma_send_device_removal_put(
 		 */
 		cma_id_put(id_priv);
 		mutex_unlock(&id_priv->handler_mutex);
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 		trace_cm_id_destroy(id_priv);
+#endif
 		_destroy_id(id_priv, state);
 		return;
 	}
@@ -5337,7 +5424,9 @@ static int cma_add_one(struct ib_device
 	}
 	mutex_unlock(&lock);
 
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_add_one(device);
+#endif
 	return 0;
 
 free_listen:
@@ -5359,7 +5448,9 @@ static void cma_remove_one(struct ib_dev
 {
 	struct cma_device *cma_dev = client_data;
 
+#if defined(HAVE_TRACE_EVENTS_H) && !defined(MLX_DISABLE_TRACEPOINTS)
 	trace_cm_remove_one(device);
+#endif
 
 	mutex_lock(&lock);
 	list_del(&cma_dev->list);
