[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

powerhooks, detaches, and activates/deactivate



I'd like to start off by discussing the required features:

Power management
----------------

Standy/Suspend/hibernate/resume works flawlessly.

Device detach
-------------

Devices disappear and their name (e.g. wd3) can be reused. Device
driver does not hang the machine waiting for a device that
isn't there.

Things that would be nice but not absolutely critical:

1) No memory leaks on detach 
2) Ability to reattach and rebind hardware


Current mechanisms
------------------

powerhook_establish/powerhook_disestablish
------------------------------------------

Any part of the kernel can register a powerhook. The hook gets
called with either PWRSTANDY, PWRSUSPEND, or PWRRESUME (to describe
3 different levels of power-down). 

Currently, there are no guarantees of the context the powerhooks, so
the user must assume that it is called in interrupt context.

It is a really bad thing for a powerhook to sleep because, aside from
possibly being called in interrupt context, some device may have
already shut themselves down. As other processes try to access those
devices, they will get back errors (like ENXIO).

The powerhook interface does not specify an order in which the
powerhooks are called.

The powerhooks are only called once per power event. Devices that use
powerhooks need to make sure they've done everything they need to
BEFORE they return from the powerhook.

Device driver activate method
-----------------------------

The device drivers can have an optional activate method that supports
one of two sorts of messages DVF_ACTIVATE and DVF_DEACTIVATE.

The pcmcia driver, on suspend and resume, fires a
DVF_ACTIVATE/DVF_DEACTIVATE messages down the device tree attached to
it. This is done using the config_activate and config_deactivate
methods provided in ker/subr_autoconf.c.

The driver activate method can be called in interrupt context. This
means that if the driver wants to complete any activity with the
device, it will need to poll the device. So, it is probably sensible
for most device drivers to abort the current task and possibly retry
it on resume.

This may not work well for non-idempotent operations or critical
tasks (firmware downloads??).

Actually, what I said above about the device driver completing its
activity on receiving DVF_DEACTIVATE is bogus in the current
implementation. This is because DVF_DEACTIVATE is also sent to the
device on forcible detach - so the device might not even be there!
Whoops!
(and of course, even if the device was there when you started polling,
the device may be detached WHILE you're polling, anyway, so all
polling loops should have timeouts)

ACTIVATE and DEACTIVATE don't tell you what power level you're going
down to. However, the device driver should probably be coded to resume
from virtually any power level.


Device driver detach 
--------------------

The detach method of a device driver is called from process
context. It is called when the user has requested a remove or forcibly
removed a device (though many drivers don't actually care about the
difference).

The theory here (I guess) is that the detach method can sleep and wait
for device activity to end. It can call other functions that may need
to sleep.  This of course, is only really relevant on gentle detach.
Unfortunately, DVF_DEACTIVATE is sent even on a gentle detach. Since
DVF_DEACTIVATE can be sent on power down and forcible detach too, the
device has to assume the worst and abort everything.

When the detach method returns, the device is removed from any cd_devs
array it was a part of, thus "disappearing from existence".

There is some time between DVF_DEACTIVATE and detach being called -
namely the process calling detach needs to be scheduled. I propose
that any process trying to poke the device between get an ENXIO.

============
Difficulties
============

Figuring out when it's safe to free the device_softc can be quite
annoying. There can be pointers to device_softc on the stack, in the
heap. There are often circular references between parent and child
devices so a naive ref counting scheme doesn't necessarily work.

Filesystem detach is not a pretty sight. It'll be a large source of
hangs and panics.  Filesystems (except for arla and NFS) are written
assuming that the storage medium is reliable and there. They issue
reads and writes and don't check the return value (what would they do
on an error anyway?)

-Costa




Visit your host, monkey.org