Understanding the Linux process kernel stack
When I re-read "LDD3", I found a sentence that I had ignored: "The kernel has a very small stack, it may only be as small as a 4096-byte page." In response to this sentence, I Briefly studied the "kernel stack" of the process.
What is the "kernel stack" of a process? In the life cycle of each process, it will inevitably be trapped in the kernel through system calls. After executing a system call and trapping in the kernel, the stack used by these kernel codes is not the original stack in user space, but a stack in kernel space, which is the "kernel stack" of the process.
For example, a simple character driver implements the open()
method. After this driver is mounted, the application calls the Linux open()
system call through the glib library. When a system call is executed and trapped in the kernel, the processor will transition to privileged mode (the specific transition mechanism varies depending on the processor architecture. For example, for ARM, the stack pointer (SP) in normal mode and user mode is a different register). At this time, the stack pointer used is the kernel stack pointer, which points to the kernel stack space allocated by the kernel for each process.
The role of the kernel stack My personal understanding is: after falling into the kernel, there are also function calls and automatic variables in system calls, which require stack support. The user space stack is obviously unsafe and therefore requires kernel stack support. In addition, the kernel stack is also used to save some application layer information before system calls (for example, user space stack pointer and system call parameters).
Association between kernel stack and process structure Each process will get a kernel stack space when it is created. The correspondence between the kernel stack and the process is completed through the pointer members in the two structures: (1) struct task_struct A structure that must be learned when learning Linux process management. It represents a process in the kernel and records all status information of the process. This structure is defined in Sched.h (include\linux). There is a member void *stack
, which points to the "bottom" of the kernel stack structure below. When the system is running, the macro current
obtains the struct task_struct
structure of the current process.
(2) Kernel stack structure union thread_union
1. union thread_union { 2. struct thread_info thread_info; 3. unsigned long stack[THREAD_SIZE/sizeof(long)]; 4. };
The struct thread_info is a structure that records part of the process information, including process context information:
1. /* 2. \* low level task data that entry.S needs immediate access to. 3. \* __switch_to() assumes cpu_context follows immediately after cpu_domain. 4. */ 5. struct thread_info { 6. unsigned long flags; /* low level flags */ 7. int preempt_count; /* 0 => preemptable, bug */ 8. mm_segment_t addr_limit; /* address limit */ 9. struct task_struct *task; /* main task structure */ 10. struct exec_domain *exec_domain; /* execution domain */ 11. __u32 cpu; /* cpu */ 12. __u32 cpu_domain; /* cpu domain */ 13. struct cpu_context_save cpu_context; /* cpu context */ 14. __u32 syscall; /* syscall number */ 15. __u8 used_cp[16]; /* thread used copro */ 16. unsigned long tp_value; 17. struct crunch_state crunchstate; 18. union fp_state fpstate __attribute__((aligned(8))); 19. union vfp_state vfpstate; 20. \#ifdef CONFIG_ARM_THUMBEE 21. unsigned long thumbee_state; /* ThumbEE Handler Base register */ 22. \#endif 23. struct restart_block restart_block; 24. };
The key is the task member, which points to the struct task_struct structure of the created process
The stack member is the kernel stack. It can be seen from here that the kernel stack space and thread_info share a space. If the kernel stack overflows, thread_info will be destroyed and the system will crash~~~
The relationship between kernel stack—struct thread_info—struct task_struct is shown in the figure below:

Generation of kernel stack
When a process is created, the system call of the fork family will allocate space for the kernel stack and struct task_struct respectively. The calling process is:
System calls of the fork family—>do_fork—>copy_process—>dup_task_struct
In the dup_task_struct function:
1. static struct task_struct *dup_task_struct(struct task_struct *orig) 2. { 3. struct task_struct *tsk; 4. struct thread_info *ti; 5. unsigned long *stackend; 6. 7. int err; 8. 9. prepare_to_copy(orig); 10. 11. **tsk = alloc_task_struct();** 12. if (!tsk) 13. return NULL; 14. 15. **ti = alloc_thread_info(tsk);** 16. if (!ti) { 17. free_task_struct(tsk); 18. return NULL; 19. } 20. 21. err = arch_dup_task_struct(tsk, orig); 22. if (err) 23. goto out; 24. 25. **tsk->stack = ti;** 26. 27. err = prop_local_init_single(&tsk->dirties); 28. if (err) 29. goto out; 30. 31. **setup_thread_stack(tsk, orig);** 32. ......
alloc_task_struct uses the kernel's slab allocator to allocate the space of struct task_struct for the process to be created
Alloc_thread_info uses the kernel's partner system to allocate kernel stack (union thread_union) space for the process to be created
Note:
The following tsk->stack = ti; statement is related to the struct task_struct and the kernel stack
In setup_thread_stack(tsk, orig);, the kernel stack and struct task_struct are associated:
1. static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) 2. { 3. *task_thread_info(p) = *task_thread_info(org); 4. task_thread_info(p)->task = p; 5. }
Kernel stack size
Since each process is allocated a kernel stack space, it is impossible to allocate a large amount. This size is architecture dependent and is generally measured in pages. In fact, it is the THREAD_SIZE we saw above. This value is generally 4K or 8K. For ARM architecture, this is defined in Thread_info.h (arch\arm\include\asm),
1. \#define THREAD_SIZE_ORDER 1 2. \#define THREAD_SIZE 8192 3. \#define THREAD_START_SP (THREAD_SIZE - 8)
So ARM’s kernel stack is 8KB
Issues that need to be paid attention to when programming (kernel) drivers:
Due to the limitation of stack space, when writing drivers (especially low-level functions used by system calls), attention should be paid to avoiding codes that consume a large amount of stack space, such as recursive algorithms, the size of local automatic variable definitions, etc.
The above is the detailed content of Understanding the Linux process kernel stack. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











The five basic components of the Linux system are: 1. Kernel, 2. System library, 3. System utilities, 4. Graphical user interface, 5. Applications. The kernel manages hardware resources, the system library provides precompiled functions, system utilities are used for system management, the GUI provides visual interaction, and applications use these components to implement functions.

vscode built-in terminal is a development tool that allows running commands and scripts within the editor to simplify the development process. How to use vscode terminal: Open the terminal with the shortcut key (Ctrl/Cmd). Enter a command or run the script. Use hotkeys (such as Ctrl L to clear the terminal). Change the working directory (such as the cd command). Advanced features include debug mode, automatic code snippet completion, and interactive command history.

To view the Git repository address, perform the following steps: 1. Open the command line and navigate to the repository directory; 2. Run the "git remote -v" command; 3. View the repository name in the output and its corresponding address.

VS Code One-step/Next step shortcut key usage: One-step (backward): Windows/Linux: Ctrl ←; macOS: Cmd ←Next step (forward): Windows/Linux: Ctrl →; macOS: Cmd →

There are six ways to run code in Sublime: through hotkeys, menus, build systems, command lines, set default build systems, and custom build commands, and run individual files/projects by right-clicking on projects/files. The build system availability depends on the installation of Sublime Text.

Although Notepad cannot run Java code directly, it can be achieved by using other tools: using the command line compiler (javac) to generate a bytecode file (filename.class). Use the Java interpreter (java) to interpret bytecode, execute the code, and output the result.

The main uses of Linux include: 1. Server operating system, 2. Embedded system, 3. Desktop operating system, 4. Development and testing environment. Linux excels in these areas, providing stability, security and efficient development tools.

To install Laravel, follow these steps in sequence: Install Composer (for macOS/Linux and Windows) Install Laravel Installer Create a new project Start Service Access Application (URL: http://127.0.0.1:8000) Set up the database connection (if required)
