This won't work right if a second IRQ arrives while the first is being
processed. Suppose the kernel driver for the second IRQ doesn't
activate a suspend blocker, and suppose all the userspace handlers for
the first IRQ end (and the opportunistic policy is re-enabled) before
the userspace handler for the second IRQ can start. Then the system
will go back to sleep before userspace can handle the second IRQ.
What? If the suspend blocker API was a one shot styled api, after the
suspend, the one shot is over and the behavior is that you do not fall
back into suspend again until user mode re-enables the one-shot
With what I am proposing the next suspend would not happen until the
user mode code re-enables the suspend blocking behavior. It would much
cleaner for everyone and I see zero down side WRT the example you just
If user mode triggers a suspend by releasing the last blocker, you have
until pm_suspend('mem') turns off interrupts to cancel it. That race
will never go away.
Let me think this through, please check that I'm understanding the issue
1) one-shot policy enable blocker PM suspend behavior;
2) release last blocker and call pm_suspend('mem') and suspend all the
3) get wake up event, one-shot policy over, no-blockers in list
4) go all the way to user mode,
5) user mode decides to not grab a blocker, and re-enables one-shot
6) pm_suspend('mem') called
7) interrupt comes in (say the modem rings)
8) modem driver handler needs to returns fail from pm_suspend call back,
device resumes (I am proposing changing the posted api for doing this.)
9) user mode figures out one-shot needs to be re-enabled and it grabs a
blocker to handle the call and re-enables the one-shot.
So the real problem grabbing blockers from ISR's trying to solve is to
reduce the window of time where a pm_suspend('mem') can be canceled.
My proposal is to;
1) change the kernel blocker api to be
"cancel-one-shot-policy-enable" that can be called from the ISR's for
the wake up devices before the IRQ's are disabled to cancel an in-flight
suspend. I would make it 2 macros one goes in the pm_suspend callback
to return fail, and the other in the ISR to disable the one-shot-policy.
2) make the policy a one shot that user mode must re-enable after each
Would it help if I coded up the above proposal as patch to the current