0

Linux kernel has separate stacks for user mode and kernel mode process and also some special stacks. One of this special stacks is interrupt stack with the size 16 kilobytes placed in the irq_stack_union:

union irq_stack_union {
    char irq_stack[IRQ_STACK_SIZE];
    struct {
        char gs_base[40];
        unsigned long stack_canary;
    };
};

There is definition of the pointer to this stack - irq_stack_ptr. As I understand correctly this irq_stack_ptr must point to the end of the irq_stack or in another words to irq_stack + IRQ_STACK_SIZE - 1, but definition of the irq_stack_ptr is:

DEFINE_PER_CPU(char *, irq_stack_ptr) =
    init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;

Why we subtract 64 bytes from the end of the irq_stack_union.irq_stack here?

Thank you.

  • 1
    I'm not familiar enough with linux internals to answer this, but in other OSes a common trick is to put per-thread data such as the current task/process pointer there, as kernel stacks are usually aligned and fixed size so it's easy to find the top. Maybe linux uses this area to store the current CPU number or to allow code to detect that it's in an interrupt context. Just speculating, though. – user3188445 Aug 22 '15 at 13:22
  • Thank you for answer. I think about this too: "current task/process pointer there", there no need to store cpu number here because we can find it easily with the API that provided by the Linux kernel, but pointer to the previous task_struct very similar. But can't find something in the code – 0xAX Aug 22 '15 at 13:25
  • But how is that API implemented? Using the APIC to get CPU number is probably expensive, so caching it at the top of the stack seems like a plausible optimization. – user3188445 Aug 22 '15 at 15:27
  • There is smp_processor_id macro for this purpose and seems that 64 bytes is too many for the pointer on the previous process or something like this – 0xAX Aug 22 '15 at 16:53
0

It seems like nobody knows anymore.

There has been a 64-byte gap at the end of the irq stack for at least 12 years. It predates git history, and I can't find any good reason for it. Remove it. What's the worst that could happen?

http://git.kernel.org/linus/4950d6d48a0c43cc61d0bbb76fb10e0214b79c66

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.