summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2020-12-08 09:35:44 +0200
committerJason Gunthorpe <jgg@nvidia.com>2020-12-10 15:05:17 -0400
commit779e0bf47632c609c59f527f9711ecd3214dccb0 (patch)
treeb968abeb26d3a1539c91e33cdb2a0d8a45533308 /drivers/infiniband
parent286e1d3f9ba89c7db5eecd30f47f9e333843ea13 (diff)
downloadlinux-stable-779e0bf47632c609c59f527f9711ecd3214dccb0.tar.gz
linux-stable-779e0bf47632c609c59f527f9711ecd3214dccb0.tar.bz2
linux-stable-779e0bf47632c609c59f527f9711ecd3214dccb0.zip
RDMA/core: Do not indicate device ready when device enablement fails
In procedure ib_register_device, procedure kobject_uevent is called (advertising that the device is ready for userspace usage) even when device_enable_and_get() returned an error. As a result, various RDMA modules attempted to register for the device even while the device driver was preparing to unregister the device. Fix this by advertising the device availability only after enabling the device succeeds. Fixes: e7a5b4aafd82 ("RDMA/device: Don't fire uevent before device is fully initialized") Link: https://lore.kernel.org/r/20201208073545.9723-3-leon@kernel.org Suggested-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/device.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 11485b8748a2..e96f979e6d52 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -1397,9 +1397,6 @@ int ib_register_device(struct ib_device *device, const char *name,
}
ret = enable_device_and_get(device);
- dev_set_uevent_suppress(&device->dev, false);
- /* Mark for userspace that device is ready */
- kobject_uevent(&device->dev.kobj, KOBJ_ADD);
if (ret) {
void (*dealloc_fn)(struct ib_device *);
@@ -1419,8 +1416,12 @@ int ib_register_device(struct ib_device *device, const char *name,
ib_device_put(device);
__ib_unregister_device(device);
device->ops.dealloc_driver = dealloc_fn;
+ dev_set_uevent_suppress(&device->dev, false);
return ret;
}
+ dev_set_uevent_suppress(&device->dev, false);
+ /* Mark for userspace that device is ready */
+ kobject_uevent(&device->dev.kobj, KOBJ_ADD);
ib_device_put(device);
return 0;