Linux内核栈和中断栈
内核栈#define MIN_THREAD_SHIFT(14 + KASAN_THREAD_SHIFT)#define THREAD_SIZE(UL(1) << THREAD_SHIFT)union thread_union {#ifndef CONFIG_THREAD_INFO_IN_TASKstruct thread_info ...
·
内核栈
#define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT)
#define THREAD_SIZE (UL(1) << THREAD_SHIFT)
union thread_union {
#ifndef CONFIG_THREAD_INFO_IN_TASK
struct thread_info thread_info;
#endif
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
注意这里有一个宏来区分stack的实现方式 CONFIG_THREAD_INFO_IN_TASK
,如果定义了该宏,实际上会通过动态申请物理页来作为stack,并且把stack放到 task_struct
结构体中,用 task_struct->stack
来表示。
中断栈
- 对于x86平台:
x86平台上,中断栈是独立于内核栈的存在,两者并不共享,如果是多处理器架构,那么每个CPU都对应有一个中断栈,本文不对x86做介绍。
- 对于 ARM平台:
中断栈和内核栈则是共享的,中断栈和内核栈共享有一个负面因素,如果中断发生嵌套,可能会造成栈溢出,从而可能会破坏到内核栈的一些重要数据。
- 对于ARM64平台:
中断栈的实现是独立的,并且区分两种情况,分别是vmap申请内存,还是直接静态定义,并且根据CPU个数,每个CPU对应单独的一个stack。
arch/arm64/kernel/irq.c:
#ifdef CONFIG_VMAP_STACK
static void init_irq_stacks(void)
{
int cpu;
unsigned long *p;
for_each_possible_cpu(cpu) {
/*
* To ensure that VMAP'd stack overflow detection works
* correctly, the IRQ stacks need to have the same
* alignment as other stacks.
*/
p = __vmalloc_node_range(IRQ_STACK_SIZE, THREAD_ALIGN,
VMALLOC_START, VMALLOC_END,
THREADINFO_GFP, PAGE_KERNEL,
0, cpu_to_node(cpu),
__builtin_return_address(0));
per_cpu(irq_stack_ptr, cpu) = p;
}
}
#else
/* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */
DEFINE_PER_CPU_ALIGNED(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack);
static void init_irq_stacks(void)
{
int cpu;
for_each_possible_cpu(cpu)
per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu);
}
#endif
更多推荐
已为社区贡献6条内容
所有评论(0)