Linux内存描述符mm_struct实例详解

Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起。(所依据的代码是2.6.32.60)

无论是内核线程还是用户进程,对于内核来说,无非都是task_struct这个数据结构的一个实例而已,task_struct被称为进程描述符(process descriptor),因为它记录了这个进程所有的context。其中有一个被称为'内存描述符‘(memory descriptor)的数据结构mm_struct,抽象并描述了Linux视角下管理进程地址空间的所有信息。

mm_struct定义在include/linux/mm_types.h中,其中的域抽象了进程的地址空间,如下图所示:

struct mm_struct {

struct vm_area_struct * mmap; //指向虚拟区间(VMA)的链表

struct rb_root mm_rb; //指向线性区对象红黑树的根

struct vm_area_struct * mmap_cache; //指向最近找到的虚拟区间

unsigned long(*get_unmapped_area) (struct file *filp,

unsigned long addr, unsigned long len,

unsigned long pgoff, unsigned long flags);//在进程地址空间中搜索有效线性地址区

unsigned long(*get_unmapped_exec_area) (struct file *filp,

unsigned long addr, unsigned long len,

unsigned long pgoff, unsigned long flags);

void(*unmap_area) (struct mm_struct *mm, unsigned long addr);//释放线性地址区间时调用的方法

unsigned long mmap_base; /* base of mmap area */

unsigned long task_size; /* size of task vm space */

unsigned long cached_hole_size;

unsigned long free_area_cache; //内核从这个地址开始搜索进程地址空间中线性地址的空闲区域

pgd_t * pgd; //指向页全局目录

atomic_t mm_users; //次使用计数器,使用这块空间的个数

atomic_t mm_count; //主使用计数器

int map_count; //线性的个数

struct rw_semaphore mmap_sem; //线性区的读/写信号量

spinlock_t page_table_lock; //线性区的自旋锁和页表的自旋锁

struct list_head mmlist; //指向内存描述符链表中的相邻元素

/* Special counters, in some configurations protected by the

* page_table_lock, in other configurations by being atomic.

*/

mm_counter_t _file_rss; //mm_counter_t代表的类型实际是typedef atomic_long_t

mm_counter_t _anon_rss;

mm_counter_t _swap_usage;

unsigned long hiwater_rss; //进程所拥有的最大页框数

unsigned long hiwater_vm; //进程线性区中最大页数

unsigned long total_vm, locked_vm, shared_vm, exec_vm;

//total_vm 进程地址空间的大小(页数)

//locked_vm 锁住而不能换出的页的个数

//shared_vm 共享文件内存映射中的页数

unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;

//stack_vm 用户堆栈中的页数

//reserved_vm 在保留区中的页数或者在特殊线性区中的页数

//def_flags 线性区默认的访问标志

//nr_ptes 进程的页表数

unsigned long start_code, end_code, start_data, end_data;

//start_code 可执行代码的起始地址

//end_code 可执行代码的最后地址

//start_data已初始化数据的起始地址

// end_data已初始化数据的最后地址

unsigned long start_brk, brk, start_stack;

//start_stack堆的起始位置

//brk堆的当前的最后地址

//用户堆栈的起始地址

unsigned long arg_start, arg_end, env_start, env_end;

//arg_start 命令行参数的起始地址

//arg_end命令行参数的起始地址

//env_start环境变量的起始地址

//env_end环境变量的最后地址

unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */

struct linux_binfmt *binfmt;

cpumask_t cpu_vm_mask; //用于惰性TLB交换的位掩码

/* Architecture-specific MM context */

mm_context_t context; //指向有关特定结构体系信息的表

unsigned int faultstamp;

unsigned int token_priority;

unsigned int last_interval;

unsigned long flags; /* Must use atomic bitops to access the bits */

struct core_state *core_state; /* coredumping support */

#ifdef CONFIG_AIO

spinlock_t ioctx_lock; //用于保护异步I/O上下文链表的锁

struct hlist_head ioctx_list;//异步I/O上下文

#endif

#ifdef CONFIG_MM_OWNER

struct task_struct *owner;

#endif

#ifdef CONFIG_PROC_FS

unsigned long num_exe_file_vmas;

#endif

#ifdef CONFIG_MMU_NOTIFIER

struct mmu_notifier_mm *mmu_notifier_mm;

#endif

#ifdef CONFIG_TRANSPARENT_HUGEPAGE

pgtable_t pmd_huge_pte; /* protected by page_table_lock */

#endif

#ifdef __GENKSYMS__

unsigned long rh_reserved[2];

#else

//有多少任务分享这个mm OOM_DISABLE

union {

unsigned long rh_reserved_aux;

atomic_t oom_disable_count;

};

/* base of lib map area (ASCII armour) */

unsigned long shlib_base;

#endif

};


总结

以上所述是小编给大家介绍的Linux内存描述符mm_struct实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是 Linux内存描述符mm_struct实例详解 的全部内容, 来源链接: utcz.com/z/329338.html

回到顶部