I don't think so. What I have in mind is situations where there
accessed has already been synchronized by other means, while the
prepare() method is running. For example:
Task 0 Task 1
------ ------
->prepare() is called
Waits for currently-running
registration in task 1
to finish
Does other stuff
Receives a request to register
a new child under dev
Sees that dev->power.state is
still DPM_ON, so goes ahead
with the child's registration
->prepare() returns
dev->power.state is set to
DPM_SUSPENDING
device_pm_add() checks
dev->power.state and fails
the registration
If dev->power.state had been set to DPM_PREPARING before ->prepare()
was called, then task 1 would have avoided trying to register the
child.
True, it can't be removed at this point. But it _can_ be removed
between the calls to resume_device() and mutex_lock().
It will still work correctly. If dpm_list is empty then dpm_list->prev
is equal to &dpm_list, so it will do the same thing as your current
code does.
I just thought of another problem. At the point where
local_irq_disable() is called, in between device_suspend() and
device_power_down(), it is possible in a preemptible kernel that
another task is holding dpm_list_mtx and is in the middle of updating
the list pointers. This would mess up the traversal in
device_power_down().
I'm not sure about the best way to prevent this. Is it legal to call
unlock_mutex() while interrupts or preemption are disabled?
Alan Stern
--