aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorParav Pandit <parav@mellanox.com>2019-05-01 01:46:55 -0400
committerJason Gunthorpe <jgg@mellanox.com>2019-05-03 09:41:23 -0400
commiteb15c78b05bd9fbac45ee5b56aaf29b2570b5238 (patch)
tree5e22616df2a1a3d2601516e4ce7928b608270914
parent1a418f7764a00bc6ad8fd1b765b941c3a8389467 (diff)
RDMA/core: Do not invoke init_port on compat devices
The driver interface cannot manipulate the sysfs of the compat device, only of the full device so we must avoid calling the driver sysfs APIs on compat devices. This prevents an oops: Call Trace: dump_stack+0x5a/0x73 kobject_init+0x74/0x80 kobject_init_and_add+0x35/0xb0 hfi1_create_port_files+0x6e/0x3c0 [hfi1] ib_setup_port_attrs+0x43b/0x560 [ib_core] add_one_compat_dev+0x16a/0x230 [ib_core] rdma_dev_init_net+0x110/0x160 [ib_core] ops_init+0x38/0xf0 setup_net+0xcf/0x1e0 copy_net_ns+0xb7/0x130 create_new_namespaces+0x11a/0x1b0 unshare_nsproxy_namespaces+0x55/0xa0 ksys_unshare+0x1a7/0x340 __x64_sys_unshare+0xe/0x20 do_syscall_64+0x5b/0x180 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 5417783eabb2 ("RDMA/core: Support core port attributes in non init_net") Reported-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Tested-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r--drivers/infiniband/core/core_priv.h3
-rw-r--r--drivers/infiniband/core/device.c2
-rw-r--r--drivers/infiniband/core/sysfs.c16
3 files changed, 10 insertions, 11 deletions
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 2764647056d8..ff40a450b5d2 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -341,8 +341,7 @@ int roce_resolve_route_from_path(struct sa_path_rec *rec,
341struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr); 341struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr);
342 342
343void ib_free_port_attrs(struct ib_core_device *coredev); 343void ib_free_port_attrs(struct ib_core_device *coredev);
344int ib_setup_port_attrs(struct ib_core_device *coredev, 344int ib_setup_port_attrs(struct ib_core_device *coredev);
345 bool alloc_hw_stats);
346 345
347int rdma_compatdev_set(u8 enable); 346int rdma_compatdev_set(u8 enable);
348 347
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 76088655f06e..2123cc693a29 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -870,7 +870,7 @@ static int add_one_compat_dev(struct ib_device *device,
870 ret = device_add(&cdev->dev); 870 ret = device_add(&cdev->dev);
871 if (ret) 871 if (ret)
872 goto add_err; 872 goto add_err;
873 ret = ib_setup_port_attrs(cdev, false); 873 ret = ib_setup_port_attrs(cdev);
874 if (ret) 874 if (ret)
875 goto port_err; 875 goto port_err;
876 876
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 2fe89754e592..7a599c5e455f 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -1015,10 +1015,10 @@ err_free_stats:
1015 return; 1015 return;
1016} 1016}
1017 1017
1018static int add_port(struct ib_core_device *coredev, 1018static int add_port(struct ib_core_device *coredev, int port_num)
1019 int port_num, bool alloc_stats)
1020{ 1019{
1021 struct ib_device *device = rdma_device_to_ibdev(&coredev->dev); 1020 struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
1021 bool is_full_dev = &device->coredev == coredev;
1022 struct ib_port *p; 1022 struct ib_port *p;
1023 struct ib_port_attr attr; 1023 struct ib_port_attr attr;
1024 int i; 1024 int i;
@@ -1057,7 +1057,7 @@ static int add_port(struct ib_core_device *coredev,
1057 goto err_put; 1057 goto err_put;
1058 } 1058 }
1059 1059
1060 if (device->ops.process_mad && alloc_stats) { 1060 if (device->ops.process_mad && is_full_dev) {
1061 p->pma_table = get_counter_table(device, port_num); 1061 p->pma_table = get_counter_table(device, port_num);
1062 ret = sysfs_create_group(&p->kobj, p->pma_table); 1062 ret = sysfs_create_group(&p->kobj, p->pma_table);
1063 if (ret) 1063 if (ret)
@@ -1113,7 +1113,7 @@ static int add_port(struct ib_core_device *coredev,
1113 if (ret) 1113 if (ret)
1114 goto err_free_pkey; 1114 goto err_free_pkey;
1115 1115
1116 if (device->ops.init_port) { 1116 if (device->ops.init_port && is_full_dev) {
1117 ret = device->ops.init_port(device, port_num, &p->kobj); 1117 ret = device->ops.init_port(device, port_num, &p->kobj);
1118 if (ret) 1118 if (ret)
1119 goto err_remove_pkey; 1119 goto err_remove_pkey;
@@ -1124,7 +1124,7 @@ static int add_port(struct ib_core_device *coredev,
1124 * port, so holder should be device. Therefore skip per port conunter 1124 * port, so holder should be device. Therefore skip per port conunter
1125 * initialization. 1125 * initialization.
1126 */ 1126 */
1127 if (device->ops.alloc_hw_stats && port_num && alloc_stats) 1127 if (device->ops.alloc_hw_stats && port_num && is_full_dev)
1128 setup_hw_stats(device, p, port_num); 1128 setup_hw_stats(device, p, port_num);
1129 1129
1130 list_add_tail(&p->kobj.entry, &coredev->port_list); 1130 list_add_tail(&p->kobj.entry, &coredev->port_list);
@@ -1308,7 +1308,7 @@ void ib_free_port_attrs(struct ib_core_device *coredev)
1308 kobject_put(coredev->ports_kobj); 1308 kobject_put(coredev->ports_kobj);
1309} 1309}
1310 1310
1311int ib_setup_port_attrs(struct ib_core_device *coredev, bool alloc_stats) 1311int ib_setup_port_attrs(struct ib_core_device *coredev)
1312{ 1312{
1313 struct ib_device *device = rdma_device_to_ibdev(&coredev->dev); 1313 struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
1314 unsigned int port; 1314 unsigned int port;
@@ -1320,7 +1320,7 @@ int ib_setup_port_attrs(struct ib_core_device *coredev, bool alloc_stats)
1320 return -ENOMEM; 1320 return -ENOMEM;
1321 1321
1322 rdma_for_each_port (device, port) { 1322 rdma_for_each_port (device, port) {
1323 ret = add_port(coredev, port, alloc_stats); 1323 ret = add_port(coredev, port);
1324 if (ret) 1324 if (ret)
1325 goto err_put; 1325 goto err_put;
1326 } 1326 }
@@ -1336,7 +1336,7 @@ int ib_device_register_sysfs(struct ib_device *device)
1336{ 1336{
1337 int ret; 1337 int ret;
1338 1338
1339 ret = ib_setup_port_attrs(&device->coredev, true); 1339 ret = ib_setup_port_attrs(&device->coredev);
1340 if (ret) 1340 if (ret)
1341 return ret; 1341 return ret;
1342 1342