临时内核映射

临时内核映射与永久内核映射的区别是,临时内核映射可以在中断处理程序和可延迟函数内部使用,它不堵塞当前进程。

一 原理介绍

临时内核映射的线性地址在永久内核映射的后面,范围是[FIXADDR_START, FIXADDR_TOP),其基本逻辑是获取一个计数值n,用FIXADDR_TOP - n*4k 得到映射的线性地址。n不同,得到的线性地址也就不相同,内核是如何确保不同线程得到的n值不同的呢。

有两个措施:

1. 每cpu变量__kmap_atomic_idx (见kmap_atomic_idx_push函数)

对于每cpu变量__kmap_atomic_idx,每个cpu都维护着一个计数,比如cpu1保存的计数是3,而cpu2保存的计数是5。映射高端内存时,将计数加1,取消映射时,将计数减1。

假如一个线程运行在cpu1上,映射内存时计数加1,__kmap_atomic_idx的值变为4;另一个线程运行在cpu2上,映射内存后计数加1,__kmap_atomic_idx的值为6。

2. 每个cpu有KM_TYPE_NR个固定映射的线性地址

KM_TYPE_NR的值为20,即[0, 20),为第一个cpu的取值范围,[20, 40)为第二个cpu的取值范围,以此类推。

idx = type + KM_TYPE_NR*smp_processor_id();

 上面的逻辑可以参考下图

图1

二 临时内核映射代码 

有了上面的介绍后,下面看下临时内核映射的代码,kmap_atomic

static inline int kmap_atomic_idx_push(void)
{int idx = __this_cpu_inc_return(__kmap_atomic_idx) - 1;return idx;
}void *kmap_atomic_prot(struct page *page, pgprot_t prot)
{unsigned long vaddr;int idx, type;preempt_disable();pagefault_disable();// 非高端内存,直接返回其线性地址if (!PageHighMem(page))return page_address(page);// 获取每cpu变量__kmap_atomic_idx的值,并将值加1type = kmap_atomic_idx_push();idx = type + KM_TYPE_NR*smp_processor_id();vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);BUG_ON(!pte_none(*(kmap_pte-idx)));// 将页框添加到页表中set_pte(kmap_pte-idx, mk_pte(page, prot));arch_flush_lazy_mmu_mode();return (void *)vaddr;
}void *kmap_atomic(struct page *page)
{return kmap_atomic_prot(page, kmap_prot);
}

kmap_atomic_prot中的idx即经过前面提到的两个措施后,得到的值。

获取线性地址vaddr时,FIX_KMAP_BEGIN是个枚举值,可参考enum fixed_addresses。

vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);

三 __fix_to_virt

__fix_to_virt的作用是将固定映射的一个值转成线性地址,其定义如下:

#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))

32位系统地址空间如下图所示:

图2 

对于32位系统,FIXADDR_TOP为0xFFFFF000,即地址空间最后一个4K的起始地址

对于64位系统,FIXADDR_TOP为0xFFFFFFFF FF600000,也在线性地址空间最后的位置

x为0时, __fix_to_virt得到临时内核映射线性区最后一页的线性地址;x为1时,得到倒数第二页的线性地址,以此类推。

四 kmap_pte

kmap_pte的作用,与永久内核映射中的pkmap_page_table作用的一样的,也是指向一个页表。与pkmap_page_table不同的是,kmap_pte指向的是临时映射所用页表的结束位置。

set_pte(kmap_pte-idx, mk_pte(page, prot));

kmap_pte在kmap_init中初始化

static void __init kmap_init(void)
{unsigned long kmap_vstart;/** Cache the first kmap pte:*/kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
}

图3

kmap_vstart距离FIXADDR_TOP有 FIX_KMAP_BEGIN * 4K的,如上图所示,kmap_pte为kmap_vstart所在的页表。

五 kmap_get_fixmap_pte

调用kmap_get_fixmap_pte将kmap_vstart转换成kmap_pte。

static inline pte_t *kmap_get_fixmap_pte(unsigned long vaddr)
{pgd_t *pgd = pgd_offset_k(vaddr); // 页全局目录p4d_t *p4d = p4d_offset(pgd, vaddr);pud_t *pud = pud_offset(p4d, vaddr); // 页上级目录pmd_t *pmd = pmd_offset(pud, vaddr); // 页中间目录return pte_offset_kernel(pmd, vaddr); // 页表
}

