linux内核地址空间,Linux内核分析之进程地址空间

关于mm_users字段和mm_count字段

mm_users字段存放共享mm_struct数据结构的轻量级进程的个数。mm_count字段是内存描述符的主使计数器,在mm_users次使用计数器中的所有用户在mm_count中只作为一个单位,每当mm_count递减时,内核都要检查他是否变为0,如果是,就要解除这个内存描述符,因为不再有用户使用他。

用一个例子解释mm_users和mm_count之间的不同。考虑一个内存描述符由两个轻量级进程共享。他的mm_users字段通常存放的值为2,而mm_count字段存放的值为1(两个所有者进程算作一个)。如果把内存描述符在一个长操作的中间不被释放,那么,就应该增加mm_users字段而不是mm_count字段的值。最终结果是相同的,因为mm_users的增加确保了mm_count不变为0,即使拥有这个内存描述符的所有轻量级进程全部死亡。

内核线程仅运行在内核态,因此,他们永远不会访问低于TASK_SIZE(等于PAGE_OFFSET,通常为0xc0000000)的地址。与普通进程相反,内核线程不用线性区,因此,内存描述符的很多字段对内核线程是没有意义的。也就是说,当创建内核线程时,内核线程的active_mm共享父进程的mm,但是只使用mm中部分数据与变量。

线性区

linux通过类型为vm_area_struct的对象实现线性区,它的字段为

/*

* This struct defines a memory VMM memory area. There is one of these

* per VM-area/task.  A VM area is any part of the process virtual memory

* space that has a special rule for the page-fault handlers (ie a shared

* library, the executable area etc).

*/

structvm_area_struct {

structmm_struct * vm_mm;/* The address space we belong to. */

unsignedlongvm_start;/* Our start address within vm_mm. */

unsignedlongvm_end;/* The first byte after our end address

within vm_mm. */

/* linked list of VM areas per task, sorted by address */

structvm_area_struct *vm_next;

pgprot_t vm_page_prot;/* Access permissions of this VMA. */

unsignedlongvm_flags;/* Flags, see mm.h. */

structrb_node vm_rb;

/*

* For areas with an address space and backing store,

* linkage into the address_space->i_mmap prio tree, or

* linkage to the list of like vmas hanging off its node, or

* linkage of vma in the address_space->i_mmap_nonlinear list.

*/

union{

struct{

structlist_head list;

void*parent;/* aligns with prio_tree_node parent */

structvm_area_struct *head;

} vm_set;

structraw_prio_tree_node prio_tree_node;

} shared;

/*

* A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma

* list, after a COW of one of the file pages.  A MAP_SHARED vma

* can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack

* or brk vma (with NULL file) can only be in an anon_vma list.

*/

structlist_head anon_vma_node;/* Serialized by anon_vma->lock */

structanon_vma *anon_vma;/* Serialized by page_table_lock */

/* Function pointers to deal with this struct. */

conststructvm_operations_struct *vm_ops;

/* Information about our backing store: */

unsignedlongvm_pgoff;/* Offset (within vm_file) in PAGE_SIZE

units, *not* PAGE_CACHE_SIZE */

structfile * vm_file;/* File we map to (can be NULL). */

void* vm_private_data;/* was vm_pte (shared mem) */

unsignedlongvm_truncate_count;/* truncate_count or restart_addr */

#ifndef CONFIG_MMU

structvm_region *vm_region;/* NOMMU mapping region */

#endif

#ifdef CONFIG_NUMA

structmempolicy *vm_policy;/* NUMA policy for the VMA */

#endif

};

进程所拥有的线性区从来不重叠,并且内核尽力把新分配的线性区与邻接的现有线性区进行合并。如果两个相邻区的访问权限相匹配,就能把他们合并在一起。0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值