Skip to content

Commit fd47619

Browse files
committed
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 <[email protected]>
1 parent b060b7d commit fd47619

File tree

5 files changed

+20
-23
lines changed

5 files changed

+20
-23
lines changed

arch/arc/include/asm/processor.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
* struct thread_info
2323
*/
2424
struct thread_struct {
25-
unsigned long ksp; /* kernel mode stack pointer */
2625
unsigned long callee_reg; /* pointer to callee regs */
2726
unsigned long fault_address; /* dbls as brkpt holder as well */
2827
#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
@@ -54,7 +53,7 @@ struct task_struct;
5453
* Where about of Task's sp, fp, blink when it was last seen in kernel mode.
5554
* Look in process.c for details of kernel stack layout
5655
*/
57-
#define TSK_K_ESP(tsk) (tsk->thread.ksp)
56+
#define TSK_K_ESP(tsk) (task_thread_info(tsk)->ksp)
5857

5958
#define TSK_K_REG(tsk, off) (*((unsigned long *)(TSK_K_ESP(tsk) + \
6059
sizeof(struct callee_regs) + off)))

arch/arc/include/asm/thread_info.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@
3737
*/
3838
struct thread_info {
3939
unsigned long flags; /* low level flags */
40+
unsigned long ksp; /* kernel mode stack top in __switch_to */
4041
int preempt_count; /* 0 => preemptable, <0 => BUG */
41-
struct task_struct *task; /* main task structure */
42-
__u32 cpu; /* current CPU */
42+
int cpu; /* current CPU */
4343
unsigned long thr_ptr; /* TLS ptr */
44+
struct task_struct *task; /* main task structure */
4445
};
4546

4647
/*
47-
* macros/functions for gaining access to the thread information structure
48-
*
49-
* preempt_count needs to be 1 initially, until the scheduler is functional.
48+
* initilaize thread_info for any @tsk
49+
* - this is not related to init_task per se
5050
*/
5151
#define INIT_THREAD_INFO(tsk) \
5252
{ \

arch/arc/kernel/asm-offsets.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ int main(void)
2020

2121
BLANK();
2222

23-
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
2423
DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg));
2524
DEFINE(THREAD_FAULT_ADDR,
2625
offsetof(struct thread_struct, fault_address));
2726

2827
BLANK();
2928

29+
DEFINE(THREAD_INFO_KSP, offsetof(struct thread_info, ksp));
3030
DEFINE(THREAD_INFO_FLAGS, offsetof(struct thread_info, flags));
3131
DEFINE(THREAD_INFO_PREEMPT_COUNT,
3232
offsetof(struct thread_info, preempt_count));

arch/arc/kernel/ctx_sw_asm.S

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
#include <asm/entry.h> /* For the SAVE_* macros */
1212
#include <asm/asm-offsets.h>
1313

14-
#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4)
15-
1614
; IN
1715
; - r0: prev task (also current)
1816
; - r1: next task
@@ -37,19 +35,19 @@ ENTRY_CFI(__switch_to)
3735
/* kernel mode callee regs of @prev */
3836
SAVE_CALLEE_SAVED_KERNEL
3937

40-
/* save final SP to @prev->thread.ksp */
41-
#if KSP_WORD_OFF <= 255
42-
st.as sp, [r0, KSP_WORD_OFF]
43-
#else
44-
/* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */
45-
add2 r10, r0, KSP_WORD_OFF
46-
st sp, [r10]
47-
#endif
38+
/*
39+
* save final SP to @prev->thread_info.ksp
40+
* @prev is "current" so thread_info derived from SP
41+
*/
42+
GET_CURR_THR_INFO_FROM_SP r10
43+
st sp, [r10, THREAD_INFO_KSP]
44+
4845
/* update @next in _current_task[] and GP register caching it */
4946
SET_CURR_TASK_ON_CPU r1, r10
5047

51-
/* load SP from @next->thread.ksp */
52-
ld.as sp, [r1, KSP_WORD_OFF]
48+
/* load SP from @next->thread_info.ksp */
49+
ld r10, [r1, TASK_THREAD_INFO]
50+
ld sp, [r10, THREAD_INFO_KSP]
5351

5452
/* restore callee regs, stack frame regs of @next */
5553
RESTORE_CALLEE_SAVED_KERNEL

arch/arc/kernel/process.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ asmlinkage void ret_from_fork(void);
141141
* | unused |
142142
* | |
143143
* ------------------
144-
* | r25 | <==== top of Stack (thread.ksp)
144+
* | r25 | <==== top of Stack (thread_info.ksp)
145145
* ~ ~
146146
* | --to-- | (CALLEE Regs of kernel mode)
147147
* | r13 |
@@ -181,14 +181,14 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
181181
c_callee = ((struct callee_regs *)childksp) - 1;
182182

183183
/*
184-
* __switch_to() uses thread.ksp to start unwinding stack
184+
* __switch_to() uses thread_info.ksp to start unwinding stack
185185
* For kernel threads we don't need to create callee regs, the
186186
* stack layout nevertheless needs to remain the same.
187187
* Also, since __switch_to anyways unwinds callee regs, we use
188188
* this to populate kernel thread entry-pt/args into callee regs,
189189
* so that ret_from_kernel_thread() becomes simpler.
190190
*/
191-
p->thread.ksp = (unsigned long)c_callee; /* THREAD_KSP */
191+
task_thread_info(p)->ksp = (unsigned long)c_callee; /* THREAD_INFO_KSP */
192192

193193
/* __switch_to expects FP(0), BLINK(return addr) at top */
194194
childksp[0] = 0; /* fp */

0 commit comments

Comments
 (0)