linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Hilman <khilman@deeprootsystems.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-pm@lists.linux-foundation.org,
	Partha Basak <p-basak2@ti.com>,
	linux-omap@vger.kernel.org
Subject: Re: [linux-pm] runtime_pm_get_sync() from ISR with IRQs disabled?
Date: Fri, 24 Sep 2010 11:54:36 -0700	[thread overview]
Message-ID: <87ocbnas5v.fsf@deeprootsystems.com> (raw)
In-Reply-To: Pine.LNX.4.44L0.1009241104540.1744-100000@iolanthe.rowland.org

Alan Stern <stern@rowland.harvard.edu> writes:

> On Thu, 23 Sep 2010, Kevin Hilman wrote:
>
>> Hello,
>> 
>> Looking for advice for a little runtime PM dilemma...
>> 
>> After some inactivity, a driver decides to supend iteslf using
>> pm_runtime_put_sync().
>> 
>> The device is now suspended, it's ->runtime_suspend() method has
>> disabled its clock, so its registers cannot be accessed anymore.
>> 
>> Now, as interrupts are still enabled, an interrupt for this device might
>> still arrive.  For example, if this device is a wakeup source, its
>> ->runtime_suspend() method may not have masked its interrupt.
>
> Right.
>
>> So, the IRQ fires, and the drivers ISR is called.  The driver wants to
>> access the device registers, but since it has been runtime suspended,
>> it's registers are not available.
>> 
>> The first reflex would be to simply do a pm_runtime_get_sync() in the
>> ISR, however this is not safe if the ISR is an IRQs-disabled handler (as
>> is the case for me, where the problematic handler is chained handler
>> used for demuxing GPIO IRQs.)
>
> An ISR shouldn't call pm_runtime_get_sync() in any case.
>
>> So, what is the "right" thing to do here?
>
> You should call pm_runtime_get(), turn off the interrupt source, and
> return.  Then your resume routine should check for an outstanding
> interrupt or wakeup request and handle it (the easiest way may be 
> simply to call the ISR).

For a "normal" device driver, your solution makes complete sense.  The
only catch is that it introduces potentically significant latency in the
interrupt handling and it requires the interrupt source to be masked,
potentially loosing other interrupts, while waiting for the runtime PM
workqueue to schedule.  For chained handlers in particular, this means
that *all* interrupts managed by the chained handler would be masked for
this additional time.  Not good.

The problematic device for me as an on-chip GPIO controller, and the ISR
in question is a chained handler (run with interrupts disabled) which
does the GPIO demux and then dispatches to the actual ISR.  Following the
above approach means that all GPIO interrupts (in that bank) would be
masked until ->runtime_resume() is called.  For a GPIO bank with
multiple edge-triggered IRQs, masked IRQs for that amount of time could
mean several missed interrupts while waiting.

For example, Here's what would happen:

- IRQ arrives
- ISR: [chained handler, called with IRQs disabled ]
  if (pm_runtime_suspended()) {
      pm_runtime_get()
      <mask the GPIO bank interrupt>
      /* starting now, we miss edge-triggered IRQs in this bank */
      state->irq_pending = true;
      return;
  }

... some time later (scheduler latency, other hard IRQs, soft IRQs?, etc.) ...

- pm_runtime_work()
      /* IRQs disabled */
      __pm_runtime_resume()
          /* IRQs enabled */
          bus->runtime_resume()
              driver->runtime_resume()
          /* IRQs disabled */
     /* IRQs enabled */

And in the driver's runtime_resume method()

  if (state->irq_pending) {
      /* disable IRQs */
      <call GPIO demux ISR, which will finally unmask the bank IRQ>
      /* enable IRQs */
      /* Here, we can finally receive interrupts on that bank again. */ 
  }
      
Not only is the additional interrupt latency a problem, but any other
drivers hooked up to these IRQs may have requested IRQF_DISABLED
handlers, expecting to be called in interrupt context with interrupts
disabled, which clearly will not be the case.  Hoever, this isn't a
major concern as we don't (currently) have IRQF_DISABLED handlers hooked
up to GPIO IRQs (that I know of.)

>> A quick hack would be to for the drivers ISR to do a
>> pm_runtime_get_noresume() and directly call the its ->runtime_resume()
>> method, then do its normal stuff, followed by a pm_runtime_put() at the
>> end of the ISR.
>> 
>> Is this an acceptable hack given that it's only needed for the
>> increasingly rare cases of ISRs with interrupts disabled?
>> 
>> Or should we think of making a version of _get_sync() that is safe for
>> IRQs disabled contexts like this where we know the device is already
>> RPM_SUSPENDED?
>> 
>> Any advice appreciated...
>
> You're trying to fight the runtime-PM design instead of using it as it 
> was intended.  We already have an API for starting a resume from 
> interrupt context, and that's what you should use.

