page _refcount和_mapcount字段

news2024/11/24 20:32:32

linux page有两个非常重要的引用计数字段_refcount和_mapcount,都是atomic_t类型,其中,_refcount表示内核中应用该page的次数。当_refcount = 0时,表示该page为空闲或者将要被释放。当_refcount > 0,表示该page页面已经被分配且内核正在使用,暂时不会被释放。

_refcount

内核中常用的加减_refcount应用计数的API:get_page()和put_page()


static inline void get_page(struct page *page)
{
    page = compound_head(page);
    /*
     * Getting a normal page or the head of a compound page
     * requires to already have an elevated page->_refcount.
     */
    VM_BUG_ON_PAGE(page_ref_count(page) <= 0, page);
    page_ref_inc(page);
}

static inline void put_page(struct page *page)
{
    page = compound_head(page);

    /*
     * For private device pages we need to catch refcount transition from
     * 2 to 1, when refcount reach one it means the private device page is
     * free and we need to inform the device driver through callback. See
     * include/linux/memremap.h and HMM for details.
     */
    if (IS_HMM_ENABLED && unlikely(is_device_private_page(page) ||
        unlikely(is_device_public_page(page)))) {
        put_zone_device_private_or_public_page(page);
        return;
    }

    if (put_page_testzero(page))
        __put_page(page);
}

增加_refcount场景
1)alloc_pages 分配成功_refcount = 1

2)加入到lru链表

3)加入到address_space

上面三个路径可以通过write写数据场景结合源码分析,我们知道write系统调用可以使用page cache加速写性能,我们就以该场景看下page->_refcount引用计数的变化情况。write写数据场景的page cache创建是mm/filemap.c : grab_cache_page_write_begin

/*
 * Find or create a page at the given pagecache position. Return the locked
 * page. This function is specifically for buffered writes.
 */
struct page *grab_cache_page_write_begin(struct address_space *mapping,
					pgoff_t index, unsigned flags)
{
	struct page *page;
	int fgp_flags = FGP_LOCK|FGP_WRITE|FGP_CREAT;
    ...

no_page:
	if (!page && (fgp_flags & FGP_CREAT)) {
        ..
		page = __page_cache_alloc(gfp_mask);
		if (!page)
			return NULL;

		if (WARN_ON_ONCE(!(fgp_flags & (FGP_LOCK | FGP_FOR_MMAP))))
			fgp_flags |= FGP_LOCK;

		/* Init accessed so avoid atomic mark_page_accessed later */
		if (fgp_flags & FGP_ACCESSED)
			__SetPageReferenced(page);

		err = add_to_page_cache_lru(page, mapping, index, gfp_mask);
		if (unlikely(err)) {
			put_page(page);
			page = NULL;
			if (err == -EEXIST)
				goto repeat;
		}

		/*
		 * add_to_page_cache_lru locks the page, and for mmap we expect
		 * an unlocked page.
		 */
		if (page && (fgp_flags & FGP_FOR_MMAP))
			unlock_page(page);
	}

	return page;
}
  1. __page_cache_alloc通过alloc_page创建页面,page刚刚创建_refcount = 1
  2. add_to_page_cache_lru将page分别加入lru链表和address_space,这两个步骤中都会增加_refcount,该函数返回后_refcount = 3

add_to_page_cache_lru


int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
				pgoff_t offset, gfp_t gfp_mask)
{
	void *shadow = NULL;
	int ret;

	__SetPageLocked(page);
	ret = __add_to_page_cache_locked(page, mapping, offset,
					 gfp_mask, &shadow);
	if (unlikely(ret))
		__ClearPageLocked(page);
	else {
		...
		if (!(gfp_mask & __GFP_WRITE) && shadow)
			workingset_refault(page, shadow);
		lru_cache_add(page);
	}
	return ret;
}


static int __add_to_page_cache_locked(struct page *page,
				      struct address_space *mapping,
				      pgoff_t offset, gfp_t gfp_mask,
				      void **shadowp)
{
    ...
	get_page(page);
    ...
error:
	page->mapping = NULL;
	/* Leave page->index set: truncation relies upon it */
	put_page(page);
	return error;
}

void lru_cache_add(struct page *page)
{
    ...
	get_page(page);
    ...
}

_add_to_page_cache_locked和lru_cache_add都会增加_refcount引用计数。

4)page被映射到其他用户进程pte时,_refcount引用技数会加1。

例如子进程创建时共享父进程的地址空间,设置父进程的pte页表项内容到子进程中并增加该页的_refcount计数:

do_fork->copy_process->copy_mm->dup_mmap->copy_page_range->...->copy_pte_range->copy_one_pte函数。

5) 对于PG_swapable的页面,_add_to_swap_cache会增加_refcount引用计数

6)内核对页面进程操作的一些关键路径上也会增加_refcount。比如内核的follow_page和get_user_pages

_mapcount

_mapcount表示这个页面被进程映射的个数,即已经映射了多少个用户pte页表。

  • _mapcount = -1,表示没有pte映射到该页面中
  • _mapcount = 0,表示只有父进程映射了页面,匿名页面刚分配时,_mapcount = 0
  • _mapcount > 0,表示除了父进程外还有其他进程映射了这个页面,同样以子进程创建共享父进程地址空间为例,设置父进程的pte页表项到子进程中并增加该页面的_mapcount。

get_page增加_refcount,page_dump_rmap增加_mapcount

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/784013.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

APP-脱壳+反编译

APP反编译加固-自动查壳脱壳 为什么要脱壳&#xff1f; 因为不脱壳无法进行反编译 查壳工具&#xff1a;https://pan.baidu.com/s/1rDfsEvqQwhUmep1UBLUwSQ 密码: wefd 脱壳工具&#xff1a;https://github.com/CodingGay/BlackDex 查壳演示&#xff1a; 使用Java运行jar包&a…

浙江大学软件学院2022保研经历分享

首先&#xff0c;我想强调一点&#xff0c;如果我们只是一个普通的非211&#xff0c;985的本科生&#xff0c;一定要参加浙江大学每年7月份组织的夏令营&#xff0c;因为浙大的夏令营是一个海王营&#xff0c;基本上不会对入营的学生做筛选&#xff0c;但是要想获得优秀营员&am…

pandas笔记:groupby整理

0 数据集 # Visual Python: Data Analysis > File vp_df pd.read_csv(https://raw.githubusercontent.com/visualpython/visualpython/main/visualpython/data/sample_csv/fish.csv) vp_df 1 单列聚合 vp_df.groupby(Type)[Kg].mean()Type mackerel 1.417456 salmon…

【C语言项目】三子棋

文章目录 项目思路一、分文件进行创建二、进入游戏前的目录2.1 目录的功能&#xff1a;2.2 目录界面&#xff1a;2.3 选择进入或退出游戏2.4 多次重玩功能 三、画出棋盘3.1 写出棋子3.2 初始化棋盘3.2 画出棋盘的框架3.3 代码实现 四、玩家落子4.1 落子逻辑4.2具体情况分类讨论…

初识C++(下)——“C++”

各位CSDN的uu们你们好呀&#xff0c;今天终于是小雅兰的初识C的下的文章啦&#xff0c;下面&#xff0c;让我们进入C的世界吧&#xff01;&#xff01;&#xff01; 内联函数 我们首先得知道&#xff1a;C中的内联函数是用来解决C语言中宏的坑的&#xff01;&#xff01;&…

jenkins中配置了发送邮件,构建后却没有发邮件Not sent to the following valid addresse

【问题描述】&#xff1a;jekins中配置了发送邮件&#xff0c;构建后却没有发邮件的问题&#xff0c;构建报错&#xff1a;Not sent to the following valid addresse 【报错显示】&#xff1a; 【问题定位】&#xff1a;Extended E-mail Notification中&#xff0c;没有配置…

【Docker】Docker的使用案例以及未来发展、Docker Hub 服务、环境安全的详细讲解

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…

LabVIEW - 串口通信

1. 题目 使用并行程序设计技术&#xff0c;实现串口通信/TCP通信/UDP通信&#xff08;任选3者一种&#xff0c;其中TCP为客户端&#xff09;数据发送和数据接收功能在各自的线程中实现&#xff0c;即一个线程只管处理数据发送功能的实现&#xff0c;另一个线程只管数据接收和数…

P2698 [USACO12MAR] Flowerpot S

P2698 [USACO12MAR] Flowerpot S 文章目录 P2698 [USACO12MAR] Flowerpot S题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路分析code [P2698 USACO12MAR] Flowerpot S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 Farmer John has been having …

【漏洞复现】厦门才茂通信网关formping远程命令执行漏洞

文章目录 前言声明一、漏洞描述二、漏洞复现 前言 厦门才茂通信网关formping存在远程命令执行漏洞&#xff0c;攻击者可通过特定payload对目标服务器发起攻击&#xff0c;造成不可估量的影响。 声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提…

文心一言 VS 讯飞星火 VS chatgpt (65)-- 算法导论6.5 4题

四、在 MAX-HEAP-INSERT 的第 2行&#xff0c;为什么我们要先把关键字设为 -∞ &#xff0c;然后又将其增加到所需的值呢? 文心一言&#xff1a; 在 MAX-HEAP-INSERT 算法的第二行将关键字设为 -∞&#xff0c;是为了保持堆的性质。堆是一种二叉树结构&#xff0c;其中每个节…

python调用文心千帆大模型

一、登录智能云控制台 https://console.bce.baidu.com/ 二、创建AI应用 已登录状态下&#xff0c;进入控制台创建应用 https://console.bce.baidu.com/ai/#/ai/easydlLiteNlp/app/list 应用创建后获取AppID、API Key、Secret Key 三、API调用 import requests import jso…

uniapp项目集成本地插件

在项目根目录下创建nativeplugins文件夹 拷贝插件到目录nativeplugins 在manifest.json -> App原生插件配置 -> 本地插件里勾选插件 删除本地基座和手机app从新自定义基座运行

大白话讲讲 Go 语言的 sync.Map(一)

阅读本文大约需要 4.25 分钟。 程序是枯燥乏味的。 在讲 sync.Map 之前&#xff0c;我们先说说什么是 map&#xff08;映射&#xff09;。 我们每个人都有身份证号码&#xff0c;如果我需要从身份证号码查到对应的姓名&#xff0c;用 map 存储是非常合适的。 map[000...001…

[驱动开发]字符设备驱动应用——点灯

点亮开发板stm32mp157的三盏灯 //头文件 #ifndef __LED_H__ #define __LED_H__//封装GPIO寄存器 typedef struct { volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsign…

C++面向对象三大特性 -- 继承

目录 一、继承的概念和定义1.1 继承的概念1.2 继承定义1.2.1定义格式1.2.2 继承方式和访问限定符1.2.3 继承基类成员访问方式的变化 二、父类和子类对象赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承和友元六、继承与静态成员七、复杂的菱形继承及菱形虚拟继承八…

小程序之移花宫-自定义底部标签图标---【浅入深出系列005】

浅入深出系列总目录在000集 如何0元学微信小程序–【浅入深出系列000】 不会导入/打开小程序的看这里 让别人的小程序长成自己的样子-更换window上下颜色–【浅入深出系列001】 文章目录 本系列校训学习资源的选择 学习目标图标的注意事项图标资源打开小程序动手实践找到图标最…

k8s使用helm部署Harbor镜像仓库并启用SSL

1、部署nfs存储工具 参照&#xff1a;https://zhaoll.blog.csdn.net/article/details/128155767 2、部署helm 有多种安装方式&#xff0c;根据自己的k8s版本选择合适的helm版本 参考&#xff1a;https://blog.csdn.net/qq_30614345/article/details/131669319 3、部署Harbo…

P1168 中位数(做法1:使用两个堆,大根堆维护较小的值,小根堆维护较大的值;做法二:vector(pos,x);在地址pos后面加入x)

ACCcode: #include<bits/stdc.h> using namespace std; #define int long long int n,x,mid; priority_queue<int,vector<int>,less<int> >q1;//大根堆 priority_queue<int,vector<int>,greater<int> >q2;//小根堆 void solve() {ci…

逻辑漏洞原理及实战

前言 作者简介&#xff1a;不知名白帽&#xff0c;网络安全学习者。 博客主页&#xff1a;不知名白帽_网络安全,CTF,内网渗透-CSDN博客 网络安全交流社区&#xff1a;https://bbs.csdn.net/forums/angluoanquan 目录 逻辑漏洞基础 概述 分类 URL跳转漏洞 概述 危害 漏洞…