Skip to content

Commit e89f912

Browse files
mhklinuxliuw
authored andcommitted
Drivers: hv: vmbus: Add comments about races with "channels" sysfs dir
The VMBus driver code has some inherent races in the creation of the "channels" sysfs subdirectory and its per-channel numbered subdirectories. These races have not generally been recognized or understood. Add some comments to call them out. No code changes. Signed-off-by: Michael Kelley <mhklinux@outlook.com> Link: https://lore.kernel.org/r/20250514225508.52629-1-mhklinux@outlook.com Signed-off-by: Wei Liu <wei.liu@kernel.org> Message-ID: <20250514225508.52629-1-mhklinux@outlook.com>
1 parent f77276d commit e89f912

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

drivers/hv/vmbus_drv.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,30 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id(const struct hv_driver *
714714
return id;
715715
}
716716

717-
/* vmbus_add_dynid - add a new device ID to this driver and re-probe devices */
717+
/* vmbus_add_dynid - add a new device ID to this driver and re-probe devices
718+
*
719+
* This function can race with vmbus_device_register(). This function is
720+
* typically running on a user thread in response to writing to the "new_id"
721+
* sysfs entry for a driver. vmbus_device_register() is running on a
722+
* workqueue thread in response to the Hyper-V host offering a device to the
723+
* guest. This function calls driver_attach(), which looks for an existing
724+
* device matching the new id, and attaches the driver to which the new id
725+
* has been assigned. vmbus_device_register() calls device_register(), which
726+
* looks for a driver that matches the device being registered. If both
727+
* operations are running simultaneously, the device driver probe function runs
728+
* on whichever thread establishes the linkage between the driver and device.
729+
*
730+
* In most cases, it doesn't matter which thread runs the driver probe
731+
* function. But if vmbus_device_register() does not find a matching driver,
732+
* it proceeds to create the "channels" subdirectory and numbered per-channel
733+
* subdirectory in sysfs. While that multi-step creation is in progress, this
734+
* function could run the driver probe function. If the probe function checks
735+
* for, or operates on, entries in the "channels" subdirectory, including by
736+
* calling hv_create_ring_sysfs(), the operation may or may not succeed
737+
* depending on the race. The race can't create a kernel failure in VMBus
738+
* or device subsystem code, but probe functions in VMBus drivers doing such
739+
* operations must be prepared for the failure case.
740+
*/
718741
static int vmbus_add_dynid(struct hv_driver *drv, guid_t *guid)
719742
{
720743
struct vmbus_dynid *dynid;
@@ -1928,7 +1951,8 @@ static const struct kobj_type vmbus_chan_ktype = {
19281951
* ring for userspace to use.
19291952
* Note: Race conditions can happen with userspace and it is not encouraged to create new
19301953
* use-cases for this. This was added to maintain backward compatibility, while solving
1931-
* one of the race conditions in uio_hv_generic while creating sysfs.
1954+
* one of the race conditions in uio_hv_generic while creating sysfs. See comments with
1955+
* vmbus_add_dynid() and vmbus_device_register().
19321956
*
19331957
* Returns 0 on success or error code on failure.
19341958
*/
@@ -2062,6 +2086,20 @@ int vmbus_device_register(struct hv_device *child_device_obj)
20622086
return ret;
20632087
}
20642088

2089+
/*
2090+
* If device_register() found a driver to assign to the device, the
2091+
* driver's probe function has already run at this point. If that
2092+
* probe function accesses or operates on the "channels" subdirectory
2093+
* in sysfs, those operations will have failed because the "channels"
2094+
* subdirectory doesn't exist until the code below runs. Or if the
2095+
* probe function creates a /dev entry, a user space program could
2096+
* find and open the /dev entry, and then create a race by accessing
2097+
* the "channels" subdirectory while the creation steps are in progress
2098+
* here. The race can't result in a kernel failure, but the user space
2099+
* program may get an error in accessing "channels" or its
2100+
* subdirectories. See also comments with vmbus_add_dynid() about a
2101+
* related race condition.
2102+
*/
20652103
child_device_obj->channels_kset = kset_create_and_add("channels",
20662104
NULL, kobj);
20672105
if (!child_device_obj->channels_kset) {

0 commit comments

Comments
 (0)