3

I know Linux kernel take thread kernel stack as ISR stack before 2.6.32, after 2.6.32, kernel uses separated stack, if wrong, please correct me. Would you tell me when the ISR stack is setup/crated, or destroy if there is. Or tell me the source file name and line number? Thanks in advance.

Updated at Oct 17 2014:

There are several kinds of stack in Linux. Below are 3 major(not all) that I know.

  1. User space process stack, each user space task has its own stack, this is created by mmap() when task is created.
  2. Kernel stack for user space task, one for each user space task, this is created within do_fork()->copy_process()->dup_task_struct()->alloc_thread_info() and used for system_call.
  3. Stack for hardware interruption(top half), one for each CPU(after 2.6), defined in arch/x86/kernel/irq_32.c: DEFINE_PER_CPU(struct irq_stack *, hardirq_stack); do_IRQ() -> handle_irq() -> execute_on_irq_stack() switch the interrupt stack

Please let me know if these are correct or not.

Qiu Yangfan
  • 871
  • 11
  • 25

1 Answers1

2

For Interrupt handler there is IRQ stack. 2 kinds of stack comes into picture for interrupt handler:

  1. Hardware IRQ Stack.
  2. Software IRQ Stack.

In contrast to the regular kernel stack that is allocated per process, the two additional stacks are allocated per CPU. Whenever a hardware interrupt occurs (or a softIRQ is processed), the kernel needs to switch to the appropriate stack. Historically, interrupt handlers did not receive their own stacks. Instead, interrupt handlers would share the stack of the running process, they interrupted. The kernel stack is two pages in size; typically, that is 8KB on 32-bit architectures and 16KB on 64-bit architectures. Because in this setup interrupt handlers share the stack, they must be exceptionally frugal with what data they allocate there. Of course, the kernel stack is limited to begin with, so all kernel code should be cautious.

Pointers to the additional stacks are provided in the following array: arch/x86/kernel/irq_32.c

static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
skaushal
  • 695
  • 3
  • 11