Loading [MathJax]/jax/input/TeX/jax.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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring Boot 3.x 自动配置详解
Spring Boot 3.x 中的自动配置使用META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports ,而不是META-INF/spring.factories,这个变动其实在2.7的时候已经改变
阿提说说
2023/10/16
5K0
Spring Boot 3.x 自动配置详解
【小家Spring】Spring解析@Configuration注解的处理器:ConfigurationClassPostProcessor(ConfigurationClassParser)
在Spring3.0以后,官方推荐我们使用注解去驱动Spring应用。那么很多人就一下子懵了,不需要xml配置文件了,那我的那些配置项怎么办呢? @Configuration是Spring3.0推出来的注解,用来代替xml配置文件。 若一个Class类被标注了这个注解,我们就认为这个类就是一个配置类,然后在这个类里面就可以写相应的其它配置了,比如@Bean等等
YourBatman
2019/09/03
1.7K0
【小家Spring】Spring解析@Configuration注解的处理器:ConfigurationClassPostProcessor(ConfigurationClassParser)
Spring源码解析(六):bean工厂后置处理器ConfigurationClassPostProcessor
具体原因,因为在postProcessBeanFactory方法中对Full类型(即被@Configuration修饰的配置类)的配置类进行了动态代理
冬天vs不冷
2025/01/21
2950
Spring源码解析(六):bean工厂后置处理器ConfigurationClassPostProcessor
逐行阅读Spring5.X源码(七)扫描和注册神器 ConfigurationClassPostProcessor ,学此类者,胜过学九阳神功!胆小勿入!
ConfigurationClassPostProcessor是一个BeanFactory的后置处理器,因此它的主要功能是参与BeanFactory的建造,在这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。 完成扫描啊!你说重要不重要!!!
源码之路
2020/09/04
7500
逐行阅读Spring5.X源码(七)扫描和注册神器 ConfigurationClassPostProcessor ,学此类者,胜过学九阳神功!胆小勿入!
Spring Import 三种用法与源码解读
  最近在看Spring Cloud相关的源码,每次引入一个新的starter,发现都会加一些enable的注解,比如:@EnableDiscoveryClient,用于将应用注册到Eureka Server并将Eureka Server有的服务拉取到微服务系统。点开EnableDiscoveryClient源码,便会发现里面用到了@import注解。源码如下:
良辰美景TT
2018/09/11
3.3K0
Spring Import 三种用法与源码解读
SpringBoot 是如何启动的
Spring源码中我已经知道的两种上下文: ClassPathXmlApplicationContext、AnnotationConfigApplicationContext
王小明_HIT
2022/06/14
6720
SpringBoot 是如何启动的
spring4.1.8扩展实战之八:Import注解
版权声明:欢迎转载,请注明出处,谢谢。 https://blog.csdn.net/boling_cavalry/article/details/82530167
程序员欣宸
2019/05/29
9900
你知道Spring是怎么解析配置类的吗?
这个流程图会随着我们的学习不断的变得越来越详细,也会越来越复杂,希望在这个过程中我们都能朝着精通Spring的目标不断前进!
程序员DMZ
2020/07/09
1.6K0
Spring源码学习笔记(7)——使用@Import导入组件
@Import注解的作用是导入其他的配置类或者组件,等同于在applicationContext.xml文件中添加如下配置
张申傲
2020/09/03
6750
@Configuration 类型的 class 需要知道的细节
@Configuration标识的类有这些特性:可以声明多个@Bean方法,且在运行时被spring容器处理来生成BeanDefinition。@Configuration类是被AnnotationConfigWebApplicationContext启动(bootstrap)处理流程的。声明方式如下代码
BUG弄潮儿
2021/12/27
5090
spring-boot-2.0.3不一样系列之番外篇 - @Configuration、Condition与@Conditional
   一名劫匪慌忙中窜上了一辆车的后座,上车后发现主驾和副驾的一男一女疑惑地回头看着他,他立即拔出枪威胁到:“赶快开车,甩掉后面的警车,否则老子一枪崩了你!”,于是副驾上的男人转过脸对那女的说:“大姐,别慌,听我口令把刚才的动作再练习一遍,挂一档,轻松离合,轻踩油门,走...走,哎 走...哎,哎,对,走走... 最后,三人都躺到了医院,劫匪的手上还戴上了铐子...
青石路
2019/03/06
6380
SpringBoot启动流程详解
注:其中起步依赖主要是解决版本控制问题,主要设计在于POM文件,这里主要探究第二优点自动装配。
花落花相惜
2021/12/16
1.8K0
Spring @Import注解源码解析
Spring 3.0之前,创建Bean可以通过xml配置文件与扫描特定包下面的类来将类注入到Spring IOC容器内。而在Spring 3.0之后提供了JavaConfig的方式,也就是将IOC容器里Bean的元信息以java代码的方式进行描述。我们可以通过@Configuration与@Bean这两个注解配合使用来将原来配置在xml文件里的bean通过java代码的方式进行描述
Java学习录
2019/08/29
7940
Spring @Import注解源码解析
解读SpringBoot和SpringMVC中配置类的@Impot等导入是如何解析的
首先,给出答案,SpringBoot和SpringMVC中配置类的@Impot等导入是通过Spring中的invokeBeanFactoryPostProcessors解析的
zhaozhen
2021/06/19
1.2K0
spring源码篇(六)配置类解析过程
一般我们都是用@Configuration来进行配置的,但是如上代码中的FBean,它也会被注册。这一个过程是怎么操作的我比较好奇,下面来慢慢探究。
用针戳左手中指指头
2021/09/10
5400
《Spring核心技术》第3章:深度解析@Bean注解
作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 源码地址:https://github.com/binghe001/spring-annotation-book/tree/master/spring-annotation-chapter-03
冰河
2023/02/21
6030
《Spring核心技术》第3章:深度解析@Bean注解
这一次搞懂SpringBoot核心原理(自动配置、事件驱动、Condition)
SpringBoot是Spring的包装,通过自动配置使得SpringBoot可以做到开箱即用,上手成本非常低,但是学习其实现原理的成本大大增加,需要先了解熟悉Spring原理。如果还不清楚Spring原理的,可以先查看博主之前的文章,本篇主要分析SpringBoot的启动、自动配置、Condition、事件驱动原理。
夜勿语
2020/09/07
7440
SpringBoot 配置类解析
SpringBoot作为Java领域非常流行的开源框架,集成了大量常用的第三方库配置,Spring Boot应用中这些第三方库几乎可以是零配置的开箱即用,大部分的 Spring Boot 应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。SpringBoot上手快,但是如果你的项目中业务场景需要一些特殊定制,甚至对源码进行定制化,那这时候了解原理就变成必需的了,只有充分了解源码,知道框架底层的工作原理,才能对源码中原有的机制进行修改 / 扩展等等。本文介绍了SpringBoot如何解析配置类、如何集成第三方配置。
2020labs小助手
2020/06/19
1.6K0
《Spring核心技术》第5章:三万字深度解析@Import注解
作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 源码地址:https://github.com/binghe001/spring-annotation-book/tree/master/spring-annotation-chapter-05
冰河
2023/03/24
4470
《Spring核心技术》第5章:三万字深度解析@Import注解
深入理解EnableAutoConfiguration原理
源码分析@EnableAutoConfiguration在SpringBoot中的加载和实例化过程
石奈子
2020/07/06
3.3K0
深入理解EnableAutoConfiguration原理
推荐阅读
相关推荐
Spring Boot 3.x 自动配置详解
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档