Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Leon Romanovsky and committed by
Jason Gunthorpe
e7a5b4aa d2c4ada1

+9
+9
drivers/infiniband/core/device.c
··· 1303 1303 1304 1304 ib_device_register_rdmacg(device); 1305 1305 1306 + /* 1307 + * Ensure that ADD uevent is not fired because it 1308 + * is too early amd device is not initialized yet. 1309 + */ 1310 + dev_set_uevent_suppress(&device->dev, true); 1306 1311 ret = device_add(&device->dev); 1307 1312 if (ret) 1308 1313 goto cg_cleanup; ··· 1320 1315 } 1321 1316 1322 1317 ret = enable_device_and_get(device); 1318 + dev_set_uevent_suppress(&device->dev, false); 1319 + /* Mark for userspace that device is ready */ 1320 + kobject_uevent(&device->dev.kobj, KOBJ_ADD); 1323 1321 if (ret) { 1324 1322 void (*dealloc_fn)(struct ib_device *); 1325 1323 ··· 1351 1343 dev_cleanup: 1352 1344 device_del(&device->dev); 1353 1345 cg_cleanup: 1346 + dev_set_uevent_suppress(&device->dev, false); 1354 1347 ib_device_unregister_rdmacg(device); 1355 1348 ib_cache_cleanup_one(device); 1356 1349 return ret;