如果使用阶数大于1的__GET_FREE_PAGES(),如何创建VM_Area映射? [英] How to create vm_area mapping if using __get_free_pages() with order greater than 1?

查看:0
本文介绍了如果使用阶数大于1的__GET_FREE_PAGES(),如何创建VM_Area映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在DMA的设备驱动程序中重新实现mmap

我看到这个问题:Linux Driver: mmap() kernel buffer to userspace without using nopage有一个答案,使用vm_insert_page()一次映射一个页面;因此,对于多个页面,需要在循环中执行。是否有其他API处理此问题?

之前,我使用dma_alloc_coherent为DMA分配内存块,并使用remap_pfn_range构建将进程的虚拟内存与物理内存相关联的页表。

现在我想使用__get_free_pages分配更大的内存块,阶数大于1。在这种情况下,我不确定如何构建页表。原因如下:

我查看了Linux设备驱动程序一书,注意到以下内容:

背景:

当用户空间进程调用mmap将设备内存映射到其地址空间时,系统会创建一个新的VMA来表示该映射。支持mmap(从而实现mmap方法)的驱动程序需要通过完成该VMA的初始化来帮助该过程。

remap_pfn_range的问题:

remap_pfn_range不允许您重新映射常规地址,其中包括通过调用get_free_page获得的地址。取而代之的是,它映射到零页面。除了进程看到的是私有的、填充为零的页面,而不是它希望看到的重新映射的RAM之外,一切似乎都正常。

序号为0的get_free_pages对应的实现,即cullp设备驱动程序中只有1页

如果分配顺序大于零,则对cullp设备禁用mmap方法,因为nopage处理单个页面,而不是页面集群。Cullp根本不知道如何正确管理属于更高级别分配的页面的引用计数。

我可以知道是否有方法为使用__get_free_pages获得的阶数大于1的页面创建VMA?

我查看了Linux源代码,注意到有一些驱动程序重新实现了struct dma_map_ops->alloc()struct dma_map_ops->map_page()。我可以知道这是不是正确的做法?

推荐答案

我想我的问题得到了答案。如果我错了,请随时纠正我。

我在谷歌搜索vm_insert_page时,碰巧看到了这个补丁:mm: Introduce new vm_map_pages() and vm_map_pages_zero() API

以前的驱动程序有自己的方法将内核页面/内存范围映射到用户vma,这是通过在循环中调用vm_ins_page()来完成的。

由于此模式在不同的驱动程序中是通用的,因此可以通过创建新函数并在所有驱动程序中使用它来进行泛化。

vm_map_ages()是可用于映射考虑了vm_pgoff的驱动程序中的内核内存/页面的API。

看过后,我知道我找到了我想要的。

该函数也可以在Linux Kernel Core API Documentation中找到。

remap_pfn_range()vm_insert_page()之间的区别是,answervm_insert_page()之间的区别是,answerquestion非常有帮助,其中包含一个指向explanation by Linus的链接。

顺便提一句,这个补丁mm: Introduce new vm_insert_range and vm_insert_range_buggy API表明vm_map_pages()的早期版本是vm_insert_range(),但我们应该坚持vm_map_pages(),因为在幕后vm_map_pages()调用vm_insert_range()

这篇关于如果使用阶数大于1的__GET_FREE_PAGES(),如何创建VM_Area映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