On Friday 30 July 2004 08:35, Alan Stern wrote: > On Thu, 29 Jul 2004, David Brownell wrote:
> Aha! The upstream "port" wasn't locked; the entire hub was! So even if > non-data signalling is taking place on a port/branch that is disjoint from > your device you still have to suffer the locking delay. It's that performance issue again: khubd could get the most-specific lock by getting it at the top of each pass through "for each port" loop. But this initial patch continued the "lock it once" strategy. > Suppose an upstream hub is locked for some reason while another thread > wants to work on a downstream device, either to reset it or to do event > processing (if the downstream device is another hub): Hubs aren't the only, or main, thing to lock ... see the other patch. Remember that the khubd change was a "minimal change" patch; I think you want a performance-tuned one! > 1. The upstream hub has a connect change event. Khubd will > immediately mark all devices below the port as NOTATTACHED. > It doesn't matter what type of locking is used on the > downstream device; pretty much everything will fail. > Certainly reset or event processing will. Suspend/resume too; "fail fast" is the model on that locktree() path. > 2. The upstream hub is being suspended. Your recursive suspend > code will lock the downstream device when it gets there. So That is, two tasks concurrently changing power/state needing to coordinate with each other. In this case they're both suspending, and the "topmost" suspend started first. > it doesn't matter what sort of locking is used by the other > thread working on the device; both locktree and regular locking > will have to wait until the device is suspended. I don't know what you mean by "regular", but that's certainly not true of what's (not) in RC2 ... :) > (Locktree > will have to wait until _everything_ below the upstream hub > is suspended.) Once the downstream device is suspended both > reset and event processing will fail. Waiting during suspend() isn't exactly performance-critical... except that it achieve the right sequence! And if this (third) thread doing the reset cared about sequence with respect to the either of the threads doing the suspend, it'd need to synchronize in any case. > 3. The upstream hub is being resumed. Under these circumstances > it's unlikely that anyone would want to do anything to the > downstream device since it must still be suspended, but never > mind that. I/O is a "driver bug" scenario, and drivers should just get errors. The other cases are "non-data signaling" (gotta be a better name for it than that). > Resume processing will recursively lock devices > below the upstream hub as they are resumed. The downstream > device will get locked in its turn, so again it doesn't matter > whether the other thread uses locktree or regular locking. Erm, and what is this second thread doing that sequence wouldn't matter? Disconnecting ... locktree uses the (newish) spinlock and is failfast for all callers, so not that. Resetting .... the resume needs to finish first, not that then. Powering off ... ditto, to ensure clean shutdown. Suspending ... same. That is, the sequence DOES matter, and that's another part of what locktree() is delivering. > 4. The upstream hub is being reset. Part of the code I added > (probably in one of the patches that Greg hasn't applied yet) > changed usb_reset_device() so that when a hub is reset all of > its children are disconnected first. Once the downstream > device is gone, the question of whether to use locktree or > regular locking is moot. Mostly controlled by the spinlock ... maybe not as much as it should be though. Locktree handles that just fine. > 5. The upstream hub is processing an overcurrent-change notification > for the port leading to the downstream device. All khubd does > when this happens is to clear the overcurrent-change feature. > There's no need for the other thread to wait for that to > complete, as locktree would make it do. It's not locktree() that makes that specific policy, it's khubd. Those (potential) performance issues each could be handled by khubd doing down(&hdev->child[i]->serialize) and then up(&hdev->serialize) before playing with that particular port. (Enumeration wouldn't quite work that way, though, child[i] being NULL.) But it'd have to get the hub lock, with locktree(), at the top of each loop. > In short, I don't see any situations in which using locktree() for hub > event processing or device resets will provide any advantage at all. But > there _are_ situations (2 and 5) in which it will provide useless delays. See above; event sequencing is important, and it's easy to drop the hub lock earlier on certain event paths. > I foresee more problems. For example, whose responsibility should it > ultimately be to suspend a subtree of nodes in the USB tree -- the driver > core's or usbcore's? For now, USB ... the driver core doesn't handle this yet. > The driver core doesn't have the knowledge to apply > the proper locking. And what should happen when there are non-USB devices > located below a USB node (a SCSI disk for example), who's responsible for > locking them? Locking them for what purpose? Subsystem rwlocks affect some things, The power core has a semaphore (sigh). USB has locks, SCSI has locks, block layer has locks ... - Dave ------------------------------------------------------- This SF.Net email is sponsored by OSTG. Have you noticed the changes on Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now, one more big change to announce. We are now OSTG- Open Source Technology Group. Come see the changes on the new OSTG site. www.ostg.com _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel