8. vma操作概述
在32位系统中,每个用户进程可以拥有3GB大小的虚拟地址空间,通常要远大于物理内存,那么如何管理这些虚拟地址空间呢?用户进程通常会多次调用malloc()或使用mmap()接口映射文件到用户空间来进行读写等操作,这些操作都会要求在虚拟地址空间中分配内存块,这些内存块基本上都是离散的。malloc()是用户态常用的分配内存的接口API函数。mmap()是用户态常用的用于建立文件映射或匿名映射的函数。这些进程地址空间在内核中使用struct vm_area_struct数据结构来描述,简称VMA,也被称为进程地址空间或进程线性区。由于这些地址空间归属于各个用户进程,所以在用户进程的struct mm_struct数据结构中也有相应的成员,用于对这些VMA进行管理。
VMA数据结构定义在mm_types.h(include/linux/mm_types.h)
/** 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).*/
struct vm_area_struct {/* The first cache line has the info for VMA tree walking. *//*指定VMA在进程地址空间的起始地址*/unsigned long vm_start; /* Our start address within vm_mm. *//*指定VMA在进程地址空间的结束地址*/unsigned long vm_end; /* The first byte after our end addresswithin vm_mm. *//* linked list of VM areas per task, sorted by address *//*进程的vma都连接成一个链表*/struct vm_area_struct *vm_next, *vm_prev;/*vma作为一个节点加入红黑树中,每个进程的struct mm_struct数据结构中都有这样一棵红黑树mm->mm_rb*/struct rb_node vm_rb;/** Largest free memory gap in bytes to the left of this VMA.* Either between this VMA and vma->vm_prev, or between one of the* VMAs below us in the VMA rbtree and its ->vm_prev. This helps* get_unmapped_area find a free area of the right size.*/unsigned long rb_subtree_gap;/* Second cache line starts here. *//*指向该vma所属的进程struct mm_struct数据结构*/struct mm_struct *vm_mm; /* The address space we belong to. *//*vma的访问权限*/pgprot_t vm_page_prot; /* Access permissions of this VMA. *//*描述该vma的一组标志位*/unsigned long vm_flags; /* Flags, see mm.h. *//** For areas with an address space and backing store,* linkage into the address_space->i_mmap interval tree.*/struct {struct rb_node rb;unsigned long rb_subtree_last;} 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.*//*anon_vam_chain和anon_vma:用于管理RMAP反向映射*/struct list_head anon_vma_chain; /* Serialized by mmap_sem &* page_table_lock */struct anon_vma *anon_vma; /* Serialized by page_table_lock *//* Function pointers to deal with this struct. *//*指向许多方法的集合,这些方法用于在vma中执行各种操作,通常用于文件映射*/const struct vm_operations_struct *vm_ops;/* Information about our backing store: *//*指定文件映射的偏移量,这个变量的单位不是Byte,而是页面的大小(PAGE_SIZE)*/unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZEunits, *not* PAGE_CACHE_SIZE *//*指向file的实例,描述一个被映射的文件*/struct file * vm_file; /* File we map to (can be NULL). */void * vm_private_data; /* was vm_pte (shared mem) */#ifndef CONFIG_MMUstruct vm_region *vm_region; /* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMAstruct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
};
struct mm_struct数据结构是描述进程内存管理的核心数据结构,该数据结构也提供了管理VMA所需的信息,这些信息概况如下:
VMA按照起始地址以递增的方式插入mm_struct->mmap链表中。当进程拥有大量的VMA时,扫描链表和查找特定的VMA是非常低效的操作。
例如在云计算的机器中,所有内核中通常要靠红黑树来协助,以便提高查找速度。
include/linux/mm_types.h
//每个VMA都要连接到mm_struct中的链表和红黑树中,以方便查找。
struct mm_struct {
/*mmap形成一个单链表,进程中所有的vma都连接到这个链表中,链表头时mm_struct->mmap*/
struct vm_area_struct *mmap; /* list of VMAs */
/*mm_rb是红黑树的根节点,每个进程有一棵VMA的红黑树*/
struct rb_root mm_rb;
u32 vmacache_seqnum; /* per-thread vmacache */
#ifdef CONFIG_MMU
unsigned long (*get_unmapped_area) (struct file *filp,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags);
#endif
unsigned long mmap_base; /* base of mmap area */
unsigned long mmap_legacy_base; /* base of mmap area in bottom-up allocations */
unsigned long task_size; /* size of task vm space */
unsigned long highest_vm_end; /* highest vma end address */
pgd_t * pgd;
atomic_t mm_users; /* How many users with user space? */
atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
atomic_long_t nr_ptes; /* PTE page table pages */
atomic_long_t nr_pmds; /* PMD page table pages */
int map_count; /* number of VMAs */
spinlock_t page_table_lock; /* Protects page tables and some counters */
struct rw_semaphore mmap_sem;
struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung
* together off init_mm.mmlist, and are protected
* by mmlist_lock
*/
unsigned long hiwater_rss; /* High-watermark of RSS usage */
unsigned long hiwater_vm; /* High-water virtual memory usage */
unsigned long total_vm; /* Total pages mapped */
unsigned long locked_vm; /* Pages that have PG_mlocked set */
unsigned long pinned_vm; /* Refcount permanently increased */
unsigned long shared_vm; /* Shared pages (files) */
unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE */
unsigned long stack_vm; /* VM_GROWSUP/DOWN */
unsigned long def_flags;
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
/*
* Special counters, in some configurations protected by the
* page_table_lock, in other configurations by being atomic.
*/
struct mm_rss_stat rss_stat;
struct linux_binfmt *binfmt;
cpumask_var_t cpu_vm_mask_var;
/* Architecture-specific MM context */
mm_context_t context;
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;
struct kioctx_table __rcu *ioctx_table;
#endif
#ifdef CONFIG_MEMCG
/*
* "owner" points to a task that is regarded as the canonical
* user/owner of this mm. All of the following must be true in
* order for it to be changed:
*
* current == mm->owner
* current->mm != mm
* new_owner->mm == mm
* new_owner->alloc_lock is held
*/
struct task_struct __rcu *owner;
#endif
/* store ref to file /proc/<pid>/exe symlink points to */
struct file *exe_file;
#ifdef CONFIG_MMU_NOTIFIER
struct mmu_notifier_mm *mmu_notifier_mm;
#endif
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
pgtable_t pmd_huge_pte; /* protected by page_table_lock */
#endif
#ifdef CONFIG_CPUMASK_OFFSTACK
struct cpumask cpumask_allocation;
#endif
#ifdef CONFIG_NUMA_BALANCING
/*
* numa_next_scan is the next time that the PTEs will be marked
* pte_numa. NUMA hinting faults will gather statistics and migrate
* pages to new nodes if necessary.
*/
unsigned long numa_next_scan;
/* Restart point for scanning and setting pte_numa */
unsigned long numa_scan_offset;
/* numa_scan_seq prevents two threads setting pte_numa */
int numa_scan_seq;
#endif
#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
/*
* An operation with batched TLB flushing is going on. Anything that
* can move process memory needs to flush the TLB when moving a
* PROT_NONE or PROT_NUMA mapped page.
*/
bool tlb_flush_pending;
#endif
struct uprobes_state uprobes_state;
#ifdef CONFIG_X86_INTEL_MPX
/* address of the bounds directory */
void __user *bd_addr;
#endif
};
8. vma操作概述相关推荐
- ibm键盘部分失灵_IBM Business Process Manager操作概述,第1部分,拓扑,安全性,基本管理和监视
ibm键盘部分失灵 存档日期:2019年5月13日 | 首次发布:2015年7月30日 维护与许多后端和前端系统和服务交互的IBM®Business Process Manager(BPM)的集群服务 ...
- PyQt5摄像头的使用--摄像头操作概述及使用摄像头拍照
1.功能概述 PyQt5多媒体模块为摄像头操作提供了几个类,可以用于获取摄像头设备信息,通过摄像头进行拍照和录像. Qt多媒体模块的功能实现是依赖于平台的.在Windows平台上,Qt多媒体模块依赖于 ...
- C 关于使用异或运算操作概述
对于异或运算操作,每次都需要读取两个数据到寄存器中,再进行运算操作,之后把结果写回到变量中,前后共需要三次内存写入操作. 异或运算可以达到交换两数的目的,代码如下: void swap(int &am ...
- C++运行时候库操作概述和整个程序运行流程
一.任何一个C/C++程序,它的背后都是一套庞大的代码来进行支撑,以使得该程序能够正常运行.这套代码至少包括入口函数.及其依赖的函数所构成的函数集合.当然,它还应该包括各种标准函数(如字符串,数学运算 ...
- 安卓机高的地图要用浏览器打开_浏览器F12操作概述
我的很多文章都是说,通过F12找到url来获取数据的<浏览器F12的用法>,那么到底怎么操作,其实通过网上搜索教程或者视频肯定能学会的,这里就简单的介绍一下,抛砖引玉. 首先,我建议使用谷 ...
- LINQ:进阶 - LINQ 标准查询操作概述
"标准查询运算符"是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> 接口或 I ...
- JS核心基础数组的操作概述
本文章将描述 JS 中向数组中添加元素的方法 [x1]微信公众号的每日提醒 随时随记 每日积累 随心而过 [x2]各种系列的视频教程 免费开源 关注 你不会迷路 [x3]系列文章 百万 Demo 随时 ...
- .NET应用程序安全操作概述
介绍 此页面旨在为开发人员提供.NET安全提示. .NET Framework .NET Framework是Microsoft用于企业开发的主要平台.它是ASP.NET,Windows桌面应用程序, ...
- 公司里开发用的机器,虚拟机、网络、转发、ssh连接、远程桌面、远程开机……等一系列骚操作的操作概述
我这里讲的都是如何回家后还可以连接公司电脑,且省电.不伤机器的事啊,审核的各位别误会了. 这篇就不要提docker了,两码事. 也不要纠结什么hyperV.virtualBox还是vmware的了,无 ...
最新文章
- MyBatis 实践 -配置
- 高可用集群技术之RHCS应用详解(一)
- apache负载均衡的安装和实现方法
- vue-cli webpack 打包报错:Unexpected token: punc (()
- Java操作Excel中HSSFCell.CELL_TYPE_STRING、BOOLEAN、NUMERIC无定义解决方法
- 如何在虚拟linux环境运行python_linux下使用virtualenv虚拟独立python环境
- 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现
- 销售记账管理系统php源码,crm客户销售管理系统销售统计ERP系统源php源码源码办公审批管理...
- 基于C#的简单聊天软件开发
- 10---OpenCV:图像进阶操作之连通区域分析
- setBackground()和setImageBitmap()看完就哦了
- ps中背影制造以及扣图后换背景的注意事项
- 名帖358 文天祥 草书《谢昌元座右自警辞》
- NAACL最佳方法论文:课本上的A*搜索算法可以提升文本生成效果!
- [译]C++中的内存同步模式(memory order)
- 巴西龟饲养日志----半年捉鱼经验总结
- 手机维修基础 常见故障分析㈢
- scala并发_探索Scala并发
- arcgis api for javascript 4.16 定位功能的实现
- 利用Multigen Creator构建地形三维模型(CAD地形图--三维模型)