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.csdn.net/iteye_5014/article/details/81824739 3,Linux Kernel get_user_pages() 源码分析 https://v1ckydxp.github.

yiyeguzhou100的专栏 3407

rdma 虚拟地址物理地址转换

RDMA的虚实地址转换

baidu_38316985的博客 1568

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

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

weixin_49199313的博客 110

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的博客 5437

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的驱动与虚拟化技术分享园地 627

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

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

zhaoxin1989的博客 1万+

Linux 内存 --- get_user_pages/pin_user_pages函数

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

小立仔 1593

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

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

weixin_42730667的博客 6725

Linux的页迁移(Page Migration)

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

lx123010的专栏 2104

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

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的博客 132

获取内存内容的几种方法

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

zhaoxin1989的博客 4301

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

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

weixin_45337360的博客 4646

基于奥比中光Orbbec Astra Pro与ROS实现实时3D环境建模:orb_slam2实战指南

本文提供了一份详细的实战指南,介绍如何使用奥比中光Orbbec Astra Pro深度摄像头与ROS系统,部署并运行ORB-SLAM2算法,实现实时3D环境建模与定位。内容涵盖从驱动安装、环境配置、算法编译到摄像头标定与性能调优的全流程,旨在帮助开发者快速搭建一套高性价比的视觉SLAM系统。

weixin_29054399的博客 308

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

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

phmatthaus的专栏 1594

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的博客 4460

redhawk-sc(seascape)学习日志2

design view是主view,是所有seascape view中最root的部分,一个design view可以驱动多种类型分析比如静态IR drop,动态IR drop以及EM.这些分析可以在不同的PVT和翻转率下.Design view是一个必须的view对于redhawk中的任何类型分析来说。seascape view相当于一个容器,用于保存各种和设计相关的数据,类似于逻辑信息、物理信息等等,每个view都有其对应的输入件和依赖,这些view都是redhawk用于各种类型的分析所需。

qq_39493558的博客 3437

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

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

宋宝华 4945

别再手动拷贝文件了!用Keil MDK的Pack Installer一键搞定STM32上的RT-Thread Nano移植

本文详细介绍了如何使用Keil MDK的Pack Installer一键快速移植RT-Thread Nano到STM32项目,告别繁琐的手动拷贝和配置过程。通过自动化版本管理和依赖处理,移植时间从47分钟缩短至3分钟,大幅提升开发效率。文章还提供了实战步骤、高级配置技巧和常见问题解决方案,帮助开发者轻松实现RTOS集成。

weixin_29194817的博客 354

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

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

数据库技术 740

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

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

宋宝华 4093

山东大学FPGA课程实验一 加法器设计

电子设计自动化与FPGA设计,实验一 加法器设计

2503_91283667的博客 852

get_user_pages的意义

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

yuxinghai2008的专栏 4456

【Python实战解析】从数据爬取到房价预测:一个完整的数据科学项目流程拆解

本文详细拆解了一个完整的Python数据科学项目流程,从爬取长沙二手房数据到房价预测模型构建。通过实战案例,介绍了数据爬取、清洗、可视化及模型优化的关键技巧,帮助开发者掌握Python在数据分析中的应用,提升程序开发能力。

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值