Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Linux 内核 内存管理】内存映射相关数据结构 ④ ( vm_area_struct 结构体成员分析 | vm_ops 成员 | vm_operations_struct 结构体成员分析 )

【Linux 内核 内存管理】内存映射相关数据结构 ④ ( vm_area_struct 结构体成员分析 | vm_ops 成员 | vm_operations_struct 结构体成员分析 )

作者头像
韩曙亮
发布于 2023-03-30 06:29:23
发布于 2023-03-30 06:29:23
2K00
代码可运行
举报
运行总次数:0
代码可运行

文章目录

在博客 【Linux 内核 内存管理】虚拟地址空间布局架构 ⑦ ( vm_area_struct 结构体成员分析 | vm_start | vm_end | vm_next | vm_prev |vm_rb) 中 , 分析了 vm_start vm_end vm_next vm_prev vm_rb

5

个结构体成员作用 ;

在博客 【Linux 内核 内存管理】内存映射相关数据结构 ② ( vm_area_struct 结构体成员分析 | vm_mm 成员 | vm_page_prot 成员 | vm_flags 成员 ) 中 , 分析了 vm_area_struct 结构体中的 vm_mm vm_page_prot vm_flags 成员作用 ;

在博客 【Linux 内核 内存管理】内存映射相关数据结构 ③ ( vm_area_struct 结构体成员分析 | shared 成员 | anon_vma_chain 成员 | anon_vma 成员 ) 中 , 分析了 vm_area_struct 结构体中的 shared anon_vma_chain anon_vma 成员作用 ;

一、vm_area_struct 结构体成员分析


1、vm_ops 成员

vm_ops 成员是 " 虚拟内存操作集合 " , 该 vm_operations_struct 结构体中封装了大量的虚拟内存操作 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	/* Function pointers to deal with this struct. */
	const struct vm_operations_struct *vm_ops;

二、vm_operations_struct 结构体成员分析


vm_operations_struct 结构体 定义在 Linux 内核源码的 linux-4.12\include\linux\mm.h#361 位置 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
 * These are the virtual MM functions - opening of an area, closing and
 * unmapping it (needed to keep files on disk up-to-date etc), pointer
 * to the functions called when a no-page or a wp-page exception occurs. 
 */
struct vm_operations_struct {
	void (*open)(struct vm_area_struct * area);
	void (*close)(struct vm_area_struct * area);
	int (*mremap)(struct vm_area_struct * area);
	int (*fault)(struct vm_fault *vmf);
	int (*huge_fault)(struct vm_fault *vmf, enum page_entry_size pe_size);
	void (*map_pages)(struct vm_fault *vmf,
			pgoff_t start_pgoff, pgoff_t end_pgoff);

下面对 vm_operations_struct 结构体成员进行分析 ;

1、open 函数指针

open 函数指针 , 指向的函数 , 在 创建 " 虚拟内存区域 " 时调用 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	void (*open)(struct vm_area_struct * area);

2、close 函数指针

close 函数指针 , 指向的函数 , 在 删除 " 虚拟内存区域 " 时调用 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	void (*close)(struct vm_area_struct * area);

3、mremap 函数指针

mremap 函数指针 , 指向的函数 , 在 使用系统调用 mremap 函数 移动 " 虚拟内存区域 " 时调用 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	int (*mremap)(struct vm_area_struct * area);

4、fault 函数指针

【Linux 内核 内存管理】内存映射原理 ② ( 内存映射概念 | 文件映射 | 匿名映射 | 内存映射原理 | 分配虚拟内存页 | 产生缺页异常 | 分配物理内存页 | 共享内存 | 进程内存 ) 博客中 , 介绍了内存映射的原理 , 分配 " 虚拟内存区域 " 后 ,

第一次访问会产生 " 缺页异常 " ,

之后对于 " 文件映射 " , 如果没有映射 " 物理内存页 " , 就会回调 fault 函数 , 将 文件中的数据 读取到 " 物理内存页 " 中 ;

fault 函数指针 , 指向的函数 , 就是在 回调 fault 函数时 时调用 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	int (*fault)(struct vm_fault *vmf);

5、huge_fault 函数指针

huge_fault 函数指针 , 与上面的 fault 函数指针类似 , 只是 huge_fault 函数指针针对的是 使用 " 透明巨型页 " 的文件映射 的情况 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	int (*huge_fault)(struct vm_fault *vmf, enum page_entry_size pe_size);

6、map_pages 函数指针

【Linux 内核 内存管理】内存映射原理 ② ( 内存映射概念 | 文件映射 | 匿名映射 | 内存映射原理 | 分配虚拟内存页 | 产生缺页异常 | 分配物理内存页 | 共享内存 | 进程内存 ) 博客中 , 介绍了内存映射的原理 , 分配 " 虚拟内存区域 " 后 ,

第一次访问 " 文件映射 " 对应的 " 虚拟内存页 " 时 , 如果发现 文件 没有映射到该 " 虚拟内存页中 " , 会报 " 缺页异常 " ,

" 异常处理程序 " 会读取 正在访问的文件页 , 以及 预读取 后续的文件页 ,

调用 map_pages 函数指针指向的函数 , 为 文件页 分配 " 物理内存页 " ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	void (*map_pages)(struct vm_fault *vmf,
			pgoff_t start_pgoff, pgoff_t end_pgoff);

7、page_mkwrite 函数指针

要 修改 " 私有文件映射 " 对应的 " 虚拟文件页 " 时 ,

如果是 第一次 写该 内存映射 时 , 会生成 " 页错误异常 " ,

" 异常处理程序 " 会执行 " 写复制 " 机制 ,

调用该 page_mkwrite 函数指针指向的函数 , 通知该 " 文件页 " 马上要变成可写状态 ,

此时 " 文件系统 " 会检查该 写操作 是否合法 , 是否允许修改该 文件页 , 是否需要等待以便进入合适的状态再进行写操作 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	/* notification that a previously read-only page is about to become
	 * writable, if an error is returned it will cause a SIGBUS */
	int (*page_mkwrite)(struct vm_fault *vmf);

三、vm_area_struct 结构体完整源码


vm_area_struct 结构体完整源码 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
 * 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. */

	unsigned long vm_start;		/* Our start address within vm_mm. */
	unsigned long vm_end;		/* The first byte after our end address
					   within vm_mm. */

	/* linked list of VM areas per task, sorted by address */
	struct vm_area_struct *vm_next, *vm_prev;

	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. */

	struct mm_struct *vm_mm;	/* The address space we belong to. */
	pgprot_t vm_page_prot;		/* Access permissions of this 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.
	 */
	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. */
	const struct vm_operations_struct *vm_ops;

	/* Information about our backing store: */
	unsigned long vm_pgoff;		/* Offset (within vm_file) in PAGE_SIZE
					   units */
	struct file * vm_file;		/* File we map to (can be NULL). */
	void * vm_private_data;		/* was vm_pte (shared mem) */

#ifndef CONFIG_MMU
	struct vm_region *vm_region;	/* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
	struct mempolicy *vm_policy;	/* NUMA policy for the VMA */
#endif
	struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
};

四、vm_operations_struct 结构体完整源码


vm_operations_struct 结构体完整源码 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
 * These are the virtual MM functions - opening of an area, closing and
 * unmapping it (needed to keep files on disk up-to-date etc), pointer
 * to the functions called when a no-page or a wp-page exception occurs. 
 */
struct vm_operations_struct {
	void (*open)(struct vm_area_struct * area);
	void (*close)(struct vm_area_struct * area);
	int (*mremap)(struct vm_area_struct * area);
	int (*fault)(struct vm_fault *vmf);
	int (*huge_fault)(struct vm_fault *vmf, enum page_entry_size pe_size);
	void (*map_pages)(struct vm_fault *vmf,
			pgoff_t start_pgoff, pgoff_t end_pgoff);

	/* notification that a previously read-only page is about to become
	 * writable, if an error is returned it will cause a SIGBUS */
	int (*page_mkwrite)(struct vm_fault *vmf);

	/* same as page_mkwrite when using VM_PFNMAP|VM_MIXEDMAP */
	int (*pfn_mkwrite)(struct vm_fault *vmf);

	/* called by access_process_vm when get_user_pages() fails, typically
	 * for use by special VMAs that can switch between memory and hardware
	 */
	int (*access)(struct vm_area_struct *vma, unsigned long addr,
		      void *buf, int len, int write);

	/* Called by the /proc/PID/maps code to ask the vma whether it
	 * has a special name.  Returning non-NULL will also cause this
	 * vma to be dumped unconditionally. */
	const char *(*name)(struct vm_area_struct *vma);

#ifdef CONFIG_NUMA
	/*
	 * set_policy() op must add a reference to any non-NULL @new mempolicy
	 * to hold the policy upon return.  Caller should pass NULL @new to
	 * remove a policy and fall back to surrounding context--i.e. do not
	 * install a MPOL_DEFAULT policy, nor the task or system default
	 * mempolicy.
	 */
	int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new);

	/*
	 * get_policy() op must add reference [mpol_get()] to any policy at
	 * (vma,addr) marked as MPOL_SHARED.  The shared policy infrastructure
	 * in mm/mempolicy.c will do this automatically.
	 * get_policy() must NOT add a ref if the policy at (vma,addr) is not
	 * marked as MPOL_SHARED. vma policies are protected by the mmap_sem.
	 * If no [shared/vma] mempolicy exists at the addr, get_policy() op
	 * must return NULL--i.e., do not "fallback" to task or system default
	 * policy.
	 */
	struct mempolicy *(*get_policy)(struct vm_area_struct *vma,
					unsigned long addr);
