Skip to content

Commit 634775a

Browse files
Elson Roy Serraogregkh
authored andcommitted
usb: roles: set switch registered flag early on
The role switch registration and set_role() can happen in parallel as they are invoked independent of each other. There is a possibility that a driver might spend significant amount of time in usb_role_switch_register() API due to the presence of time intensive operations like component_add() which operate under common mutex. This leads to a time window after allocating the switch and before setting the registered flag where the set role notifications are dropped. Below timeline summarizes this behavior Thread1 | Thread2 usb_role_switch_register() | | | ---> allocate switch | | | ---> component_add() | usb_role_switch_set_role() | | | | | --> Drop role notifications | | since sw->registered | | flag is not set. | | --->Set registered flag.| To avoid this, set the registered flag early on in the switch register API. Fixes: b787a3e ("usb: roles: don't get/set_role() when usb_role_switch is unregistered") Cc: stable <[email protected]> Signed-off-by: Elson Roy Serrao <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e5644be commit 634775a

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/usb/roles/class.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,11 @@ usb_role_switch_register(struct device *parent,
387387
dev_set_name(&sw->dev, "%s-role-switch",
388388
desc->name ? desc->name : dev_name(parent));
389389

390+
sw->registered = true;
391+
390392
ret = device_register(&sw->dev);
391393
if (ret) {
394+
sw->registered = false;
392395
put_device(&sw->dev);
393396
return ERR_PTR(ret);
394397
}
@@ -399,8 +402,6 @@ usb_role_switch_register(struct device *parent,
399402
dev_warn(&sw->dev, "failed to add component\n");
400403
}
401404

402-
sw->registered = true;
403-
404405
/* TODO: Symlinks for the host port and the device controller. */
405406

406407
return sw;

0 commit comments

Comments
 (0)