IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux内核源码分析之伙伴系统(四) -> 正文阅读

[系统运维]linux内核源码分析之伙伴系统(四)

目录

内核映射

1,持久内核映射

查找地址?

解除映射

2,临时内存映射

3,没有高端内存


内核映射

尽管 vmalloc 函数族可用于从高端内存域向内核映射页帧(这些在内核空间中通常是无法直接看
到的),但这并不是这些函数的实际用途。重要的是强调以下事实:内核提供了其他函数用于将
ZONE_HIGHMEM 页帧显式映射到内核空间,这些函数与 vmalloc 机制无关

1,持久内核映射

????????
????????如果需要将高端页帧长期映射(作为持久映射 )到内核地址空间中,必须使用 kmap 函数。需要映射的页用指向page 的指针指定,作为该函数的参数。
????????如果没有启用高端支持,该函数的任务就比较简单。在这种情况下,所有页都可以 直接访问 ,因此只需要返回页的地址,无需显式创建一个映射。
????????如果确实存在 高端页 ,情况会比较复杂。类似于vmalloc ,内核首先必须 建立高端页和所映射到的地址 之间的关联。还必须在虚拟地址空间中分配一个区域以映射页帧,最后,内核必须记录该虚拟区域的哪些部分在使用中,哪些仍然是空闲的。
数据结构:page_address_map?
???????? 建立物理内存的page实例与其在虚拟内存区中位置之间的关联。
struct page_address_map {
	struct page *page;
	void *virtual;
	struct list_head list;
};
  • 建立pagevirtual的映射
  • page是一个指向全局mem_map数组中的page实例的指针;
  • virtual指定了该页在内核虚拟地址空间中分配的位置。

查找地址?

????????page_address首先检查传递进来的 page 实例在普通内存还是在高端内存。如果是前者,页地址可以根据page mem_map 数组中的位置计算。对于后者,可通过上述散列表查找虚拟地址。

创建映射

为通过 page 指针建立映射,必须使用 kmap 函数。 它只是一个前端,用于确认指定的页是否确实
在高端内存域中。否则,结果返回 page_address 得到的地址。如果确实在高端内存中,则内核将工作委托给kmap_high ,该函数定义如下:

void *kmap_high(struct page *page)
{
	unsigned long vaddr;

	lock_kmap();
	vaddr = (unsigned long)page_address(page);
	if (!vaddr)
		vaddr = map_new_virtual(page);
	pkmap_count[PKMAP_NR(vaddr)]++;
	BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 2);
	unlock_kmap();
	return (void*) vaddr;
}
  • page_address函数首先检查该页是否已经映射。如果它不对应到有效地址,则必须使用map_new_virtual映射该页。
  • 从最后使用的位置(保存在全局变量last_pkmap_nr中)开始,反向扫描pkmap_count数组,直至找到一个空闲位置。如果没有空闲位置,该函数进入睡眠状态,直至内核的另一部分执行解除映射操作腾出空位。

解除映射

????????用kmap 映射的页,如果不再需要,必须用 kunmap 解除映射
关键函数: flush_all_zero_pkmaps
static void flush_all_zero_pkmaps(void)
{
	int i;
	int need_flush = 0;

	flush_cache_kmaps();

	for (i = 0; i < LAST_PKMAP; i++) {
		struct page *page;

		if (pkmap_count[i] != 1)
			continue;
		pkmap_count[i] = 0;

		BUG_ON(pte_none(pkmap_page_table[i]));

		page = pte_page(pkmap_page_table[i]);
		pte_clear(&init_mm, PKMAP_ADDR(i), &pkmap_page_table[i]);

		set_page_address(page, NULL);
		need_flush = 1;
	}
	if (need_flush)
		flush_tlb_kernel_range(PKMAP_ADDR(0), PKMAP_ADDR(LAST_PKMAP));
}

  • flush_cache_kmaps在内核映射上执行刷出,因为内核的全局页表已经修改;
  • 扫描整个pkmap_count数组。计数器值为1的项设置为0,从页表删除相关的项,最后删除该 映射;
  • 最后,使用flush_tlb_kernel_range函数刷出所有与PKMAP区域相关的TLB项。

2,临时内存映射

? ? ? ? kmap_atomic,其执行是原子的。该函数的一个主要优点是它比普通的kmap快速。但它不能用于可能进入睡眠的代码。因此,它对于很快就需要一个临时页的简短代码,是非常理想的。

void *kmap_atomic(struct page *page, enum km_type type)

3,没有高端内存

使用通用版本的kmap返回页的地址,且不修改虚拟内存。不能用于中断处理程序,如果pkmap数组中没有空闲位置,该函数会进入睡眠状态,直至情形有所改善。

void *kmap_high(struct page *page);
void kunmap_high(struct page *page);

static inline void *kmap(struct page *page)
{
	BUG_ON(in_interrupt());
	if (!PageHighMem(page))
		return page_address(page);
	return kmap_high(page);
}

static inline void kunmap(struct page *page)
{
	BUG_ON(in_interrupt());
	if (!PageHighMem(page))
		return;
	kunmap_high(page);
}

void *kmap_atomic(struct page *page);
void __kunmap_atomic(void *kvaddr);

参考

《深入Linux内核架构》

剖析Linux内核物理内存管理-大学生教程-腾讯课堂 (qq.com)


  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 13:09:20  更:2022-05-09 13:12:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 15:20:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码