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

Change-Id: I78a0cbfef6bc77d7572cb71653cf76f74437d370
---
 drivers/infiniband/core/device.c | 122 ++++++++++++++++++++++++++++---
 1 file changed, 110 insertions(+), 12 deletions(-)

--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -46,6 +46,7 @@
 #include <rdma/ib_addr.h>
 #include <rdma/ib_cache.h>
 #include <rdma/rdma_counter.h>
+#include <linux/sizes.h>
 
 #include "core_priv.h"
 #include "restrack.h"
@@ -53,6 +54,9 @@
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("core kernel InfiniBand API");
 MODULE_LICENSE("Dual BSD/GPL");
+#ifdef RETPOLINE_MLNX
+MODULE_INFO(retpoline, "Y");
+#endif
 
 struct workqueue_struct *ib_comp_wq;
 struct workqueue_struct *ib_comp_unbound_wq;
@@ -186,11 +190,17 @@ static DECLARE_HASHTABLE(ndev_hash, 5);
 static void free_netdevs(struct ib_device *ib_dev);
 static void ib_unregister_work(struct work_struct *work);
 static void __ib_unregister_device(struct ib_device *device);
+#if defined(HAVE_REGISTER_BLOCKING_LSM_NOTIFIER) || defined (HAVE_REGISTER_LSM_NOTIFIER)
 static int ib_security_change(struct notifier_block *nb, unsigned long event,
 			      void *lsm_data);
 static void ib_policy_change_task(struct work_struct *work);
 static DECLARE_WORK(ib_policy_change_work, ib_policy_change_task);
 
