All of lore.kernel.org
 help / color / mirror / Atom feed
* [questions] about usb_set_intfdata(intf, NULL) and if race is possible between ->disconnect() and ->suspend()
@ 2022-07-14  1:40 Alexey Klimov
  2022-07-14  2:28 ` Alan Stern
  0 siblings, 1 reply; 2+ messages in thread
From: Alexey Klimov @ 2022-07-14  1:40 UTC (permalink / raw)
  To: linux-usb; +Cc: gregkh, stern, klimov.linux

For instance, let's say we have simple usb driver with:

static struct usb_driver usb_some_driver = {
	.name		= DRIVER_NAME,
	.probe		= yet_another_probe,
	.disconnect	= yet_another_disconnect,
	.suspend	= yet_another_suspend,
	.resume		= yet_another_resume,
	.reset_resume	= yet_another_resume,
	.id_table	= yet_another_device_table,
};

1. Can ->suspend and ->disconnect methods race?

Documentation/driver-api/usb/power-management.rst says:
This implies that external suspend/resume events are mutually exclusive
with calls to ``probe``, ``disconnect``, ``pre_reset``, and
``post_reset``;


Comment for usb_suspend_both() says that:
 * ...	Usbcore will insure that
 * method calls do not arrive during bind, unbind, or reset operations.
and that:
 * However drivers must be prepared to handle suspend calls arriving at
 * unpredictable times.

Also I was asked couple of years back what I am going to do if
disconnect() and suspend() will race, so seems never hurts to double-
check.

2. Do I need to usb_set_intfdata(intf, NULL) in disconnect method and
in probe() function if registration with another subsystem fails?
Like:
static int usb_streamlabs_wdt_probe(struct usb_interface *intf,
                                        const struct usb_device_id *id)
{
	...
	usb_set_intfdata(intf, &data);
	...
	retval = devm_subsystem_register_device(&intf->dev, ...);
	if (retval) {
		dev_err(&intf->dev, "error message\n");
		usb_set_intfdata(intf, NULL)
		return retval;
	}
}

I saw some patches that clear stale dev->driver_data pointer in
disconnect but doesn't seem that all usb drivers do that hence the
question.

Thanks,
Alexey



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [questions] about usb_set_intfdata(intf, NULL) and if race is possible between ->disconnect() and ->suspend()
  2022-07-14  1:40 [questions] about usb_set_intfdata(intf, NULL) and if race is possible between ->disconnect() and ->suspend() Alexey Klimov
@ 2022-07-14  2:28 ` Alan Stern
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Stern @ 2022-07-14  2:28 UTC (permalink / raw)
  To: Alexey Klimov; +Cc: linux-usb, gregkh

On Thu, Jul 14, 2022 at 02:40:03AM +0100, Alexey Klimov wrote:
> For instance, let's say we have simple usb driver with:
> 
> static struct usb_driver usb_some_driver = {
> 	.name		= DRIVER_NAME,
> 	.probe		= yet_another_probe,
> 	.disconnect	= yet_another_disconnect,
> 	.suspend	= yet_another_suspend,
> 	.resume		= yet_another_resume,
> 	.reset_resume	= yet_another_resume,
> 	.id_table	= yet_another_device_table,
> };
> 
> 1. Can ->suspend and ->disconnect methods race?

In short, no.  usb_unbind_interface() does usb_autoresume_device(), so 
it is guaranteed that the device will not go into autosuspend while the 
driver's disconnect method is running.

> Documentation/driver-api/usb/power-management.rst says:
> This implies that external suspend/resume events are mutually exclusive
> with calls to ``probe``, ``disconnect``, ``pre_reset``, and
> ``post_reset``;
> 
> 
> Comment for usb_suspend_both() says that:
>  * ...	Usbcore will insure that
>  * method calls do not arrive during bind, unbind, or reset operations.
> and that:
>  * However drivers must be prepared to handle suspend calls arriving at
>  * unpredictable times.
> 
> Also I was asked couple of years back what I am going to do if
> disconnect() and suspend() will race, so seems never hurts to double-
> check.
> 
> 2. Do I need to usb_set_intfdata(intf, NULL) in disconnect method and
> in probe() function if registration with another subsystem fails?

No.  usb_unbind_interface() does this call for you, and 
usb_probe_interface() does it if the probe method fails.

Alan Stern

> Like:
> static int usb_streamlabs_wdt_probe(struct usb_interface *intf,
>                                         const struct usb_device_id *id)
> {
> 	...
> 	usb_set_intfdata(intf, &data);
> 	...
> 	retval = devm_subsystem_register_device(&intf->dev, ...);
> 	if (retval) {
> 		dev_err(&intf->dev, "error message\n");
> 		usb_set_intfdata(intf, NULL)
> 		return retval;
> 	}
> }
> 
> I saw some patches that clear stale dev->driver_data pointer in
> disconnect but doesn't seem that all usb drivers do that hence the
> question.
> 
> Thanks,
> Alexey
> 
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-07-14  2:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-14  1:40 [questions] about usb_set_intfdata(intf, NULL) and if race is possible between ->disconnect() and ->suspend() Alexey Klimov
2022-07-14  2:28 ` Alan Stern

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.