lkml.org 
[lkml]   [2016]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 098/305] cpuidle: Fix cpuidle_state_is_coupled() argument in cpuidle_enter()
    3.16.37-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Daniel Lezcano <daniel.lezcano@linaro.org>

    commit e7387da52028b072489c45efeb7a916c0205ebd2 upstream.

    Commit 0b89e9aa2856 (cpuidle: delay enabling interrupts until all
    coupled CPUs leave idle) rightfully fixed a regression by letting
    the coupled idle state framework to handle local interrupt enabling
    when the CPU is exiting an idle state.

    The current code checks if the idle state is coupled and, if so, it
    will let the coupled code to enable interrupts. This way, it can
    decrement the ready-count before handling the interrupt. This
    mechanism prevents the other CPUs from waiting for a CPU which is
    handling interrupts.

    But the check is done against the state index returned by the back
    end driver's ->enter functions which could be different from the
    initial index passed as parameter to the cpuidle_enter_state()
    function.

    entered_state = target_state->enter(dev, drv, index);

    [ ... ]

    if (!cpuidle_state_is_coupled(drv, entered_state))
    local_irq_enable();

    [ ... ]

    If the 'index' is referring to a coupled idle state but the
    'entered_state' is *not* coupled, then the interrupts are enabled
    again. All CPUs blocked on the sync barrier may busy loop longer
    if the CPU has interrupts to handle before decrementing the
    ready-count. That's consuming more energy than saving.

    Fixes: 0b89e9aa2856 (cpuidle: delay enabling interrupts until all coupled CPUs leave idle)
    Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
    [ rjw: Subject & changelog ]
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    [bwh: Backported to 3.16: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/cpuidle/cpuidle.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    --- a/drivers/cpuidle/cpuidle.c
    +++ b/drivers/cpuidle/cpuidle.c
    @@ -125,7 +125,7 @@ int cpuidle_enter_state(struct cpuidle_d

    time_end = ktime_get();

    - if (!cpuidle_state_is_coupled(dev, drv, entered_state))
    + if (!cpuidle_state_is_coupled(dev, drv, index))
    local_irq_enable();

    diff = ktime_to_us(ktime_sub(time_end, time_start));
    \
     
     \ /
      Last update: 2016-09-17 09:56    [W:4.130 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site