六 kmap_atomic在内核中的应用

在一个函数中只调用一次kmap_atomic,如下所示:

void read_inline_data(struct page *page, struct page *ipage)
{struct inode *inode = page->mapping->host;void *src_addr, *dst_addr;if (PageUptodate(page))return;f2fs_bug_on(F2FS_P_SB(page), page->index);zero_user_segment(page, MAX_INLINE_DATA(inode), PAGE_SIZE);/* Copy the whole inline data block */src_addr = inline_data_addr(inode, ipage);// 映射dst_addr = kmap_atomic(page);memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode));flush_dcache_page(page);// 取消映射kunmap_atomic(dst_addr);if (!PageUptodate(page))SetPageUptodate(page);
}

映射后得到线性地址dst_addr,对线性地址进行操作,最后取消映射。

在一个函数中调用多次 kmap_atomic,看下面代码:

void copy_user_highpage(struct page *to, struct page *from,unsigned long u_vaddr, struct vm_area_struct *vma)
{void *kfrom = kmap_atomic(from);void *kto = kmap_atomic(to);int clean_src_k_mappings = 0;... ...kunmap_atomic(kto);kunmap_atomic(kfrom);
}

先映射from页框得到线性地址kfrom,再映射页框to得到线性地址kto。每调用一次kmap_atomic,运行此段代码的cpu保存的__kmap_atomic_idx就加1,因此最后得到的线性地址kfrom和ktto就不相同。

线性地址使用完毕后,调用kunmap_atomic取消映射,对应cpu保存的__kmap_atomic_idx的值也减1。

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

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

相关文章

vivo 基于 StarRocks 构建实时大数据分析平台,为业务搭建数据桥梁

在大数据时代&#xff0c;数据分析和处理能力对于企业的决策和发展至关重要。 vivo 作为一家全球移动互联网智能终端公司&#xff0c;需要基于移动终端的制造、物流、销售等各个方面的数据进行分析以满足业务决策。 而随着公司数字化服务的演进&#xff0c;业务诉求和技术架构有…

基于MATLAB优化的多焦点相位

1、概要 目前智能手机的显示屏得益于机械或化学性能的稳定&#xff0c;让这些手机非常耐用&#xff0c;显示屏具有足够硬度使其可以承受住很大的压力&#xff0c;甚至多年使用下来都没有磨损迹象。 但是另一方面&#xff0c;材料的硬度通常伴随着脆性&#xff0c;手机的屏幕玻…

第四十二回 假李逵翦径劫单身 黑旋风沂岭杀四虎-python读写csv和json数据

李逵答应了宋江三件事&#xff1a;不可吃酒&#xff0c;独自前行&#xff0c;不带板斧。李逵痛快答应了&#xff0c;挎一口腰刀&#xff0c;提着朴刀&#xff0c;带了一锭大银子&#xff0c;三五个小银子就下山去了。 宋江放心不下&#xff0c;于是请同乡朱贵也回家一趟&#…

【Postman+Newman】接口自动化测试以及测试报告输出

Newmanpostman自动化测试 postmanPre-request Script前置脚本 Newman测试报告输出 postman 学习postman脚本编写 Pre-request Script前置脚本 Newman 测试报告输出 输出报告时使用的命令&#xff1a;     -r html,json,junit 指定生成html&#xff0c;json&#xff0c…

Java并发-并发编程的三个核心问题

文章目录 并发编程的三个核心问题参考 并发编程的三个核心问题 并发编程可以总结为三个核心问题&#xff1a;分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程&#xff0c;而同步指的是线程之间如何协作&#xff0c;互斥则是保证同一时刻只允许一个线程访问…

猫头虎分享已解决Bug || Rust Error: expected function, found module ‍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【Java程序设计】【C00277】基于Springboot的招生管理系统(有论文)

基于Springboot的招生管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的招生管理系统 本系统分为系统功能模块、管理员功能模块以及学生功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、专业…

Git diff Word 文档

前言 前段时间用 nodeJS 写了一个提交代码的工具&#xff0c;开发过程中在认证部分遇到了一些小问题&#xff0c;于是就想看看官方的文档中有没有什么说明之类的&#xff0c;没想到文档中的内容十分丰富&#xff0c;除了解释了 git 相关的原理外&#xff0c;还学到了很多有用的…

