Linux kernel threads, processes, threads

Source: Internet
Author: User

http://blog.csdn.net/dyllove98/article/details/8917197

Linux has a lot to do with memory management, and this article starts with the management of the virtual address space of the process. (The code on which it is based is 2.6.32.60)

Whether it is a kernel thread or a user process, for the kernel, it is nothing more than an instance of the TASK_STRUCT data structure, Task_struct is called the process descriptor, because it records all the context of the process. There is a data structure called ' Memory Descriptor ' (descriptor) mm_struct, which abstracts and describes all the information in the management process address space from the Linux perspective. Mm_struct is defined in Include/linux/mm_types.h, where the domain abstracts the address space of the process, as shown in: Each process has its own independent mm_struct, so that each process has an abstract, flat, independent 32-or 64-bit address space, Each process stores different data and does not interfere with the same address memory in its own address space. If the same address space is shared between processes, it is called Threads。 Where [Start_code,end_code] represents the address space range of the code snippet. [Start_data,end_start] represents the address space range of a data segment. [START_BRK,BRK] represents the starting space of the heap and the current heap pointer, respectively. [Start_stack,end_stack] represents the address space range of the stack segment. The mmap_base represents the starting address of the memory mapping segment. then why does the mmap segment have no end address? What is the BBS section used for? BBS represents all the non-initialized global variables, so that they only need to be anonymously mapped to ' 0 pages ', rather than the mapping from the disk file during program load, which reduces the size of elf binaries and increases the efficiency of program loading. Why is there no address space representation of BBS segment in mm_struct? In addition to this, Mm_struct also defines several important domains:
215        atomic_t mm_users;                      /* How many users with user space? */216        atomic_t Mm_count;                      /* How many references to "struct Mm_struct" (Users count as 1) */

These two counter appear to be similar at first glance, what is the difference in Linux usage? Reading the code is the best explanation.

681static int copy_mm (unsigned long clone_flags, struct task_struct * tsk) 682{683        struct mm_struct * mm, *OLDMM; 684        int retval;  692        tsk->mm = null; 693        tsk->active_mm = null; 694 695/*        696         * is we cloning a kernel thread? 697< c7/>* 698         * We need to steal a active VMS for that: 699         * * OLDMM        = current->mm; 701        if (!OLDMM) 7                703 return 0; 704        if (Clone_flags & CLONE_VM) {705                atomic_inc (&oldmm->mm_users); 706                mm = OLDMM; 707                goto good_mm; 708        }

No matter when we call Fork,vfork,clone, the Do_fork function is eventually called, except that Vfork and clone give copy_mm a CLONE_VM flag, which indicates that the parent-child process is running in the same ' Virtual address space ' above (as Linux is called Lightweight process or thread ), and of course share the same physical address space (Page Frames).

The COPY_MM function, if there is a CLONE_VM identity in the creation thread, indicates that the parent-child process shares the address space and the same memory descriptor, and only needs to mm_users the value +1, which means that mm_users represents the number of threads that are referencing the address space. is a thread level counter.

Where's mm_count? Mm_count's understanding is a bit complicated.

For Linux, the user process and kernel thread (kernel thread) are task_struct instances, the only difference being that kernel thread does not have a process address space and the kernel thread does not have a mm descriptor, so the kernel thread's tsk-> The MM field is empty (null). Kernel Scheduler in the process context switching, according to TSK->MM determine whether the process will be scheduled is a user process or kernel thread. But while thread thread does not have access to the user process address space, it still requires page table to access kernel's own space. Fortunately, for any user process, their kernel space is 100% the same, so the kernel can ' borrow ' the page table in mm of the called user process to access the kernel address, this mm is recorded in the active_mm.

In short, for kernel thread,tsk->mm = = NULL represents the identity of its kernel thread, and tsk->active_mm is the mm of the previous user process, using the MM page table to access the kernel space. For user processes, tsk->mm = = tsk->active_mm.

To support this particular, Mm_struct introduced another counter,mm_count. Just said mm_users indicates how many threads the process address space is shared with or referenced by, while Mm_count represents the number of times that the address space is referenced by the kernel thread +1.

For example, if a process A has 3 threads, the mm_users value of the mm_struct of A is 3, but Mm_count is 1, so mm_count is the counter of the process level. What is the use of maintaining 2 counter? Consider such a scenario, after the kernel dispatched a, switch to kernel kernel thread b,b ' borrow ' a mm description utilises access to the kernel space, then mm_count becomes 2, while another CPU core dispatched a and process a exit, this time mm_ Users become 0,mm_count to 1, but the kernel will not destroy the mm_struct because of mm_users==0, and the kernel will release mm_struct only when Mm_count==0. Because there is no user process using this address space at this time, there is no kernel thread referencing this address space.

We'll try to explain the difference between the use of Mm_users and mm_count with an example. Consider a memory descriptor shared by lightweight processes. Normally, its Mm_users field stores the value 2, while its Mm_count field stores the value 1 (both owner processes count a S one).

If the memory descriptor is temporarily lent to a kernel thread (see the next section), the kernel increases the Mm_count Field. In this, even if both lightweight processes die and the Mm_users field becomes zero, the memory descriptor are not rele ased until the kernel thread finishes using it because the Mm_count field remains greater than zero.

Linux kernel threads, processes, threads

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.