auto suspend aborts with SD card remove call from pm notifier

From: srinath mannam <hidden>
Date: 2015-08-12 10:25:44

Hi
 
We have seen an issue in autosleep suspend sequence. While validating 
the autosleep in the android setup using POWER input event.
Android version: KitKat
Linux kernel Version: 3.10


Issue description:
1.       Android attempts autosleep with POWER input event.

2.       In autosleep sequence at the time of suspend, suspend_prepare 
will call pm notifier function “mmc_pm_notify” in PM_SUSPEND_PREPARE 
mode.

3.       With mmc pm notifier call mmc card is removed. Connected SD 
card is removal disk.In the removable sd card scenario pm notifier 
function will call the card remove. card remove function send events to 
user space, then user space will acquire the wakeup sources.

4.       Android user space demon has received the card removed events 
and acquires the NETLINK wakeup source for cleanup.

5.       In the same suspend_prepare sequence “try_to_freeze_tasks” 
function is called from freeze_processes function.

6.       try_to_freeze_tasks function has aborted because of pending 
wakeup source NETLINK and returns error to suspend_prepare call.

7.       With above error suspend_prepare calls mmc pm notifier function 
in PM_POST_SUSPEND mode.

8.       With mmc pm notifier call mmc card is detected back.

9.       Android user space demon has received the card detected events 
and releases the NETLINK wakeup source.

10.   Android re-attempts the autosleep and repeats same sequence of 2 
to 9. This goes infinite.

 
 
try_to_freeze_tasks:
In this function all the tasks are going to freeze in while loop before 
end_time and also checks the pm_wakeup_pending condition.
The highlighted part in the below code is checks for the pending wakeup 
sources. In my issue NETLINK is the pending wakeup source.
If I move the highlighted code block to outside of the loop then I did 
not seen any pending wakeup sources, because NETLINK wakeup source is 
released by the time all the tasks are freeze.
At the time of second iteration of the loop the NETLINK wakeup source 
has released, If I did not break the loop with pm_wakeup_pending 
condition check in the first iteration. This is verified in my issue 
scenario.
 
But moving the pm_wakeup_pending condition check outside of the loop may 
not the right solution;
Because there may be scenarios like wakeup sources are based on devices 
which need pm notifier call with PM_POST_SUSPEND.
 
Could you please suggest me the right solution?
 
while (true) {
                todo = 0;
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
                        if (p == current || !freeze_task(p))
                                continue;
                        if (!freezer_should_skip(p))
                                todo++;
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
 
                if (!user_only) {
                        wq_busy = freeze_workqueues_busy();
                        todo += wq_busy;
                }
                if (!todo || time_after(jiffies, end_time))
                        break;
 /----------------------------------------------------------------------
-----------/
                if (pm_wakeup_pending()) {   “This check is true in my 
case because of NETLINK wakeup source is active”
#ifdef CONFIG_PM_SLEEP
                pm_get_active_wakeup_sources(suspend_abort,
                                MAX_SUSPEND_ABORT_LEN);
                log_suspend_abort_reason(suspend_abort);
#endif
                wakeup = true;
                break;
                }
/-----------------------------------------------------------------------
----------/
                /*
                 * We need to retry, but first give the freezing tasks 
some
                 * time to enter the refrigerator.  Start with an 
initial
                 * 1 ms sleep followed by exponential backoff until 8 
ms.
                 */
                usleep_range(sleep_usecs / 2, sleep_usecs);
                if (sleep_usecs < 8 * USEC_PER_MSEC)
                        sleep_usecs *= 2;
        }
 
Thanks & Regards,
Srinath Babu Mannam
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help