+static struct notifier_block ibdev_lsm_nb = {
+	.notifier_call = ib_security_change,
+};
+#endif
+
 static void __ibdev_printk(const char *level, const struct ib_device *ibdev,
 			   struct va_format *vaf)
 {
@@ -251,10 +261,6 @@ define_ibdev_printk_level(ibdev_warn, KE
 define_ibdev_printk_level(ibdev_notice, KERN_NOTICE);
 define_ibdev_printk_level(ibdev_info, KERN_INFO);
 
-static struct notifier_block ibdev_lsm_nb = {
-	.notifier_call = ib_security_change,
-};
-
 static int rdma_dev_change_netns(struct ib_device *device, struct net *cur_net,
 				 struct net *net);
 
@@ -454,17 +460,32 @@ static int alloc_name(struct ib_device *
 {
 	struct ib_device *device;
 	unsigned long index;
-	struct ida inuse;
-	int rc;
 	int i;
+#ifdef HAVE_IDA_ALLOC
+       struct ida inuse;
+       int rc;
+#else
+	unsigned long *inuse;
 
+	inuse = (unsigned long *) get_zeroed_page(GFP_KERNEL);
+	if (!inuse)
+		return -ENOMEM;
+#endif
+#ifdef HAVE_LOCKUP_ASSERT_HELD_EXCLUSIVE
+      lockdep_assert_held_exclusive(&devices_rwsem);
+#elif defined(HAVE_LOCKUP_ASSERT_HELD_WRITE)
 	lockdep_assert_held_write(&devices_rwsem);
-	ida_init(&inuse);
+#endif
+
+#ifdef HAVE_IDA_ALLOC
+       ida_init(&inuse);
+#endif
 	xa_for_each (&devices, index, device) {
 		char buf[IB_DEVICE_NAME_MAX];
 
 		if (sscanf(dev_name(&device->dev), name, &i) != 1)
 			continue;
+#ifdef HAVE_IDA_ALLOC
 		if (i < 0 || i >= INT_MAX)
 			continue;
 		snprintf(buf, sizeof buf, name, i);
@@ -484,6 +505,17 @@ static int alloc_name(struct ib_device *
 out:
 	ida_destroy(&inuse);
 	return rc;
+#else
+	if (i < 0 || i >= PAGE_SIZE * 8)
+		continue;
+	snprintf(buf, sizeof buf, name, i);
+	if (!strcmp(buf, dev_name(&device->dev)))
+		set_bit(i, inuse);
+	}
+	i = find_first_zero_bit(inuse, PAGE_SIZE * 8);
+	free_page((unsigned long) inuse);
+	return dev_set_name(&ibdev->dev, name, i);
+#endif
 }
 
 static void ib_device_release(struct device *device)
@@ -511,7 +543,11 @@ static void ib_device_release(struct dev
 	kfree_rcu(dev, rcu_head);
 }
 
+#ifdef HAVE_NET_NAMESPACE_GET_CONST_DEVICE
+static int ib_device_uevent(const struct device *device,
+#else
 static int ib_device_uevent(struct device *device,
+#endif
 			    struct kobj_uevent_env *env)
 {
 	if (add_uevent_var(env, "NAME=%s", dev_name(device)))
@@ -524,7 +560,11 @@ static int ib_device_uevent(struct devic
 	return 0;
 }
 
+#ifdef HAVE_NET_NAMESPACE_GET_CONST_DEVICE
+static const void *net_namespace(const struct device *d)
+#else
 static const void *net_namespace(struct device *d)
+#endif
 {
 	struct ib_core_device *coredev =
 			container_of(d, struct ib_core_device, dev);
@@ -879,6 +919,7 @@ void ib_get_device_fw_str(struct ib_devi
 }
 EXPORT_SYMBOL(ib_get_device_fw_str);
 
+#if defined(HAVE_REGISTER_BLOCKING_LSM_NOTIFIER) || defined (HAVE_REGISTER_LSM_NOTIFIER)
 static void ib_policy_change_task(struct work_struct *work)
 {
 	struct ib_device *dev;
@@ -908,6 +949,7 @@ static int ib_security_change(struct not
 
 	return NOTIFY_OK;
 }
+#endif /* HAVE_REGISTER_BLOCKING_LSM_NOTIFIER */
 
 static void compatdev_release(struct device *dev)
 {
@@ -1372,6 +1414,7 @@ int ib_register_device(struct ib_device
 	if (ret)
 		return ret;
 
+#ifdef HAVE_DEVICE_DMA_OPS
 	/*
 	 * If the caller does not provide a DMA capable device then the IB core
 	 * will set up ib_sge and scatterlist structures that stash the kernel
@@ -1379,6 +1422,17 @@ int ib_register_device(struct ib_device
 	 */
 	WARN_ON(dma_device && !dma_device->dma_parms);
 	device->dma_device = dma_device;
+#else /* HAVE_DEVICE_DMA_OPS */
+	WARN_ON_ONCE(!device->dev.parent && !device->dma_device);
+	WARN_ON_ONCE(device->dev.parent && device->dma_device
+		     && device->dev.parent != device->dma_device);
+	if (!device->dev.parent)
+		device->dev.parent = device->dma_device;
+	if (!device->dma_device)
+		device->dma_device = device->dev.parent;
+	/* Setup default max segment size for all IB devices */
+	dma_set_max_seg_size(device->dma_device, SZ_2G);
+#endif /* HAVE_DEVICE_DMA_OPS */
 
 	ret = setup_device(device);
 	if (ret)
@@ -1397,7 +1451,9 @@ int ib_register_device(struct ib_device
 	if (ret)
 		goto cache_cleanup;
 
+#ifdef HAVE_CGROUP_RDMA_H
 	ib_device_register_rdmacg(device);
+#endif
 
 	rdma_counter_init(device);
 
@@ -1463,7 +1519,9 @@ dev_cleanup:
 	device_del(&device->dev);
 cg_cleanup:
 	dev_set_uevent_suppress(&device->dev, false);
+#ifdef HAVE_CGROUP_RDMA_H
 	ib_device_unregister_rdmacg(device);
+#endif
 cache_cleanup:
 	ib_cache_cleanup_one(device);
 	return ret;
@@ -1491,7 +1549,9 @@ static void __ib_unregister_device(struc
 
 	ib_free_port_attrs(&ib_dev->coredev);
 	device_del(&ib_dev->dev);
+#ifdef HAVE_CGROUP_RDMA_H
 	ib_device_unregister_rdmacg(ib_dev);
+#endif
 	ib_cache_cleanup_one(ib_dev);
 
 	/*
@@ -1610,6 +1670,7 @@ static void ib_unregister_work(struct wo
  * Drivers using this API must use ib_unregister_driver before module unload
  * to ensure that all scheduled unregistrations have completed.
  */
+#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
 void ib_unregister_device_queued(struct ib_device *ib_dev)
 {
 	WARN_ON(!refcount_read(&ib_dev->refcount));
@@ -1619,6 +1680,7 @@ void ib_unregister_device_queued(struct
 		put_device(&ib_dev->dev);
 }
 EXPORT_SYMBOL(ib_unregister_device_queued);
+#endif
 
 /*
  * The caller must pass in a device that has the kref held and the refcount
@@ -2269,9 +2331,10 @@ struct ib_device *ib_device_get_by_netde
 {
 	struct ib_device *res = NULL;
 	struct ib_port_data *cur;
+        COMPAT_HL_NODE;
 
 	rcu_read_lock();
-	hash_for_each_possible_rcu (ndev_hash, cur, ndev_hash_link,
+	compat_hash_for_each_possible_rcu (ndev_hash, cur, ndev_hash_link,
 				    (uintptr_t)ndev) {
 		if (rcu_access_pointer(cur->netdev) == ndev &&
 		    (driver_id == RDMA_DRIVER_UNKNOWN ||
@@ -2685,6 +2748,9 @@ void ib_set_device_ops(struct ib_device
 	SET_DEVICE_OP(dev_ops, get_vf_config);
 	SET_DEVICE_OP(dev_ops, get_vf_guid);
 	SET_DEVICE_OP(dev_ops, get_vf_stats);
+#ifndef HAVE_MMU_INTERVAL_NOTIFIER
+	SET_DEVICE_OP(dev_ops, invalidate_range);
+#endif
 	SET_DEVICE_OP(dev_ops, iw_accept);
 	SET_DEVICE_OP(dev_ops, iw_add_ref);
 	SET_DEVICE_OP(dev_ops, iw_connect);
@@ -2795,14 +2861,28 @@ static int __init ib_core_init(void)
 		goto err;
 
 	ib_comp_wq = alloc_workqueue("ib-comp-wq",
-			WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
+			0
+			| WQ_HIGHPRI
+			| WQ_MEM_RECLAIM
+			| WQ_SYSFS
+#if defined(HAVE_WQ_NON_REENTRANT)
+			| WQ_NON_REENTRANT
+#endif
+			, 0);
 	if (!ib_comp_wq)
 		goto err_unbound;
 
 	ib_comp_unbound_wq =
 		alloc_workqueue("ib-comp-unb-wq",
-				WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM |
-				WQ_SYSFS, WQ_UNBOUND_MAX_ACTIVE);
+			0
+			| WQ_UNBOUND
+			| WQ_HIGHPRI
+			| WQ_MEM_RECLAIM
+			| WQ_SYSFS
+#if defined(HAVE_WQ_NON_REENTRANT)
+			| WQ_NON_REENTRANT
+#endif
+			, WQ_UNBOUND_MAX_ACTIVE);
 	if (!ib_comp_unbound_wq)
 		goto err_comp;
 
@@ -2832,11 +2912,17 @@ static int __init ib_core_init(void)
 		goto err_mad;
 	}
 
+#if defined(HAVE_REGISTER_BLOCKING_LSM_NOTIFIER) || defined(HAVE_REGISTER_LSM_NOTIFIER)
+#ifdef HAVE_REGISTER_BLOCKING_LSM_NOTIFIER
 	ret = register_blocking_lsm_notifier(&ibdev_lsm_nb);
+#elif defined(HAVE_REGISTER_LSM_NOTIFIER)
+       ret = register_lsm_notifier(&ibdev_lsm_nb);
+#endif /* HAVE_REGISTER_BLOCKING_LSM_NOTIFIER */
 	if (ret) {
 		pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
 		goto err_sa;
 	}
+#endif
 
 	ret = register_pernet_device(&rdma_dev_net_ops);
 	if (ret) {
@@ -2851,9 +2937,15 @@ static int __init ib_core_init(void)
 	return 0;
 
 err_compat:
+#if defined(HAVE_REGISTER_BLOCKING_LSM_NOTIFIER) || defined(HAVE_REGISTER_LSM_NOTIFIER)
+#ifdef HAVE_REGISTER_BLOCKING_LSM_NOTIFIER
 	unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
+#elif defined(HAVE_REGISTER_LSM_NOTIFIER)
+	unregister_lsm_notifier(&ibdev_lsm_nb);
+#endif /* HAVE_REGISTER_BLOCKING_LSM_NOTIFIER */
 err_sa:
 	ib_sa_cleanup();
+#endif
 err_mad:
 	ib_mad_cleanup();
 err_addr:
@@ -2877,7 +2969,11 @@ static void __exit ib_core_cleanup(void)
 	nldev_exit();
 	rdma_nl_unregister(RDMA_NL_LS);
 	unregister_pernet_device(&rdma_dev_net_ops);
+#ifdef HAVE_REGISTER_BLOCKING_LSM_NOTIFIER
 	unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
+#elif defined(HAVE_REGISTER_LSM_NOTIFIER)
+	unregister_lsm_notifier(&ibdev_lsm_nb);
+#endif
 	ib_sa_cleanup();
 	ib_mad_cleanup();
 	addr_cleanup();
@@ -2887,7 +2983,9 @@ static void __exit ib_core_cleanup(void)
 	destroy_workqueue(ib_comp_wq);
 	/* Make sure that any pending umem accounting work is done. */
 	destroy_workqueue(ib_wq);
+#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
 	destroy_workqueue(ib_unreg_wq);
+#endif
 	WARN_ON(!xa_empty(&clients));
 	WARN_ON(!xa_empty(&devices));
 }
