LWN:对user-space pages进行明确的pin操作!

内存管理之——get_user_pages和pin_user_pages及缺页异常 内存管理,锁内存函数get_user_pages/pin_user_pages,以及内存管理核心函数follow_page_mask,缺页异常核心函数handle_mm_fault 阅读详情

关注了就能看到更多这么棒的文章哦~

Explicit pinning of user-space pages

By Jonathan Corbet
December 13, 2019

原文来自:https://lwn.net/Articles/807108/

get_user_pages()和它所导致的kernel问题,已经在LWN上有过多篇介绍了,看这里:https://lwn.net/Kernel/Index/#Memory_management-get_user_pages 。简单来说,get_user_pages()是用来把user-space pages给钉在memory里面,供其他人(除了拥有它以外的其他人)来进行某种操作。这些操作可能会让kernel里其他一些以为对这个page有独占访问权限的部分碰到一些意外情况。John Hubbard提出了一组patch,虽然没有解决所有问题,但也是建立了一个解决这类问题的通用框架。

简要来说,get_user_pages()相关的问题有两种形式。一种是当kernel以为这个page里的内容不会改变的时候,某个外设却在这里进行了写入操作。另一种情况,如果这个memory是位于文件系统管理的persistent-memory设备上的情况,把page pin到memory的话,文件系统就不能对跟这个page有关的memory进行layout调整了。这个问题目前的解决办法是不允许在persistent-memory设备上进行这种非易失性page相关的pin操作,不过确实有些应用场景里面真的需要这样做,所以还是需要更好的解决方案。

这里部分问题来自get_user_pages()不会对pin到RAM的page进行任何专门记录。虽然会增长引用计数来确保不会被挤出memory,不过这样pin进内存的page跟其他那些途径pin进来的page完全无法区分。这样一来,我们虽然可以知道某个page是否有引用,却没有办法知道page是否是因为DMA I/O等目的pin进来的。

Hubbard的patch set就是针对这一点的。首先引入了一些新的内部函数来作为get_user_pages()系列函数的替代:

    long pin_user_pages(unsigned long start, unsigned long nr_pages,
		    	unsigned int gup_flags, struct page **pages,
		    	struct vm_area_struct **vmas);
    long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm,
			       unsigned long start, unsigned long nr_pages,
			       unsigned int gup_flags, struct page **pages,
			       struct vm_area_struct **vmas, int *locked);
    int pin_user_pages_fast(unsigned long start, int nr_pages,
			    unsigned int gup_flags, struct page **pages);

在调用者看来,这些新的函数跟之前的get_user_pages()系列没有什么不同。所以切换起来很容易,只要替换一下调用的函数名即可。用这种方法pin进来的page在释放的时候必须要用新增的unpin_user_page()和unpin_user_pages()函数,这些是Hubbard在2019年上半年加进来替代put_user_page()的。

开发者该如何选择get_user_pages()和pin_user_pages()呢?在patch里增加的文档里面有描述。简单来说,如果pin page的目的仅仅是为了访问这些page里的内容,那么应该使用pin_user_pages()。如果是为了操作page structure而不是访问page内容本身,那么应给使用get_user_pages()。

新增的函数会告知kernel这次调用的目的,不过大家肯定还想知道如何记录管理这些pin进来的page。肯定需要某种引用计数,因为某个page可能会被pin多次,那么直到最后一个用户也调用unpin_user_pages()来释放后才会解除pin状态。理论上来说应该把引用计数放到struct page里面,不过有个小问题:这个struct里面的内容已经塞得很满了,又不能增大这个结构。

最终选择的方案是继续利用page现有的引用计数。调用get_user_pages()会导致引用计数加一从而完成pin的操作。而调用pin_user_pages()则会给它加GUP_PIN_COUNTING_BIAS,在这组patch的第23个patch里面定义为1024。Kernel代码可以通过调用page_dma_pinned()来确定某个page是否是这样pin进来的,其实只要简单检查page的引用计数是否超过了1024。

这样使用引用计数的话会有一些需要注意的地方。如果某个page通过正常方式增加引用计数而超过了1024的话,就会被误认为是pin进来做DMA的。patch set里也承认有这个行为,不过并不认为是一个问题,因为这样导致的误报并不会影响系统的行为。还有一个可能影响更大的问题,这个引用计数只有21个bit的空间,这意味着关于pin本身的引用计数就只有11个bit可用了。对多数情况来说应该够用了,不过如果是在pin一个compound page的时候,在每次pin一个tail page的时候都要把第一个page再pin一次。一个1GB的compound page包含256个4KB page,这样一来,这个page只要被pin 8次就会导致引用计数溢出了。

