Re: [linux-usb] power management (WAS Re: [linux-usb] OHCI crash)

From: Benjamin Herrenschmidt (bh40@calva.net)
Date: Thu Mar 23 2000 - 05:01:27 EST


On Wed, Mar 22, 2000, Henroid, Andrew D <andrew.d.henroid@intel.com> wrote:

>I'm curious.. Have you encountered a device that needs
>interrupts to save/restore device context or is this
>speculation?

The framebuffer may need a vmalloc. For now, that's the only case we have
on powerbooks.

I speculate the need for interrupts from some work I've done on device
drivers on MacOS. I admit that on Linux, I didn't need them. However, our
PowerBook sleep code may not be very robust if there is lot of activity
on the IDE or SCSI while going to sleep. (What would happen if the sleep
occur in the middle of an ATAPI command, after the command is sent and
before the reply is reveived).

Well, after more thinking, I beleive we can live with interrupts disabled
in probably all cases since we can always do polling. We need a "step 1"
that occurs with interrupts enabled and before disks are sync'ed and
before block devices are put to sleep for the rare drivers that may to do
vmalloc-like stuffs (fb).
In fact, shared interrupts, as Alan pointed to me, are a real hell that
simply cannot be handled if interrupts are enabled. So yes, step 2 in my
scheme can probably be removed. But we still need step 1.

>What about requests from above the driver? Are you blocking
>userspace and all activity within the kernel? (eg. the
>network stack)

Well, that's a good question ;) Our current driver triggers the sleep
from an ioctl and powerbooks are all UP, so we don't have problem with
userspace activity or BHs (do we ?). Currently, we only block devices
themselves. We don't yet have specific code to block request queues or
things like that, but I beleive that our code is not very robust if a lot
of IO activity is happening when sleep is triggered. The pre-emptive
kernel patches may cause more issues. For example, if for any reason, an
IDE request arrives to the ide.c driver after the controller have been
put to sleep, we are dead. That's why the actual sleep of the controller
is done is the last step, with interrupts disabled. There are other
issues, for example, printk calling the fb dev, itself using the 2D
accelerator, so a printk can crash if issues after the display was put to
sleep.
We currently handle those problems by prioritizing the sleep queues with
hard-coded per-device priority values. This is ok for PowerBooks since
they have a known limted range of hardware. Ideally, this should be
handled by a dependency tree (for example, the IDE depends on the
hot-swap media-bay and so the bay must be put to sleep after the IDE).

>I'm not sure that the solution is in adding in more stages.
>With your 2 or 3 stage protocols, there is always the possibility
>that a request (from above or below) is going to arrive between
>a driver returning OK to the first stage sleep request and
>subsequent stages. Multiple stages are a pain for driver
>writers to have to implement and for little benefit.

Well, you may well be right. The multiple stage is easy to implement when
the OS driver model is based on a strict request queue mecanism (that is
the case on MacOS, well almost...). But on Linux, I beleive a 2 stage
would be enough. Most device don't do anything in the first stage. Only
the rare devices that may need to allocate some backup storage need to do
something there since they need the swapper to be working. They don't
actually put the device to sleep in stage 1, but just allocate necessary
backup storage.

>Wouldn't it be better for the driver just to be able to stop
>the process of going to sleep asynchronously, whenever it
>receives a request? This is the purpose of the "pm_access"
>call in the generic power management interface. (Yes, the
>implementation doesn't really do anything right now.)

Well, you close your portable lid, and then, because an IDE request is
still pending somewhere, your machine will wake back up with the lid
closed. This can be bad, especially with some machines that have heat
problems when running with the lid closed.

> 1. Send all drivers a suspend request
> 2. Save contents of memory to disk (yes, special handling
> for storage devices)

Well, you need the disk drivers to be still alive at this point. That can
be a problem if the underlying device was already suspended. It has to be
woken up and suspended again to handle the request. Also, some machines
don't need the save-to-disk (this feature is useful when you actually
shut the machine down instead of putting it to sleep).

> 3. Disable interrupts
> 4. Enter sleep
> [sleep for some time...]
> 5. Send all drivers a wake/resume request
> 6. Enable interrupts
>
>Anytime between steps 1 and 4, a driver can interrupt the
>process of going to sleep. For balance, step 6 should
>really come before step 5 but it needs to be in this order
>to work around buggy hardware like Alan's OHCI card.

I would prefer:

 1. Send all drivers a "sleep request" request. (If one driver refuse it
for any reason, then it returns an error and a special "sleep canceled"
is sent to all driver that accepted the sleep request).

 2. disable interrupts

 3. Send all driver a "sleep now". This is synchronous.

 4. Put the machine to sleep

 Then, wakeup:

 5. Send all driver a "wake now" request

 6. Enable interrupts

 7. Send all drivers a "woken up" request for additional cleanup
    and freeing memory allocated in step 1.

IMHO, asynchronous handling of sleep would be way too complex and cause
more problems than it solves.

Ben.

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



This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:38 EST