LWN:对user-space pages进行明确的pin操作!-程序员宅基地

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

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深度文章以及开源社区的各种新近言论~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Linux_Everything/article/details/103884537

智能推荐

易学编程网之游戏过保护+游戏过检测_编写外挂时过保护是什么意思-程序员宅基地

文章浏览阅读1.3k次。驱动编程01-开发环境的简单介绍驱动编程02-C语言语法介绍驱动编程03-运算符 表达式 语句 循环驱动编程04-分支和跳转驱动编程05-进制01驱动编程06-进制的运算驱动编程07-数组和指针驱动编程08-数组和指针驱动编程09-数组和指针驱动编程10-结构体驱动编程11-结构体驱动编程12-指针驱动编程13-指针驱动编程14-指针驱动编程15-指针驱动编程16C+..._编写外挂时过保护是什么意思

Dimensinality reduction and topic modeling_topic modeling, dimensionality reduction-程序员宅基地

文章浏览阅读129次。Dimensinality reduction and topic modeling0 AbstractBOW not effective facing synonym and polysemy.Dimension reduction can solve this, represent a document in lower-dimension, and reflect concepts.Two froms of dimension reduction:latent semantic index_topic modeling, dimensionality reduction

nn.AdaptiveAvgPool1d()-程序员宅基地

文章浏览阅读175次。官网地址: https://pytorch.org/docs/stable/generated/torch.nn.AdaptiveAvgPool1d.html#torch.nn.AdaptiveAvgPool1d。

movewindow窗口闪烁_onmousemove闪烁-程序员宅基地

文章浏览阅读1.6k次,点赞13次,收藏6次。场景: 一个视频播放窗口,需要功能是可移动,可拉动改变大小 结果在快速移动时,有些电脑出现了花屏, why? 在onmousemove响应移动加拉动消息 大多数电脑是正常的,偶尔少数电脑出现了这情况, 最后我的结论是:onmousemove进入的消息太多,差的电脑处理不过来,_onmousemove闪烁

(附源码)计算机毕业设计springboot自习室预订系统_3fy99_自习室预订代码-程序员宅基地

文章浏览阅读160次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_自习室预订代码

Android项目-闪屏界面与GridView_android gridview初始化引起的闪烁-程序员宅基地

文章浏览阅读865次。Android项目-闪屏界面与GridView闪屏界面一般闪屏界面是应用的第一个界面。应用在闪屏界面做的主要工作一般有:展示logo(应用logo、公司logo)项目初始化检测版本更新校验程序的合法性(比如是否有网络) 闪屏界面显示的内容一般都是一张背景图片。我们将图片作为布局的背景即可 闪屏页面一般至少要显示一段时间Point1 (去除标题)一般应用,是没有标题的,有的话太难看了_android gridview初始化引起的闪烁

随便推点

编译安装nginx-1.12.2.tar.gz-程序员宅基地

文章浏览阅读1.3k次,点赞2次,收藏2次。编译安装nginx 前提配置好yum文件 测试环境使用centos-1511版本nginx-1.12.2.tar.gz 使用的软件包http://nginx.org/download/nginx-1.12.2.tar.gz安装初始化的环境[root@nginx ~]# yum install -y gcc gcc-c++ openssl-devel zlib-devel zlib pcre-devel 创建用户:[root@nginx ~]# groupadd -g 1001 n_nginx-1.12.2.tar.gz

使用MIUI远程管理时打开电脑文件出现“ftp无法访问此文件夹,请确保输入的文件名是正确”_小米远程管理ftp文件夹错误-程序员宅基地

文章浏览阅读1.3w次,点赞7次,收藏11次。打开MIUI进行远程管理时首先出现了ftp不允许匿名访问,这时需要在窗口上登录你的小米账户和密码。完成后在电脑带成功进入手机的文件管理界面,但想要打开一个文件夹时出现了“ftp无法访问此文件夹,请确保输入的文件名是正确”这时就需要打开控制面板,找到:程序和功能–>启动或关闭windows功能,点进去,勾选TFTP客户端,和网络信息服务的FTP服务,确定。就此就可以使用MIUI的远程管理功能,甚至可以修改文件,和电脑的文件共享功能一样。..._小米远程管理ftp文件夹错误

PHP cURL库函数抓取页面内容_curl查看网页内容-程序员宅基地

文章浏览阅读1.1w次,点赞2次,收藏12次。cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议和选项,如HTTP、FTP、TELNET等,能提供 URL 请求相关的各种细节信息。最爽的是,PHP 也支持 cURL 库。本文将介绍 cURL 的一些高级特性,以及在 PHP 中如何运用它。1 为什么要用cURL?是的,我们可以通过其他办法获取网页内容。大多数时候,我因为想偷懒,都直接用简单的 PH_curl查看网页内容

windows11下使用VisualStudio2019编译glog方法_glog window-程序员宅基地

文章浏览阅读182次。5.打开VS2019的命令行工具"Developer Command Prompt for VS 2019",然后cd切换到第3步的build文件夹。7.打开生成的glog.sln工程,菜单栏依次"生成"->“批生成”,然后在"批生成"窗口,先点击"全选",然后点击"重新生成"即可。1.去https://github.com/google/glog下载最新的release版本glog-0.6.0.zip。3.在解压后的glog-0.6.0目录,创建build文件。,以生成VS2019的sln工程。_glog window

sql 查询判断字符串包含中文_sql查询判断-程序员宅基地

文章浏览阅读1.5w次。SELECT * FROM [dbname].[dbo].[db_tbl] WHERE NAME LIKE '%[吖-座]%'_sql查询判断

c++标准库windows.h文件_windows.h下载-程序员宅基地

文章浏览阅读6.1k次,点赞2次,收藏14次。#include <winapifamily.h>/*++ BUILD Version: 0001 Increment this if a change has global effectsCopyright (c) Microsoft Corporation. All rights reserved.Module Name: windows.hAbs..._windows.h下载

推荐文章

热门文章

相关标签