Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 14: Kernel Activities


On IA-32 systems, the number of the raised interrupt is saved in the most significant 8 bits oforig_eax.
Other architectures use other locations. As mentioned above, some platforms even adopt the approach
of placing the interrupt number on the stack as a direct argument.

IRQ Stacks


The situation described above is only valid if the kernel uses the kernel stack to process IRQs. This need
not always be the case. The IA-32 architecture provides the configuration optionCONFIG_4KSTACKS.^14
If it is activated, the size of the kernel stack is reduced from 8 KiB to 4 KiB. Since the page size is 4 KiB
on this machine, the number of pages necessary to implement the kernel stack is reduced from two
to one. This makes life easier for the VM subsystem when a huge number of processes (or threads) is
active on the system because single pages are easier to find than two consecutive ones as required before.
Unfortunately, 4 KiB might not always be enough for the regular kernel workandthe space required by
IRQ processing routines, so two more stacks come into play:

❑ A stack for hardware IRQ processing.
❑ A stack for software IRQ processing.

In contrast to the regular kernel stack that is allocatedper 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.

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;

Note that the attribute__read_mostlydoesnotrefer to the stack itself, but to the pointer that points to
the appropriate place in memory. This is only manipulated when the stacks are initially allocated, but no
more during the system’s lifetime.

The data structure used for the stacks is not too complicated:

arch/x86/kernel/irq_32.c
union irq_ctx {
struct thread_info tinfo;
u32 stack[THREAD_SIZE/sizeof(u32)];
};

tinfois used to store information about the thread that was running before the interruption occurred
(see Chapter 2 for more details).stackprovides the stack space itself.STACK_SIZEis defined to 4,096
if 4-KiB stacks are enabled, so this guarantees the desired stack size. Note that since aunionis used to
combinetinfoandstack[], the data structure fits into exactly one page frame. This also implies that the
thread information contained intinfois always available on the stack.

(^14) The PowerPC and SuperH architectures provide the configuration optionCONFIG_IRQSTACKSto enable separate stacks for IRQ
processing. Since the mechanism used there is similar, these cases are not discussed separately.

Free download pdf