• Shreyas B. Prabhu's avatar
    powerpc/powernv: Fix race in updating core_idle_state · b32aadc1
    Shreyas B. Prabhu authored
    core_idle_state is maintained for each core. It uses 0-7 bits to track
    whether a thread in the core has entered fastsleep or winkle. 8th bit is
    used as a lock bit.
    The lock bit is set in these 2 scenarios-
     - The thread is first in subcore to wakeup from sleep/winkle.
     - If its the last thread in the core about to enter sleep/winkle
    
    While the lock bit is set, if any other thread in the core wakes up, it
    loops until the lock bit is cleared before proceeding in the wakeup
    path. This helps prevent race conditions w.r.t fastsleep workaround and
    prevents threads from switching to process context before core/subcore
    resources are restored.
    
    But, in the path to sleep/winkle entry, we currently don't check for
    lock-bit. This exposes us to following race when running with subcore
    on-
    
    First thread in the subcorea		Another thread in the same
    waking up		   		core entering sleep/winkle
    
    lwarx   r15,0,r14
    ori     r15,r15,PNV_CORE_IDLE_LOCK_BIT
    stwcx.  r15,0,r14
    [Code to restore subcore state]
    
    						lwarx   r15,0,r14
    						[clear thread bit]
    						stwcx.  r15,0,r14
    
    andi.   r15,r15,PNV_CORE_IDLE_THREAD_BITS
    stw     r15,0(r14)
    
    Here, after the thread entering sleep clears its thread bit in
    core_idle_state, the value is overwritten by the thread waking up.
    In such cases when the core enters fastsleep, code mistakes an idle
    thread as running. Because of this, the first thread waking up from
    fastsleep which is supposed to resync timebase skips it. So we can
    end up having a core with stale timebase value.
    
    This patch fixes the above race by looping on the lock bit even while
    entering the idle states.
    Signed-off-by: default avatarShreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
    Fixes: 7b54e9f213f76 'powernv/powerpc: Add winkle support for offline cpus'
    Cc: stable@vger.kernel.org # 3.19+
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    b32aadc1
idle_power7.S 11.8 KB