diff options
author | Leon Romanovsky <leonro@mellanox.com> | 2019-05-05 19:33:20 +0300 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2019-05-07 13:02:43 -0300 |
commit | e7a5b4aafd82771f8924905c208d5d236ddcb671 (patch) | |
tree | bae764d152d85fb319e3844635d533b264b1df32 /drivers | |
parent | d2c4ada1ed883ea1310112965f2f1d713a470699 (diff) | |
download | linux-e7a5b4aafd82771f8924905c208d5d236ddcb671.tar.bz2 |
RDMA/device: Don't fire uevent before device is fully initialized
When the refcount is 0 the device is invisible to netlink. However in the
patch below the refcount = 1 was moved to after the device_add(). This
creates a race where userspace can issue a netlink query after the
device_add() event and not see the device as visible.
Ensure that no uevent is fired before device is fully registered.
Fixes: d79af7242bb2 ("RDMA/device: Expose ib_device_try_get(()")
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/core/device.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 9665c3796cfb..78dc07c6ac4b 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -1303,6 +1303,11 @@ int ib_register_device(struct ib_device *device, const char *name) ib_device_register_rdmacg(device); + /* + * Ensure that ADD uevent is not fired because it + * is too early amd device is not initialized yet. + */ + dev_set_uevent_suppress(&device->dev, true); ret = device_add(&device->dev); if (ret) goto cg_cleanup; @@ -1315,6 +1320,9 @@ 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 *); @@ -1343,6 +1351,7 @@ int ib_register_device(struct ib_device *device, const char *name) dev_cleanup: device_del(&device->dev); cg_cleanup: + dev_set_uevent_suppress(&device->dev, false); ib_device_unregister_rdmacg(device); ib_cache_cleanup_one(device); return ret; |