Hubbard认为解决方法是让get_user_pages()系列函数都要能认识huge page,如此一来引用计数就只需要增加一次就好了。不过这需要做不少改动,需要一些时间,因此没有包含在这组patch set里面,毕竟目前已经有了25个patch,改动已经很大了。

还有一点需要注意:kernel应该如何处理这样pin进来的page呢?也就是Hubbard所问的:“碰到这种情况之后该如何处理,留待后续patch吧”。比如说可以按Ira Weiny提出的layout lease方案,通过提供一个机制来让那些长期保持pin状态的page在有需要的时候可以unpin掉。目前还不清楚应该如何实现这个机制,可以说get_user_pages()的完整解决方案还需要不少时间。预计在2020 Linux Storage, Filesystem, and Memory-Management Summit峰会上会是一个热门议题。

至少kernel目前已经能够利用这个机制来识别并跟踪pinned page了,这是我们朝正确方向迈出的一小步。这些patch已经经过了多轮迭代,可能很快会合入Andrew Morton的-mm tree了。这样很可能会合入5.6 kernel中。

全文完

LWN文章遵循CC BY-SA 4.0许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~

linux那些事之pin memory相关API 内核中为pin memory 用户空间申请物理内存除了get_user_pages() API函数之外,还有其他相关一系列函数,主要位于mm\gup.c 主要都是针对get_user_pages进行的扩展,以满足各种不同需求。 pin_user_pages pin_user_pages()为用户空间锁定物理页,与get_user_pages函数基本相同,差别在于gup_flags标志位不同: /** * pin_user_pages() - pin user pages in memory for 阅读详情

相关推荐

get_user_page

1,get_user_pages函数详解 https://liujunming.top/2017/07/03/get-user-pages%E5%87%BD%E6%95%B0%E8%AF%A6%E8%A7%A3/ 2,页面的引用计数和get_user_pages https://blog.youkuaiyun.com/iteye_5014/article/details/81824739 3,Linux Kernel get_user_pages() 源码分析 https://v1ckydxp.github.

yiyeguzhou100的专栏 3408

rdma 虚拟地址物理地址转换

RDMA的虚实地址转换

baidu_38316985的博客 1573

【信息科学与工程学】【产品体系】第三十三篇 DPU/smartinic芯片中的学科知识03

需求实现DMA 与流边界检测优化​分级超时状态机(短/中/长)+ 积压计数 + 批量触发DMA 控制器优化​描述符预取(深度 4)+ 中断合并(阈值 8)Fence 语义正确性验证​RTL 断言 + C 语言序列号检测 + 性能对比 + 硬件计数器所有代码均为可综合 Verilog,已在仿真器中通过基本功能测试。在 FPGA 原型上运行上述 RTL,配合 ChipScope 观察 fence 时序在 BlueField-3 上运行 DOCA DPA 测试程序,对比加/不加 fence 的结果。

weixin_49199313的博客 272

get_user_pages和get_user_pages_fast的区别

最近工作中经常遇见get_user_pages和get_user_pages_fast,虽然知道他们都是用来pin住一个页的,但是依然没搞明白后者是如何实现fast的,两者的区别具体在哪。刚好利用周末时间研究一下。本文的分析基于linux 4.19.195. 先看看get_user_pages_fast函数的定义 /** * get_user_pages_fast() - pin user pages in memory * @start: starting user address * @nr_pa

kaka__55的博客 5453

非gdb方式观察应用程序的运行时的变量状态

非gdb方式观察应用程序的运行时的变量状态

zhaoxin1989的博客 1万+

linux那些事之pin memory(get_user_pages())

pin memory 通常一个应用程序使用malloc或者mmap申请到的只是虚拟内存,只有在第一次访问该地址时触发page fault才为其申请物理内存称为按需分配内存。整个映射过程其实用户是无法感知,但是触发一次page fault非常耗时。有时应用程序为了优化性能,通常采用pin memory的形式即使用mmap/malloc时提前将虚拟内存与对应物理内存锁定,以提高性能,这也是很多程序常用优化方法。 pin memory好处还有另外一个优势就是可以防止内存被swap out置换到存储器中,如果在

weixin_42730667的博客 6736

The GPU Memory Subsystem as a Mirror of CPU Memory Management: A Structural Analogy

Abstract: The Linux GPU memory management subsystem (TTM/GEM/GPUVM) is a domain-specific reimplementation of classical CPU virtual memory principles, adapted for accelerator hardware.

图形/计算GPU的驱动与虚拟化技术分享园地 697

获取内存内容的几种方法

获取内存内容的几种方法,远程进程用户空间内容获取,内核空间内容获取,vdso,vsyscall,/proc/kcore

zhaoxin1989的博客 4332

Linux 内存 --- get_user_pages/pin_user_pages函数

本文介绍了Linux内核中固定用户内存页(pin user pages)的概念及其实现机制。

小立仔 1630

BUUCTF逆向题Youngter-drive

其实线程一代码我自己也不大理解,看了正确的 flag 后,我自己推出来的是这样:在 couece 中取出字符,然后在 QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm 中找出一样的,取出该字符在 QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm 中的下标,如果取出的字符是大写则 在ASCII中找出【下标 - 38】值对应的字符替换couece中的字符,同理,小写就减 96。

于高山之巅,方见大河奔涌;于群峰之上,更觉长风浩荡。 1090

YOLOv8实战:5分钟搞定Windows环境下的目标检测模型部署(附常见报错解决方案)

本文详细介绍了在Windows环境下快速部署YOLOv8目标检测模型的实战指南,包括环境配置、模型加载、快速验证及常见报错解决方案。通过5分钟快速入门教程,帮助开发者高效实现计算机视觉应用,特别适合需要快速上手的AI开发者。

weixin_30566063的博客 556

Linux的页迁移(Page Migration)

对于用户空间的应用程序,我们通常根本不关心page的物理存放位置,因为我们用的是虚拟地址。所以,只要虚拟地址不变,哪怕这个页在物理上从DDR的这里飞到DDR的那里,用户都基本不感知。那么,为什么要写一篇论述页迁移的文章呢? 我认为有2种场景下,你会关注这个Page迁移的问题:一个是在Linux里面写实时程序,尤其是Linux的RT补丁打上后的情况,你希望你的应用有一个确定的时延,不希望跑着跑着你的Page正在换位置而导致的延迟;再一个场景就是在用户空间做DMA的场景,尤其是SVA(SharedVirtua

lx123010的专栏 2110

of_graph_get_remote_port

isp { compatible = "isp"; core@0 { id = <0>; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; ...

wmzjzwlzs的专栏 1164

Linux 物理内存管理涉及的三大结构体之struct page

本文主要详细的介绍了内存管理中三大结构体的struct page。将struct page里面的每个部分拆分出来,结合代码,对每个部分,每个成员变量尽力做到详细讲解。如果不对之处,请指正。最后想说的是:struct page结构的设计充分体现了内核设计人员为了减少内存占用的所做出的各种努力,且这种努力还在一直在继续。

weixin_45337360的博客 4656

深入解析FOC电流环PI参数整定:从理论到实践

本文深入解析了FOC(磁场定向控制)中电流环PI参数整定的核心原理与实践方法。文章从永磁同步电机模型出发,详细阐述了基于带宽与零极点对消的工程法及考虑逆变器延迟的二阶系统整定法两种经典策略,并提供了从理论计算到安全上电调试的完整步骤与常见问题解决方案,帮助工程师精准调校电机控制性能。

weixin_29164497的博客 446

小爱音箱Play增强版刷机接入大模型:自定义唤醒词与远程控制全攻略

智能音箱作为家庭语音入口,受限于厂商预设技能,难以满足个性化需求。通过串口刷机与Linux系统分区改造,可以完全掌控设备底层,将豆包、通义千问等大模型API接入原有音频链路,实现真正智能的语音问答。自定义唤醒词打破了“小爱同学”的唯一唤醒方式,结合ESP32-S3外挂模块,还能优化远场拾音。更深入的应用在于将音箱打造为家庭中控,通过大模型工具调用解析自然语言指令,实现远程控制电脑、智能灯等设备。本文从设备选型、拆机串口、系统备份到语音链路搭建,完整梳理了小爱音箱Play增强版的改造路径,适合具备动手能力的开

weixin_30036289的博客 705

【技术解析】带你了解设备透传虚拟机的快速启动技术优化方案

IOMMU_MAP_DMA 的 ioctl 进入内核空间会执行到 vfio_pin_map_dma 函数,在这个函数里会对虚拟机内存大小的虚拟内存进行 iommu map 操作,首先调用 vfio_pin_pages_remote 进行内存 pin 操作,这个函数的返回值 npage 是物理地址连续的N个内存页,然后调用 vfio_iommu_map 执行 iommu map 操作,比如对于 500G 内存的虚拟机来说会执行很多次这两个函数。

m0_63147799的博客 134

SAP FAGLFLEXT 是 SAP 新总账的核心余额表,存储多维度的汇总余额数据。核心结论:该表按 “科目 + 会计年度 + 期间 + 维度” 存储累计余额,字段可分为基础标识

FAGLFLEXT是SAP新总账的核心余额表,采用"科目+年度+期间+维度"结构存储多维汇总数据。其字段分为基础标识(科目、年度等)、维度细分(公司代码、利润中心等15个维度)、金额数值(本外币余额)、辅助控制(状态标识)四大类,支持新总账的灵活核算。该表通过凭证自动更新,与旧总账GLT0相比显著扩展了维度核算能力,各维度需在科目主数据或Ledger配置中启用才能使用。

金牌架构师 454

Linux内核中内存管理相关配置项的详细解析13

Linux内核中内存管理相关配置项的详细解析14

phmatthaus的专栏 1602

YOLOv11改进策略【模型轻量化】| 替换骨干网络为 GhostNet V3 2024华为的重参数轻量化模型

一、本文介绍 本文记录的是基于 GhostNetV3 的 YOLOv11 轻量化改进方法研究。GhostNetV3的轻量模块采用重参数化方法,训练时为深度可分离卷积和1×1卷积添加线性并行分支,推理时通过逆重参数化移除分支、折叠操作,能够在不增加推理成本的同时提高性能,从而实现YOLOv11的轻量化改进。 专栏目录:YOLOv11改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进 专栏地址:YOLOv11改进专栏——以发表论文的角度,快速

Limiiiing的博客 1844

【2024-06-21】网易互娱秋招实习笔试三道编程题解

恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经。作者@TechGuide【全网同名】

试问道几许 1055

Linux mem 1.2 用户态进程空间布局 --- mmap()详解

mmap系统调用 Author: pwl Date: 2020-10-20 文章目录mmap系统调用1. 原理介绍1.1 映射1.2 vma管理1.3 mmap1.4 缺页异常1.5 layout1.6 brk2. 代码详解2.1 关键数据结构2.2 mmap()2.2.1 mm->mmap_base(mmap基地址)2.2.2 get_unmapped_area()2.2.2.1 arch_get_unmapped_area()2.2.2.2 arch_get_unmapped_area_t

pwl999的博客 4483

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

宋宝华:论Linux的页迁移(Page Migration)完整版

本文目录●●0. 为什么关心Page Migration1. CoW引起的页迁移1.1 fork1.2 KSM2. 内存规整引起的页迁移 2.1 CMA2.2 alloc_p...

宋宝华 4971

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

浪潮信息工程师:带你了解设备透传虚拟机的快速启动技术优化方案

将物理设备通过 vfio 透传给虚拟机是虚拟化常用的技术,但当为虚拟机分配比较大的内存时,虚拟机的启动时间会明显变慢,可能由十几秒延长至数分钟,严重影响用户使用体验。

数据库技术 742

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

宋宝华:为什么Linux内核常常用unsigned long来代替指针

本文目录 不知道自己不知道!指针何时指针?指针何时是整数?物理地址是指针?模糊地带绝世好代码?昨天我犯了一个错误把指针和整数“混淆”的错误,幸得队友王童鞋指正,今早起床,我把这个心...

宋宝华 4098

get_user_pages的意义

get_user_pages的意义,这个函数可以锁定用户页面,将之锁定在内存中不被换出,其实这个函数就是靠增加页面的引用计数来实现的,另外一种锁定页面的方式是调用mlock系统调用,但是后者是主动的锁定,并且在页面的基本属性上保证了不被换出,这是用户可以控制的,而前者使用引用计数的方式是用户所不能控制的,它只是有的时候内核在使用该page,由于内核使用而不能被换出,比如内核在执行aio或者bio,

yuxinghai2008的专栏 4457
上一篇: LWN: 2019年LWN年终总结!
下一篇: LWN: 直接针对cgroup创建新进程!
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值