Linux 为什么MMIO空间作为单个PTE映射到/dev/mem,所以没有结构页?

Linux 为什么MMIO空间作为单个PTE映射到/dev/mem,所以没有结构页?,linux,memory-management,linux-kernel,linux-device-driver,mmap,Linux,Memory Management,Linux Kernel,Linux Device Driver,Mmap,在Linux上,MMIO空间作为单个PTE进行映射(例如,通过/dev/mem调用remap\u pfn\u range()),因此没有结构页 为什么Linux不使用struct page创建大量PTE?我将尽我所能回答这个问题。我不清楚您在问什么,为什么Linux不使用struct page创建大量PTE?。但是,我想你的主要问题是,“为什么MMIO不使用struct page?”但你也提到,作为一个单独的PTE,所以没有struct page。一些澄清: 如果MMIO区域小于或等于页面大小

在Linux上,MMIO空间作为单个PTE进行映射(例如,通过/dev/mem调用
remap\u pfn\u range()
),因此没有结构页


为什么Linux不使用struct page创建大量PTE?

我将尽我所能回答这个问题。我不清楚您在问什么,
为什么Linux不使用struct page创建大量PTE?
。但是,我想你的主要问题是,“为什么MMIO不使用
struct page
?”但你也提到,
作为一个单独的PTE,所以没有struct page
。一些澄清:

  • 如果MMIO区域小于或等于页面大小,则只有一个PTE。如果MMIO区域大于一个页面,则会有多个PTE
  • 有一个
    结构页面
    ,当MMIO发生时,它只是“未使用”
根据我的理解,答案是:

物理内存中的每个页面都只有一个
struct page
。映射到内存中页面的
struct页面
永远不会更改(尽管内存中的底层数据可能会更改)。
struct页
将物理页的使用信息存储在内存中。还要注意的是,内存中的每个物理页都有一个单个
结构页。通常,对这些
struct page
的引用保存在众所周知的位置,通常是
mem\u map

另外,请记住,Linux页面表条目(PTE)还存储关于页面的使用信息。对于给定页面,Linux PTE大致与任何硬件内存管理单元的“PTE”保持同步

如果物理内存地址映射到设备(即MMIO),则设备内存没有
结构页
s。这些物理地址处的物理内存的
struct页仍然存在,但它们的使用方式与正常情况不同,因为该物理内存现在未使用(但物理地址用于指向不再在物理内存中,而是在设备内存中的内存)

请记住,在已知位置的物理内存中,每个页面都有一个
struct page
:一个名为
mem\u map
的预分配数组


因此,PTE足以跟踪设备内存的状态。
struct页面
结构专门用于系统物理内存中的内存。但页表条目可用于跟踪任何内存的状态,而不仅仅是物理内存。

缩写更少(我知道“内存映射I/O”和“页表条目”,但这会使问题难以理解)。什么是“结构页面”一点也不清楚。你的意思是没有包含结构的内存页吗?或者没有名为
page
struct
类型?或者没有表示内存页的结构?或者有一个
struct page
类型,但它不用于MMIO?@Ben Voigt“没有struct page”-我的意思是,内存的每一页都没有PTE(页表条目),但/dev/mem只有一个PTE。非常感谢!也就是说,对于
/dev/mem
(MMIO),没有任何
结构页面,并且有许多PTE,不是吗?但是我如何为
/dev/mem
MMIO创建
结构页面
呢?我不确定我是否理解你的意思,但
/dev/mem
不是MMIO
/dev/mem
提供对整个物理地址空间的访问。这意味着系统中所有物理内存的
struct page
s已经存在。设备内存(MMIO)没有任何
结构页。您只需使用物理内存*地址直接访问设备内存,但不需要使用
ioremap
vm\u insert\u page
来创建
struct page
s
ioremap
仅将设备I/O映射到虚拟内存<代码>虚拟机插入页面
用于已创建的结构页面
。是否有理由要为设备I/O内存创建
struct page
s?nVidia的开发人员说:“
cudaHostRegister(virt_ptr,size,0)
不准备在没有相应结构页的情况下处理虚拟地址”。我无法将设备内存映射到虚拟用户空间内存,然后将其重新映射到GPU内存(UVA),以便从GPU使用它。解决这个问题的一个变种是:“问题似乎源自英伟达驱动程序和它所期望的虚拟内存区域上出现的标志和/或结构关联,它被传递到<代码> CUAdHuthStave。但是,驱动程序是作为二进制块而没有可用的源代码……”"... 为了克服这个问题,修改了netmap内核模块,更具体地说是实现
mmap(3)
功能的代码。该补丁只需更改用于将分配的页面导出到用户空间的例程。显然,这里的问题是使用
remap\u pfn\u range
,它生成原始pfn(页面帧号)映射,并且页面没有与之关联的结构页面。而是对每个页面使用
vm\u insert\u page
。”