lkml.org 
[lkml]   [2010]   [Sep]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:x86/idle] x86, hotplug: Move WBINVD back outside the play_dead loop
    Commit-ID:  a68e5c94f7d3dd64fef34dd5d97e365cae4bb42a
    Gitweb: http://git.kernel.org/tip/a68e5c94f7d3dd64fef34dd5d97e365cae4bb42a
    Author: H. Peter Anvin <hpa@linux.intel.com>
    AuthorDate: Fri, 17 Sep 2010 17:06:46 -0700
    Committer: H. Peter Anvin <hpa@linux.intel.com>
    CommitDate: Fri, 17 Sep 2010 17:10:23 -0700

    x86, hotplug: Move WBINVD back outside the play_dead loop

    On processors with hyperthreading, when only one thread is offlined
    the other thread can cause a spurious wakeup on the idled thread. We
    do not want to re-WBINVD when that happens.

    Ideally, we should simply skip WBINVD unless we're the last thread on
    a particular core to shut down, but there might be similar issues
    elsewhere in the system.

    Thus, revert to previous behavior of only WBINVD outside the loop.
    Partly as a result, remove the mb()'s around it: they are not
    necessary since wbinvd() is a serializing instruction, but they were
    intended to make sure the compiler didn't do any funny loop
    optimizations.

    Reported-by: Asit Mallick <asit.k.mallick@intel.com>
    Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
    Cc: Arjan van de Ven <arjan@linux.kernel.org>
    Cc: Len Brown <lenb@kernel.org>
    Cc: Venkatesh Pallipadi <venki@google.com>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.hl>
    LKML-Reference: <tip-ea53069231f9317062910d6e772cca4ce93de8c8@git.kernel.org>
    ---
    arch/x86/kernel/smpboot.c | 11 +++++------
    1 files changed, 5 insertions(+), 6 deletions(-)

    diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
    index 07bf423..55c80ffb 100644
    --- a/arch/x86/kernel/smpboot.c
    +++ b/arch/x86/kernel/smpboot.c
    @@ -1422,9 +1422,9 @@ static inline void mwait_play_dead(void)
    (highest_subcstate - 1);
    }

    + wbinvd();
    +
    while (1) {
    - mb();
    - wbinvd();
    __monitor(&current_thread_info()->flags, 0, 0);
    mb();
    __mwait(eax, 0);
    @@ -1433,11 +1433,10 @@ static inline void mwait_play_dead(void)

    static inline void hlt_play_dead(void)
    {
    + if (current_cpu_data.x86 >= 4)
    + wbinvd();
    +
    while (1) {
    - mb();
    - if (current_cpu_data.x86 >= 4)
    - wbinvd();
    - mb();
    native_halt();
    }
    }

    \
     
     \ /
      Last update: 2010-09-18 02:15    [W:0.023 / U:33.252 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site