软考-中级-系统集成2023年综合知识(三)

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 软考中级专栏回顾 专栏…

【PythonGIS】基于Python融合矢量数据(多面合一)

之前发过使用批量合并矢量数据的文章&#xff1a;【Python&GIS】基于Python批量合并矢量数据&#xff0c;正好前段时间有需求把矢量数据进行融合&#xff0c;然后就编了一段融合矢量数据的代码。今天就和大家分享一下如何使用Python对矢量数据实现融合的操作。 1.定义 首先…

金南瓜SECS/GEM如何添加工程?

公开资料皆为是2、3年前版本 编译SecsEquip.dll依赖库 ① 打开示例程序中的SecsEquip项目 ② 选中SecsEquip工程&#xff0c;右键选择属性 如果没有“解决方案资源管理器”页面&#xff0c;可以从菜单的“视图”->“解决方案资源管理器”打开 ③ 选择跟设备相同的NET版本…

This dependency was not found解决方法

问题如上(前端代码)&#xff0c;我是引用js文件出的问题&#xff0c;无法找到api/userManage模块。 解决&#xff1a;没感觉哪有问题&#xff0c;把后面加了个/&#xff0c;就解决了&#xff0c;代表src目录&#xff0c;应该是目录和目录之间应该有/作为分割&#xff1a;

python 提取PDF文字

使用pdfplumber&#xff0c;不能提取扫描的pdf和插入的图片。 import pdfplumberfile_path rD:\UserData\admindesktop\官方文档\1903_Mesh-Models-Overview_FINAL.pdf with pdfplumber.open(file_path) as pdf:page pdf.pages[0]print(page.extract_text()) # 所以文字prin…

DIcom调试Planar configuration

最近和CBCT组同事调dicom图像 这边得图像模块老不兼容对方得dicom文件。 vtk兼容&#xff0c;自己写得原生解析不兼容。 给对方调好了格式&#xff0c;下次生成文件还会有错。 简单记录下&#xff0c;日后备查。 今天对方又加了 个字段&#xff1a;Planar configuration 查…

koa项目部署云服务器(部署本地虚拟机中)

文章目录 一、服务器安装Node、MySQL1.1. 安装Node.js1.2. 安装MySQL1.3.配置MySQL1.4. 数据库迁移 二. 部署Node项目2.1. 代码托管到Git仓库&#xff08;选做&#xff09;2.2. 代码clone到服务器&#xff08;选做&#xff09;2.3. VSCode中打开代码&#xff08;推荐&#xff0…

【二十七】【C++】二叉树练习

606. 根据二叉树创建字符串 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 "()" 表示&#xff0c;转化后需要省略所有不影响字符串与…

集成TinyMCE富文本编辑器

若依的基础上集成TinyMCE富文本编辑器 前端bootstrap TinyMCE官网链接 TinyMCE所需静态资源下载链接 开源项目-若依链接 将TinyMCE静态资源包放入项目中&#xff1b; 代码引入css&#xff1a; <!-- 引入TinyMCE CSS --><link th:href"{/ajax/libs/tinymce/j…

抖音视频评论数据提取软件|抖音数据抓取工具

一、开发背景&#xff1a; 在业务需求中&#xff0c;我们经常需要下载抖音视频。然而&#xff0c;在网上找到的视频通常只能通过逐个复制链接的方式进行抓取和下载&#xff0c;这种操作非常耗时。我们希望能够通过关键词自动批量抓取并选择性地下载抖音视频。因此&#xff0c;为…

什么是调制比

一般情况下&#xff0c;调制波和载波的最大幅值是不一样的。 正弦波的最大幅值低于三角波的最大幅值。 这样做的目的就是产生最大占空比&#xff08;2000W逆变器中最大占空比是80%&#xff09; 调制波就是正弦波的最大幅值比三角载波的最大幅值 问题1 为什么调制波要小于1&…

Oracle不能启动,提示设备空间不足,实际上是信号量不够(ORA-27300,ORA-27301,ORA-27302)

我的一个客户的Oracle数据库不能启动&#xff0c;出现下面的提示&#xff1a; ORA-27154: post/wait create failed ORA-27300: OS system dependent operation:semget failed with status: 28 ORA-27301: OS failure message: No space left on device ORA-27302: failure oc…