#endif
	/*
	 * Called by vm_normal_page() for special PTEs to find the
	 * page for @addr.  This is useful if the default behavior
	 * (using pte_page()) would not find the correct page.
	 */
	struct page *(*find_special_page)(struct vm_area_struct *vma,
					  unsigned long addr);
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Linux 内核 内存管理】内存映射相关数据结构 ⑤ ( vm_area_struct 结构体成员分析 | vm_pgoff 成员 | vm_file 成员 | vm_private_data )
在博客 【Linux 内核 内存管理】虚拟地址空间布局架构 ⑦ ( vm_area_struct 结构体成员分析 | vm_start | vm_end | vm_next | vm_prev |vm_rb) 中 , 分析了 vm_start vm_end vm_next vm_prev vm_rb 这
韩曙亮
2023/03/30
3.2K0
【Linux 内核 内存管理】内存映射相关数据结构 ③ ( vm_area_struct 结构体成员分析 | shared 成员 | anon_vma_chain 成员 | anon_vma 成员 )
在博客 【Linux 内核 内存管理】虚拟地址空间布局架构 ⑦ ( vm_area_struct 结构体成员分析 | vm_start | vm_end | vm_next | vm_prev |vm_rb) 中 , 分析了 vm_start vm_end vm_next vm_prev vm_rb 这
韩曙亮
2023/03/30
2.5K0
【Linux 内核 内存管理】内存映射相关数据结构 ② ( vm_area_struct 结构体成员分析 | vm_mm 成员 | vm_page_prot 成员 | vm_flags 成员 )
在之前的博客 【Linux 内核 内存管理】虚拟地址空间布局架构 ⑦ ( vm_area_struct 结构体成员分析 | vm_start | vm_end | vm_next | vm_prev |vm_rb) 中 , 分析了 vm_start vm_end vm_next vm_prev vm_rb 这
韩曙亮
2023/03/30
4.2K0
【Linux 内核 内存管理】内存映射相关数据结构 ② ( vm_area_struct 结构体成员分析 | vm_mm 成员 | vm_page_prot 成员 | vm_flags 成员 )
【Linux 内核 内存管理】虚拟地址空间布局架构 ⑦ ( vm_area_struct 结构体成员分析 | vm_start | vm_end | vm_next | vm_prev |vm_rb)
文章目录 一、vm_area_struct 结构体成员分析 二、vm_area_struct 结构体完整源码 一、vm_area_struct 结构体成员分析 ---- vm_area_struct 结构体中相关成员解析 : unsigned long vm_start 成员 : 虚拟内存空间 起始地址 ; unsigned long vm_start; /* Our start address within vm_mm. */ unsigned long vm_end 成员 : 虚拟内存空间 终止地址
韩曙亮
2023/03/30
1.6K0
从内核世界透视 mmap 内存映射的本质(源码实现篇)
本文我们将进入到内核源码实现中,来看一下虚拟内存分配的过程,在这个过程中,我们还可以亲眼看到前面介绍的 mmap 内存映射原理在内核中具体是如何实现的,下面我们就从 mmap 系统调用的入口处来开始本文的内容:
bin的技术小屋
2023/10/30
7280
从内核世界透视 mmap 内存映射的本质(源码实现篇)
【Linux 内核 内存管理】内存映射相关数据结构 ⑥ ( 文件映射 虚拟内存区域 | vm_area_struct | vm_operations_struct | 匿名映射 虚拟内存区域 )
" 文件映射 " 的 " 虚拟内存区域 " vm_area_struct 结构体 的 数据结构表示形式如下 ;
韩曙亮
2023/03/30
1.1K0
【Linux 内核 内存管理】内存映射相关数据结构 ⑥ ( 文件映射 虚拟内存区域 | vm_area_struct | vm_operations_struct | 匿名映射 虚拟内存区域 )
Linux mmap原理
mmap是linux操作系统提供给用户空间调用的内存映射函数,很多人仅仅只是知道可以通过mmap完成进程间的内存共享和减少用户态到内核态的数据拷贝次数,但是并没有深入理解mmap在操作系统内部是如何实现的,原理是什么。
大忽悠爱学习
2022/10/30
3.8K0
Linux mmap原理
【内存管理】页表映射基础知识
大家在看内核代码时会经常看的以上术语,但在ARM的芯片手册中并没有用到这些术语,而是使用L1,L2,L3页表这种术语。
嵌入式与Linux那些事
2024/06/11
4730
【内存管理】页表映射基础知识
Linux内存映射——mmap
所谓的内存映射就是把物理内存映射到进程的地址空间之内,这些应用程序就可以直接使用输入输出的地址空间,从而提高读写的效率。Linux提供了mmap()函数,用来映射物理内存。在驱动程序中,应用程序以设备文件为对象,调用mmap()函数,内核进行内存映射的准备工作,生成vm_area_struct结构体,然后调用设备驱动程序中定义的mmap函数。
全栈程序员站长
2022/07/02
5.9K0
Linux内存映射——mmap
一步一图带你深入理解 Linux 物理内存管理
在上篇文章 《深入理解 Linux 虚拟内存管理》 中,笔者分别从进程用户态和内核态的角度详细深入地为大家介绍了 Linux 内核如何对进程虚拟内存空间进行布局以及管理的相关实现。在我们深入理解了虚拟内存之后,那么何不顺带着也探秘一下物理内存的管理呢?
bin的技术小屋
2023/10/30
1.6K0
一步一图带你深入理解 Linux 物理内存管理
Linux进程的内存管理
一个进程的虚拟地址空间主要由两个数据结来描述,一个是 mm_struct,一个是 vm_area_structs。
刘盼
2021/03/23
3.4K0
Linux进程的内存管理之缺页异常
通过《Linux进程的内存管理之malloc和mmap》我们知道,这两个函数只是建立了进程的vma,但还没有建立虚拟地址和物理地址的映射关系。
刘盼
2021/04/13
2.7K1
Linux进程的内存管理之缺页异常
Linux内存管理2.6 -反向映射RMAP(最终版本)
所谓反向映射是相对于从虚拟地址到物理地址的映射,反向映射是从物理页面到虚拟地址空间VMA的反向映射。
233333
2023/08/14
6300
Linux内存管理2.6 -反向映射RMAP(最终版本)
Linux 匿名页的反向映射
我们知道LINUX的内存管理系统中有”反向映射“这一说,目的是为了快速去查找出一个特定的物理页在哪些进程中被映射到了什么地址,这样如果我们想把这一页换出(SWAP),或是迁移(Migrate)的时候,就能相应该更改所有相关进程的页表来达到这个目的。
233333
2019/05/25
3.8K0
一文聊透 Linux 缺页异常的处理 —— 图解 Page Faults
在前面两篇介绍 mmap 的文章中,笔者分别从原理角度以及源码实现角度带着大家深入到内核世界深度揭秘了 mmap 内存映射的本质。从整个 mmap 映射的过程可以看出,内核只是在进程的虚拟地址空间中寻找出一段空闲的虚拟内存区域 vma 然后分配给本次映射而已。
bin的技术小屋
2023/12/21
3.9K0
一文聊透 Linux 缺页异常的处理 —— 图解 Page Faults
Linux虚拟内存管理
Linux的内存管理分为 虚拟内存管理 和 物理内存管理,本文主要介绍 虚拟内存管理 的原理和实现。在介绍 虚拟内存管理 前,首先介绍一下 x86 CPU 内存寻址的具体过程。
用户7686797
2020/08/25
4.1K0
Linux虚拟内存管理
Linux内核虚拟内存管理之匿名映射缺页异常分析
韩传华,就职于南京大鱼半导体有限公司,主要从事linux相关系统软件开发工作,负责Soc芯片BringUp及系统软件开发,乐于分享喜欢学习,喜欢专研Linux内核源代码。
Linux阅码场
2020/09/10
3K0
Linux内核虚拟内存管理之匿名映射缺页异常分析
内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
s1mba
2018/01/03
2.6K0
内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
图解Linux内核(基于6.x):解读Linux内存反向映射之匿名映射
匿名映射中,mapping可以用来找到anon_vma,anon_vma关联vma,通过folio和vma,就可以得出映射的虚拟地址address,最终由address和vma定位PTE,如图1所示。
屿小夏
2024/06/21
9710
图解Linux内核(基于6.x):解读Linux内存反向映射之匿名映射
Linux内存管理
谈到内存管理,最先想到的就是分段和分页机制。计算机刚出现的时候,并没有这些,刚开始是直接使用的物理地址,也就是代码中操作的地址是可以直接和物理地址对应上的,可是后来随着多进程调度的需求,以及有限的物理内存,于是人们就开始做规定,比如对于一块内存,某个范围是属于内核,然后另外一个范围属于进程A,再另外一个范围属于进程B,如下图所示
一只小虾米
2023/03/19
14K0
Linux内存管理
推荐阅读
【Linux 内核 内存管理】内存映射相关数据结构 ⑤ ( vm_area_struct 结构体成员分析 | vm_pgoff 成员 | vm_file 成员 | vm_private_data )
3.2K0
【Linux 内核 内存管理】内存映射相关数据结构 ③ ( vm_area_struct 结构体成员分析 | shared 成员 | anon_vma_chain 成员 | anon_vma 成员 )
2.5K0
【Linux 内核 内存管理】内存映射相关数据结构 ② ( vm_area_struct 结构体成员分析 | vm_mm 成员 | vm_page_prot 成员 | vm_flags 成员 )
4.2K0
【Linux 内核 内存管理】虚拟地址空间布局架构 ⑦ ( vm_area_struct 结构体成员分析 | vm_start | vm_end | vm_next | vm_prev |vm_rb)
1.6K0
从内核世界透视 mmap 内存映射的本质(源码实现篇)
7280
【Linux 内核 内存管理】内存映射相关数据结构 ⑥ ( 文件映射 虚拟内存区域 | vm_area_struct | vm_operations_struct | 匿名映射 虚拟内存区域 )
1.1K0
Linux mmap原理
3.8K0
【内存管理】页表映射基础知识
4730
Linux内存映射——mmap
5.9K0
一步一图带你深入理解 Linux 物理内存管理
1.6K0
Linux进程的内存管理
3.4K0
Linux进程的内存管理之缺页异常
2.7K1
Linux内存管理2.6 -反向映射RMAP(最终版本)
6300
Linux 匿名页的反向映射
3.8K0
一文聊透 Linux 缺页异常的处理 —— 图解 Page Faults
3.9K0
Linux虚拟内存管理
4.1K0
Linux内核虚拟内存管理之匿名映射缺页异常分析
3K0
内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
2.6K0
图解Linux内核(基于6.x):解读Linux内存反向映射之匿名映射
9710
Linux内存管理
14K0
相关推荐
【Linux 内核 内存管理】内存映射相关数据结构 ⑤ ( vm_area_struct 结构体成员分析 | vm_pgoff 成员 | vm_file 成员 | vm_private_data )
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验