It may seem like I'm trying to fight the design, but I'm actually trying
to find ways to use it.  I want to use the API (and we're using it
successfully in most of our drivers now.)  The problem is only in a few
of these corner cases where using it introduces significant changes from
previous behavior like introducing long, unbounded windows for missed
interrupts.

Kevin

  reply	other threads:[~2010-09-24 18:54 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-24  0:05 runtime_pm_get_sync() from ISR with IRQs disabled? Kevin Hilman
2010-09-24 15:13 ` [linux-pm] " Alan Stern
2010-09-24 18:54   ` Kevin Hilman [this message]
2010-09-24 20:04     ` Rafael J. Wysocki
2010-09-27 13:57       ` Alan Stern
2010-09-27 20:00         ` Rafael J. Wysocki
2010-09-27 20:39           ` Alan Stern
2010-09-27 21:09             ` Rafael J. Wysocki
2010-09-28 14:55               ` Alan Stern
2010-09-28 18:19                 ` Rafael J. Wysocki
2010-09-30 18:25                   ` [PATCH] PM: add synchronous runtime interface for interrupt handlers Alan Stern
2010-09-30 20:15                     ` Rafael J. Wysocki
2010-09-30 21:42                       ` Alan Stern
2010-09-30 22:41                         ` Rafael J. Wysocki
2010-10-01 14:28                           ` Alan Stern
2010-10-01 21:23                             ` Rafael J. Wysocki
2010-10-02 14:12                               ` Alan Stern
2010-10-02 22:06                                 ` Rafael J. Wysocki
2010-10-03 15:52                                   ` Alan Stern
2010-10-03 20:33                                     ` Rafael J. Wysocki
2010-10-05 21:44                                 ` Kevin Hilman
2010-10-06 15:58                                   ` Alan Stern
2010-10-06 19:33                                     ` Rafael J. Wysocki
2010-10-06 19:35                                     ` Kevin Hilman
2010-10-06 20:28                                       ` Alan Stern
2010-10-06 21:47                                         ` Rafael J. Wysocki
2010-10-07 15:26                                           ` Alan Stern
2010-10-07 16:52                                             ` Kevin Hilman
2010-10-07 17:35                                               ` Alan Stern
2010-10-07 21:11                                                 ` Rafael J. Wysocki
2010-10-07 23:15                                                   ` Kevin Hilman
2010-10-07 23:37                                                     ` Rafael J. Wysocki
2010-10-07 23:55                                                       ` Kevin Hilman
2010-10-08 16:22                                                         ` Alan Stern
2010-10-08 21:04                                                           ` Kevin Hilman
2010-10-08 19:57                                                         ` Rafael J. Wysocki
2010-10-08 16:18                                                   ` Alan Stern
2010-10-08 19:53                                                     ` Rafael J. Wysocki
2010-10-09 11:09                                                       ` [linux-pm] " Rafael J. Wysocki
2010-10-11 17:00                                                         ` Alan Stern
2010-10-11 22:30                                                           ` Rafael J. Wysocki
2010-11-19 15:45                                           ` [PATCH ver. 2] " Alan Stern
2010-11-20 12:56                                             ` Rafael J. Wysocki
2010-11-20 16:59                                               ` Alan Stern
2010-11-20 19:41                                                 ` [linux-pm] " Alan Stern
2010-11-21 23:45                                                   ` Rafael J. Wysocki
2010-11-21 23:41                                                 ` Rafael J. Wysocki
2010-11-22 15:38                                                   ` Alan Stern
2010-11-22 23:01                                                     ` Rafael J. Wysocki
2010-11-23  3:19                                                       ` Alan Stern
2010-11-23 22:51                                                         ` Rafael J. Wysocki
2010-11-24  0:11                                                           ` Kevin Hilman
2010-11-24 16:43                                                             ` Alan Stern
2010-11-24 18:03                                                               ` Kevin Hilman
2010-11-24 14:56                                                           ` Alan Stern
2010-11-24 20:33                                                             ` Rafael J. Wysocki
2010-11-25 15:52                                                               ` [PATCH ver. 3] " Alan Stern
2010-11-25 18:58                                                                 ` [linux-pm] " Oliver Neukum
2010-11-25 20:03                                                                   ` Rafael J. Wysocki
2010-11-26 22:23                                                                 ` Rafael J. Wysocki
2010-10-06 23:51                                         ` [PATCH] " Kevin Hilman
2010-09-30 22:02                     ` Rafael J. Wysocki
2010-10-01 14:12                       ` Alan Stern
2010-10-01 21:14                         ` Rafael J. Wysocki
2010-09-27 21:11             ` [linux-pm] runtime_pm_get_sync() from ISR with IRQs disabled? Kevin Hilman
2010-09-24 20:27     ` Alan Stern
2010-09-24 21:52       ` Kevin Hilman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ocbnas5v.fsf@deeprootsystems.com \
    --to=khilman@deeprootsystems.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=p-basak2@ti.com \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).