在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操作概述相关推荐

  1. ibm键盘部分失灵_IBM Business Process Manager操作概述,第1部分,拓扑,安全性,基本管理和监视

    ibm键盘部分失灵 存档日期:2019年5月13日 | 首次发布:2015年7月30日 维护与许多后端和前端系统和服务交互的IBM®Business Process Manager(BPM)的集群服务 ...

  2. PyQt5摄像头的使用--摄像头操作概述及使用摄像头拍照

    1.功能概述 PyQt5多媒体模块为摄像头操作提供了几个类,可以用于获取摄像头设备信息,通过摄像头进行拍照和录像. Qt多媒体模块的功能实现是依赖于平台的.在Windows平台上,Qt多媒体模块依赖于 ...

  3. C 关于使用异或运算操作概述

    对于异或运算操作,每次都需要读取两个数据到寄存器中,再进行运算操作,之后把结果写回到变量中,前后共需要三次内存写入操作. 异或运算可以达到交换两数的目的,代码如下: void swap(int &am ...

  4. C++运行时候库操作概述和整个程序运行流程

    一.任何一个C/C++程序,它的背后都是一套庞大的代码来进行支撑,以使得该程序能够正常运行.这套代码至少包括入口函数.及其依赖的函数所构成的函数集合.当然,它还应该包括各种标准函数(如字符串,数学运算 ...

  5. 安卓机高的地图要用浏览器打开_浏览器F12操作概述

    我的很多文章都是说,通过F12找到url来获取数据的<浏览器F12的用法>,那么到底怎么操作,其实通过网上搜索教程或者视频肯定能学会的,这里就简单的介绍一下,抛砖引玉. 首先,我建议使用谷 ...

  6. LINQ:进阶 - LINQ 标准查询操作概述

    "标准查询运算符"是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> 接口或 I ...

  7. JS核心基础数组的操作概述

    本文章将描述 JS 中向数组中添加元素的方法 [x1]微信公众号的每日提醒 随时随记 每日积累 随心而过 [x2]各种系列的视频教程 免费开源 关注 你不会迷路 [x3]系列文章 百万 Demo 随时 ...

  8. .NET应用程序安全操作概述

    介绍 此页面旨在为开发人员提供.NET安全提示. .NET Framework .NET Framework是Microsoft用于企业开发的主要平台.它是ASP.NET,Windows桌面应用程序, ...

  9. 公司里开发用的机器,虚拟机、网络、转发、ssh连接、远程桌面、远程开机……等一系列骚操作的操作概述

    我这里讲的都是如何回家后还可以连接公司电脑,且省电.不伤机器的事啊,审核的各位别误会了. 这篇就不要提docker了,两码事. 也不要纠结什么hyperV.virtualBox还是vmware的了,无 ...

最新文章

  1. MyBatis 实践 -配置
  2. 高可用集群技术之RHCS应用详解(一)
  3. apache负载均衡的安装和实现方法
  4. vue-cli webpack 打包报错:Unexpected token: punc (()
  5. Java操作Excel中HSSFCell.CELL_TYPE_STRING、BOOLEAN、NUMERIC无定义解决方法
  6. 如何在虚拟linux环境运行python_linux下使用virtualenv虚拟独立python环境
  7. 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现
  8. 销售记账管理系统php源码,crm客户销售管理系统销售统计ERP系统源php源码源码办公审批管理...
  9. 基于C#的简单聊天软件开发
  10. 10---OpenCV:图像进阶操作之连通区域分析
  11. setBackground()和setImageBitmap()看完就哦了
  12. ps中背影制造以及扣图后换背景的注意事项
  13. 名帖358 文天祥 草书《谢昌元座右自警辞》
  14. NAACL最佳方法论文:课本上的A*搜索算法可以提升文本生成效果!
  15. [译]C++中的内存同步模式(memory order)
  16. 巴西龟饲养日志----半年捉鱼经验总结
  17. 手机维修基础 常见故障分析㈢
  18. scala并发_探索Scala并发
  19. arcgis api for javascript 4.16 定位功能的实现
  20. 利用Multigen Creator构建地形三维模型(CAD地形图--三维模型)

热门文章

  1. 个人博客:后台(登录)
  2. 高中数学必修一:一元三次函数快速求解(全新思维)
  3. [企业管理]一个软件企业管理的典型案例分析
  4. 208亿背后的“秘密” 1
  5. 读《知心书.第二辑:疯子的自由》
  6. OpenStack Murano Dashboard(Kilo)安装
  7. 两个有序数组的中位数
  8. Caffe框架总结-Caffe结构
  9. git 上传代码步骤
  10. unity物体设置透明度_URP自学笔记5. 透明度混合与透明度测试