Thread (1 message) 1 message, 1 author, 2013-03-05

Re: [PATCH 0/7] USB: don't recover device if suspend fails in system sleep

From: Bjørn Mork <bjorn@mork.no>
Date: 2013-03-05 13:18:35
Also in: linux-input

Possibly related (same subject, not in this thread)

Ming Lei [off-list ref] writes:
On Tue, Mar 5, 2013 at 3:03 PM, Bjørn Mork [off-list ref] wrote:
quoted
Ming Lei [off-list ref] writes:
quoted
Hi,

This patch adds comments on interface driver suspend callback
to emphasize that the failure return value is ignored by
USB core in system sleep context, so do not try to recover
device for this case, otherwise the URB traffic scheduled
in recovery of failure path may cross system sleep, and may
cause problems.
Well, an unexpected error did happen so problems are to be expected,
yes.
quoted
Also fixes the USB serial, HID and several usbnet drivers
which may recover device in suspend failure path of system sleep.
I believe all of these are wrong unless you have any real bug which is
fixed by this.
It is really a bug if one driver submits URBs and keeps them scheduled
on bus before system sleep, because the bus transaction can't be kept
across system sleep cycle.
1. You do not fix that.  You just ignore that the driver failed to
   cancel *one* of its URBs and return to the caller in an unknown
   state.  That's not even papering over the bug, it is just adding a
   new one without solving anything

2. I asked for a *real* bug, as opposed to theoretical bug.  Working
  around real issues by papering over them may sometimes be acceptable
  if the real issue is bad enough.  Working around theoretical bugs this
  way never is.

Yes, I can also see the theoretical issue.  Feel free to fix that if you
know how. I don't.
quoted
All these drivers suspend in multiple steps, where each step can
fail. If a later step fails then they revert any previously successful
step before returning the failure, thereby ensuring that the
device/driver state when suspend returns is consistently either
suspended or resumed.
IMO, for autosuspend, that is right, but it is not for system suspend,
and the driver's suspend callback can't return in resumed state
OK.  You do realize that the code you are changing tries to deal with
the case where suspend already failed, so returning in suspended state
is impossible?  If you cannot return in resumed state, then you have two
options:
 a) define a new state
 b) don't return

You seem to want to do a).  But that is far more work than just ignoring
partial errors.  You need to add the state, make the caller deal with
it, make resume deal with it etc.

Personally I believe that alternative

c) revert to resumed state and return error

like these drivers do is a better option.
because the USB core will ignore the failure return value and force
to suspend the device.
Yes, I know that. So fix that then if it is an issue. My claim is that
it is not, and that is why the USB core can ignore the failure.  If it
were an issue then the core could not ignore it.  Simple as that.

You cannot keep pushing this down to "Do not allow operation to ever
fail" for every small task involved in a suspend.  It involves
hardware.  It can and will fail.
quoted
I am going to NAK the cdc_mbim and qmi_wwan pacthes unless you can
convince me that we need to add a "partly-suspended" state for the
system suspend error case.  In which case the patch will need to include
the corresponding resume fix for the "partly-suspended" state.
Yes, you may argue that the device might be in partly-suspended state,
but it doesn't matter since the device will be put into suspend later and
Where will it do that?  AFAICS, usb_suspend_both() will resume all
already suspended interfaces if a driver fails suspend.  From the
function docs:

 * This is the central routine for suspending USB devices.  It calls the
 * suspend methods for all the interface drivers in @udev and then calls
 * the suspend method for @udev itself.  If an error occurs at any stage,
 * all the interfaces which were suspended are resumed so that they remain
 * in the same state as the device.


You do want the *failing* interface driver/function to have the same
state as the rest of the device functions, i.e. resumed, on return from
suspend.
the resume callback can recover from the partly-suspend state.
It can.  But it won't magically just do that by ignoring errors in
suspend.
These patches doesn't break previous failure path of system suspend
and just avoid to submit new URBs, so how about letting later delta
patches fix for the corresponding resume?
From Documentation/usb/power-management.txt :

        The suspend method is called to warn the driver that the
        device is going to be suspended.  If the driver returns a
        negative error code, the suspend will be aborted.  Normally
        the driver will return 0, in which case it must cancel all
        outstanding URBs (usb_kill_urb()) and not submit any more.


The driver need only cancel outstanding URBs if it returns 0.  How the
USB core handles this is up to the USB core.  It is not for the
drivers to deal with.  Unless you modify the API to say that suspend
cannot fail in the !PMSG_IS_AUTO(message) case.

But I really think all that ugly PMSG_IS_AUTO(message) testing in the
USB drivers is contradicting the simple design of the USB core, using a
single common suspend for both runtime and system suspend and leaving it
up to the USB core to handle the differences.

AFAICS, it does that just fine.  If you think it does not, then please
fix that in the USB core or redefine the API.  But don't just randomly
make drivers ignore errors.


Bjørn
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help