Chapter 2: Process Management and Scheduling
In principle, individual architectures are, however, free to store whatever they like in thestackpointer
if they signal this to the kernel by setting the pre-processor constant__HAVE_THREAD_FUNCTIONS.Inthis
case, they must provide their own implementations oftask_thread_infoandtask_stack_page,which
allows for obtaining the thread information and the kernel mode stack for a giventask_structinstance.
Additionally, they must implement the functionsetup_thread_stackthat is called indup_task_struct
to create a destination forstack. Currently, only IA-64 and m68k do not rely on the default methods of
the kernel.
On most architectures, one or two memory pages are used to hold an instance ofthread_union.On
IA-32, two pages are the default setting, and thus the available kernel stack size is slightly less than
8 KiB because part is occupied by thethread_infoinstance. Note, though, that the configuration option
4KSTACKSdecreases the stack size to 4 KiB and thus to one page. This is advantageous if a large number
of processes is running on the system because one page per process is saved. On the other hand, it can
lead to problems with external drivers that oftentend to be ‘‘stack hogs,’’ for example, use too much
stack space. All central parts of the kernel that are part of the standard distribution have been designed
to operate smoothly also with a stack size of 4 KiB, but problems can arise (and unfortunately have in the
past) if binary-only drivers are required, which often have a tendency to clutter up the available stack
space.
thread_infoholds process data that needs to be accessed by the architecture-specific assembly language
code. Although the structure is defined differently from processor to processor, its contents are similar to
the following on most systems.
<asm-arch/thread_info.h>
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
unsigned long status; /* thread-synchronous flags */
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable, <0 => BUG */
mm_segment_t addr_limit; /* thread address space */
struct restart_block restart_block;
}
❑ taskis a pointer to thetask_structinstance of the process.
❑ exec_domainis used to implementexecution domainswith which different ABIs (Application
Binary Interfaces) can be implemented on a machine type (e.g., to run 32-bit applications on an
AMD64 system in 64-bit mode).
❑ flagscan hold various process-specific flags, two of which are of particular interest to us:
❑ TIF_SIGPENDINGis set if the process has pending signals.
❑ TIF_NEED_RESCHEDindicates that the process should be or would like to be replaced with
another process by the scheduler.
Other possible constants — some hardware-specific — which are, however, hardly ever used,
are available in<asm-arch/thread_info.h>.
❑ cpuspecifies the number of the CPU on which a process is just executing (important on multi-
processor systems — very easy to determine on single-processor systems).