linux-stable/arch/arc/kernel/ctx_sw_asm.S
Vineet Gupta fd476197c6 ARC: __switch_to: move ksp to thread_info from thread_struct
task's arch specific bits are carried in 2 places
 - embedded thread_struct in task_struct
 - associated thread_info (hoisted in task's stack page) and
   syntactically: (thread_info *)(task_struct->stack)

ksp (dynamic kernel stack top) currently lives in thread_struct but
given its deep location in task struct likely to cache miss when
accessed from  __switch_to(). Moving it to thread_info would be more
efficient given proximity to frequently accessed items such as
preempt_count thus very likely to be in cache, specially in schedular
code.

Note however that currently tsk.thread.ksp takes 1 memory access (off
of tsk pointer) while new code tsk->stack.ksp would take 2, but likely
to be in cache. Moreover if task is current the 2nd reference can be
elided and instead derived from SP as (SP & ~(THREAD_SIZE - 1))

All of this also makes __switch_to() code simpler and we can see the 2
ways of retirving ksp (descrobed above) in new code.

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
2023-08-17 20:31:59 -07:00

64 lines
1.4 KiB
ArmAsm

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* 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>
; IN
; - r0: prev task (also current)
; - r1: next task
; OUT
; - r0: prev task (so r0 not touched)
.section .sched.text,"ax",@progbits
ENTRY_CFI(__switch_to)
/* save kernel stack frame regs of @prev task */
push blink
CFI_DEF_CFA_OFFSET 4
CFI_OFFSET r31, -4
push fp
CFI_DEF_CFA_OFFSET 8
CFI_OFFSET r27, -8
mov fp, sp
CFI_DEF_CFA_REGISTER r27
/* kernel mode callee regs of @prev */
SAVE_CALLEE_SAVED_KERNEL
/*
* save final SP to @prev->thread_info.ksp
* @prev is "current" so thread_info derived from SP
*/
GET_CURR_THR_INFO_FROM_SP r10
st sp, [r10, THREAD_INFO_KSP]
/* update @next in _current_task[] and GP register caching it */
SET_CURR_TASK_ON_CPU r1, r10
/* load SP from @next->thread_info.ksp */
ld r10, [r1, TASK_THREAD_INFO]
ld sp, [r10, THREAD_INFO_KSP]
/* restore callee regs, stack frame regs of @next */
RESTORE_CALLEE_SAVED_KERNEL
pop fp
CFI_RESTORE r27
CFI_DEF_CFA r28, 4
pop blink
CFI_RESTORE r31
CFI_DEF_CFA_OFFSET 0
j [blink]
END_CFI(__switch_to)