lkml.org 
[lkml]   [2017]   [Mar]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC][PATCHv2 4/8] pm: switch to printk.emergency mode in unsafe places
    Date
    It's not always possible/safe to wake_up() printk kernel
    thread. For example, late suspend/early resume may printk()
    while timekeeping is not initialized yet, so calling into the
    scheduler may result in recursive warnings.

    Another thing to notice is the fact PM at some point
    freezes user space and kernel threads: freeze_processes()
    and freeze_kernel_threads(), correspondingly. Thus we need
    printk() to operate in old mode there and attempt to
    immediately flush pending kernel message to the console.

    This patch adds printk_emergency_begin/on sections.

    Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
    ---
    kernel/power/hibernate.c | 8 ++++++++
    kernel/power/suspend.c | 4 ++++
    2 files changed, 12 insertions(+)

    diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
    index a8b978c35a6a..a8c6bb2dbcef 100644
    --- a/kernel/power/hibernate.c
    +++ b/kernel/power/hibernate.c
    @@ -502,6 +502,7 @@ int hibernation_restore(int platform_mode)
    {
    int error;

    + printk_emergency_begin();
    pm_prepare_console();
    suspend_console();
    pm_restrict_gfp_mask();
    @@ -519,6 +520,7 @@ int hibernation_restore(int platform_mode)
    pm_restore_gfp_mask();
    resume_console();
    pm_restore_console();
    + printk_emergency_end();
    return error;
    }

    @@ -542,6 +544,7 @@ int hibernation_platform_enter(void)
    goto Close;

    entering_platform_hibernation = true;
    + printk_emergency_begin();
    suspend_console();
    error = dpm_suspend_start(PMSG_HIBERNATE);
    if (error) {
    @@ -589,6 +592,7 @@ int hibernation_platform_enter(void)
    entering_platform_hibernation = false;
    dpm_resume_end(PMSG_RESTORE);
    resume_console();
    + printk_emergency_end();

    Close:
    hibernation_ops->end();
    @@ -692,6 +696,7 @@ int hibernate(void)
    goto Unlock;
    }

    + printk_emergency_begin();
    pm_prepare_console();
    error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls);
    if (error) {
    @@ -759,6 +764,7 @@ int hibernate(void)
    Exit:
    __pm_notifier_call_chain(PM_POST_HIBERNATION, nr_calls, NULL);
    pm_restore_console();
    + printk_emergency_end();
    atomic_inc(&snapshot_device_available);
    Unlock:
    unlock_system_sleep();
    @@ -868,6 +874,7 @@ static int software_resume(void)
    goto Unlock;
    }

    + printk_emergency_begin();
    pm_prepare_console();
    error = __pm_notifier_call_chain(PM_RESTORE_PREPARE, -1, &nr_calls);
    if (error) {
    @@ -884,6 +891,7 @@ static int software_resume(void)
    Finish:
    __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
    pm_restore_console();
    + printk_emergency_end();
    atomic_inc(&snapshot_device_available);
    /* For success case, the suspend path will release the lock */
    Unlock:
    diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
    index 15e6baef5c73..1f897b149fc0 100644
    --- a/kernel/power/suspend.c
    +++ b/kernel/power/suspend.c
    @@ -433,6 +433,7 @@ int suspend_devices_and_enter(suspend_state_t state)
    if (!sleep_state_supported(state))
    return -ENOSYS;

    + printk_emergency_begin();
    error = platform_suspend_begin(state);
    if (error)
    goto Close;
    @@ -462,6 +463,7 @@ int suspend_devices_and_enter(suspend_state_t state)

    Close:
    platform_resume_end(state);
    + printk_emergency_end();
    return error;

    Recover_platform:
    @@ -520,6 +522,7 @@ static int enter_state(suspend_state_t state)
    #endif

    pr_debug("PM: Preparing system for sleep (%s)\n", pm_states[state]);
    + printk_emergency_begin();
    pm_suspend_clear_flags();
    error = suspend_prepare(state);
    if (error)
    @@ -537,6 +540,7 @@ static int enter_state(suspend_state_t state)
    Finish:
    pr_debug("PM: Finishing wakeup.\n");
    suspend_finish();
    + printk_emergency_end();
    Unlock:
    mutex_unlock(&pm_mutex);
    return error;
    --
    2.12.2
    \
     
     \ /
      Last update: 2017-03-29 11:30    [W:6.021 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site