forked from Minki/linux
e81b75f7b2
SYNC in __switch_to() is a historic relic and not needed at all. - In UP context it is obviously useless, why would we want to stall the core for all updates to stack memory of t0 to complete before loading kernel mode callee registers from t1 stack's memory. - In SMP, there could be potential race in which outgoing task could be concurrently picked for running on a different core, thus writes to stack here need to be visible before the reads from stack on other core. Peter confirmed that generic schedular already has needed barriers (by way of rq lock) so there is no need for additional arch barrier. This came up when Noam was trying to replace this SYNC with EZChip specific hardware thread scheduling instruction for their platform support. Link: http://lkml.kernel.org/r/20151102092654.GM17308@twins.programming.kicks-ass.net Cc: Peter Zijlstra <peterz@infradead.org> Cc: linux-kernel@vger.kernel.org Cc: Noam Camus <noamc@ezchip.com> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
63 lines
1.7 KiB
ArmAsm
63 lines
1.7 KiB
ArmAsm
/*
|
|
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* Vineetg: Aug 2009
|
|
* -Moved core context switch macro out of entry.S into this file.
|
|
* -This is the more "natural" hand written assembler
|
|
*/
|
|
|
|
#include <linux/linkage.h>
|
|
#include <asm/entry.h> /* For the SAVE_* macros */
|
|
#include <asm/asm-offsets.h>
|
|
|
|
#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4)
|
|
|
|
;################### Low Level Context Switch ##########################
|
|
|
|
.section .sched.text,"ax",@progbits
|
|
.align 4
|
|
.global __switch_to
|
|
.type __switch_to, @function
|
|
__switch_to:
|
|
|
|
/* Save regs on kernel mode stack of task */
|
|
st.a blink, [sp, -4]
|
|
st.a fp, [sp, -4]
|
|
SAVE_CALLEE_SAVED_KERNEL
|
|
|
|
/* Save the now KSP in task->thread.ksp */
|
|
#if KSP_WORD_OFF <= 255
|
|
st.as sp, [r0, KSP_WORD_OFF]
|
|
#else
|
|
/* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */
|
|
add2 r24, r0, KSP_WORD_OFF
|
|
st sp, [r24]
|
|
#endif
|
|
/*
|
|
* Return last task in r0 (return reg)
|
|
* On ARC, Return reg = First Arg reg = r0.
|
|
* Since we already have last task in r0,
|
|
* don't need to do anything special to return it
|
|
*/
|
|
|
|
/*
|
|
* switch to new task, contained in r1
|
|
* Temp reg r3 is required to get the ptr to store val
|
|
*/
|
|
SET_CURR_TASK_ON_CPU r1, r3
|
|
|
|
/* reload SP with kernel mode stack pointer in task->thread.ksp */
|
|
ld.as sp, [r1, (TASK_THREAD + THREAD_KSP)/4]
|
|
|
|
/* restore the registers */
|
|
RESTORE_CALLEE_SAVED_KERNEL
|
|
ld.ab fp, [sp, 4]
|
|
ld.ab blink, [sp, 4]
|
|
j [blink]
|
|
|
|
END(__switch_to)
|