- Linux Kernel Programming by Kaiwan N Billimoria, Packt Publishing, March 2021, Ch 6
- in_task() See line 121
- struct task_struct From line 723
- current pointer For example, current --> pid
- A user application normally runs in unprivileged mode, in user space. Contexts for execution of kernel code by user applications:
- Process context - kernel code is executed from a system call or a processor exception (e.g., page fault). Synchronous
- Interrupt context - kernel code (e.g., device driver's interrupt handler) is executed from a peripheral chip's HW interrupt. Asynchronous.
- Kernel mode threads are application which execute exclusively in kernel space, in process context.
- Each process in user space has dedicated virtual memory containing the following segments:
- Text segment - machine code
- Data setments - global and static data:
- Initialized data segment
- Uninitialized data segment (bss), may be auto-initialized to 0 at run-time
- Heap segment - for dynamic allocation, grows up from lower addresses
- Libraries (text data) - shared libraries which a process may dynamically link into
- Stack - Captures high-level lanaguage function calling flow, including call/return sequence, parameter passing, local variable instantiation, return value.
Stack allocation is architecture dependent, but normally grows down towards lower addresses.
A stack frame is allocated and appropriately initialized on every funciton call. Details of stack frame layout are architecture dependent, a SP (Stack Pointer) register normally will be used to point to current frame at top of stack
- Each thread (user as well as kernel) in kernel space has a dedicated task_struct which contains all attributes related to the thread.
- Each user space thread has 2 stacks, one in user space and a second in kernel space, each of which monitors thread execution when the thread executes in user or kernel space respectively.
- Kernel space threads have only 1 stack, in kernel space. The kernel mode stacks are normally fixed size and relatively small.
- getrlimit / setrlimit may be used to get/set resource limits, in particular to set max size of user space stack.
- A dedicated stack per CPU may be allocated by architecture for interrupt handling, to avoid overloading the kernel mode stack of the thread which was interrupted.
Reference diagram on page 81 of Linux Kernel Programming diagrams
- ps aux
- Print list (including pids) of all running processes
- cat /proc/< pid >/stack
- Dumps kernel space stack (call frame per line)
- gstack
- Outputs user space stack
- strace()
- trace system calls
- ltrace()
- trace library calls
- ps -LA
- Prints pid field of task structure (under LWP = LightWeight Process or thread column) and tgid (Thread Group member, which is actually the process id, under PID column)
- In case process is single thread, pid = tgid.
- In multithreaded, tgid is unique per thread
- Code samples: git clone
- current_affairs
- thrd_showall
- Iterate over tasks in kernel's task lists to display all live processes (using for_each_process() macro),
- Or all threads within each process (using the pair of do_each_thread() {...} while_each_thread() macros.
- main() thread's current--> mm points to a structure of type mm_struct, which represents the entire process' user space mapping.
- If current-->mm is NULL, it means this process has no user space mapping so it must be a kernel thread.