On Wed, 22 Sep 2004, David Brownell wrote:
> > Or put it another way: if the semaphore was used for _everything_, and not
> > just by the PM core but by drivers as well so that the entire driver model
> > was completely serialized, then again there wouldn't be any deadlock.
>
> I don't see how that would solve anything. Unless you mean to
> suggest that everything could always assume the lock was held,
> in which case it wouldn't protect against anything ... :)
>
> The root cause of the self-deadlocks is that the driver model
> code has to be re-entrant, so that logic in suspend/resume
> paths can do things that can be done at other times too. That
> means the locking mustn't be context-dependent, and the lock
> scope must shrink to something sane (like, not held during
> potentially long-lasting outcalls).
The context-dependency problems are solved by making the semaphore public,
not private to the PM core. If the core required callers to hold the
lock, and always invoked callbacks with the lock held, then there wouldn't
be any deadlock.
The scope problem is something else. I'm saying that by increasing the
scope greatly, deadlock can be prevented. Of course this just worsens the
situation with regard to potentially long-lasting callbacks and such. In
fact it makes things as bad as possible: all operations are completely
serialized. That's why I didn't say this was the right thing to do -- I
only said it would prevent deadlock.
> > Ah, but if _all_ those tasks, in addition to power management, used
> > dpm_sem then there wouldn't be any interference. Just blockage and
> > slowdowns. (Not that I'm advocating this -- per-device locking like in
> > USB is the best way to go.)
>
> Again, I don't see how the re-entrancy issues would be addressed.
If the PM core required callers to hold the semaphore then it would never
have to acquire the semaphore itself. Hence re-entrancy wouldn't matter.
> > By the way, the PM lists aren't necessary. By using the existing list
> > pointers in the device structure it's possible to do a proper tree
> > traversal with bounded stack usage. I don't know if anyone's interested
> > in that...
>
> I've had the same thought about bounded memory, but I don't think
> they'd work well without separate PM lists. At least without
> adding rude "whole system is serialized" constraints ...
>
> I do want to add PMcore primitives to walk a (sub)tree in constant
> stak space, so that USB can rely on that to ensure subtrees (as for
> example USB hub to USB-storage to SCSI-Host to SCSI-Disk) can work
> even when they jump out of the USB domain.
The existing PM data structures aren't quite up to the job. But if the
children of each parent were linked in a "siblings" list (which struct
device does include but struct dev_pm_info doesn't) it would be possible.
Here's the algorithm for the device tree (not the PM tree). Locking
optional... :-)
void walk_sub_tree(struct device *start_dev) {
struct device *d = start_dev;
for (;;) {
// Pre-order traversal tasks go here
if (!list_empty(d->children)) {
d = d->children.next;
continue;
}
up_one_level:
// Post-order traversal tasks go here
if (d == start_dev)
break;
if (d->parent == d->node.next) {
d = d->parent;
goto up_one_level;
}
d = d->node.next;
}
}
You might want to change the .next's to .prev's for the resume traversal,
to make it the reverse of the suspend traversal.
Alan Stern
-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel