lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 20 Apr 2007 11:57:27 -0400
From:	"Dmitry Torokhov" <dmitry.torokhov@...il.com>
To:	"Alan Stern" <stern@...land.harvard.edu>
Cc:	"Tejun Heo" <htejun@...il.com>,
	"Cornelia Huck" <cornelia.huck@...ibm.com>,
	linux-kernel <linux-kernel@...r.kernel.org>,
	"Greg K-H" <greg@...ah.com>,
	"Rusty Russell" <rusty@...tcorp.com.au>
Subject: Re: [PATCH RFD] alternative kobject release wait mechanism

On 4/20/07, Alan Stern <stern@...land.harvard.edu> wrote:
>
> Dmitry, in thinking things over some more I realized there's going to be a
> problem with the autosuspend support in USB.  It has to do with the way a
> driver needs to prevent (or block) suspends from occurring while it is
> actively using a device.
>
> To understand this, you need to know that USB adds a pm_mutex to the
> device structure.  It gets used for synchronizing all suspend- or
> resume-related activities.  In particular, the driver's suspend() method
> is called with usbdev->pm_mutex held.
>
> The next idea is that a driver needs to synchronize its remove() method
> with other methods such as read() -- we mustn't allow read() to try and
> refer to the device after the driver has been unbound.  Let's say the
> driver has unbind_mutex embedded in its private data structure for this
> purpose.
>
> Now consider what read() has to do.  It needs to block suspends from
> occurring while it runs, and it needs to do an autoresume if the device
> was already suspended.  So read() will look like this:
>
>        mutex_lock(&private->unbind_mutex);
>        if (private->gone) {
>                ret = -ENODEV;
>                goto done;
>        }
>        if (private->suspended)
>                autoresume(private->usbdev);
>        ...
>  done:
>        mutex_unlock(&private->unbind_mutex);
>        return ret;
>
> Meanwhile, the suspend() method needs to block while read() is running.
> So it will look like this:
>
>        private->suspended = 1;
>        mutex_lock(&private->unbind_mutex);
>        /* Now the driver has quiesced */
>        mutex_unlock(&private->unbind_mutex);
>
> Here's the problem:  The autoresume() call inside read() tries to acquire
> usbdev->pm_mutex while holding private->unbind_mutex.  The suspend()
> method does the reverse, a locking-order violation.
>
> So far I haven't figured out any way to make this work.  Do you have a
> suggestion?  (Don't say read() should hold pm_mutex as well as
> unbind_mutex; that's no good -- although the reason is rather obscure.)
>

First of all I think that I would merge pm and unbind mutex into one -
you also need to synchronize resume and suspend with bind and unbind
so you pretty much need to always acquire both of them.

Second (and I admit I have not followed USB autoresume discussions, my
usb-devle backlog is over 5000 messages ;( ) is I am not sure why
woudl a read block autoresume. I can see write doing that but passive
reads should not affect device state.

-- 
Dmitry
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