可能重复:
mmap()与读取块
我听说(在互联网上读取它)mmap()
比顺序IO更快.它是否正确?如果是,那为什么它更快?
mmap()
不按顺序阅读.mmap()
具有从盘面本身一样去取read()
呢那么mmap()
实际上应该比read()
文件慢吗?我上面的哪些假设是错误的?
我正在为IA64开发Linux模块.我目前的问题是驱动程序使用PAGE_SIZE和PAGE_SHIFT宏进行dma页面分配.我遇到的问题是编译驱动程序的机器不是需要运行驱动程序的机器.因此,如果编译机器上的PAGE_SIZE为2 ^ 14K且目标机器为2 ^ 16K,则驱动程序将失败.
我不想把这个问题变成关于在不运行模块的机器上编译模块的"最佳实践"问题.我理解这个问题.我发现人们大多使用getpagesize()或sysconf(_SC_PAGE_SIZE).这两个选项不在ia64内核头文件中,因此我无法使用它们.还有另一种方法可以获得运行时PAGE_SIZE吗?
我正在看的选项:
我希望尽快将支持DMA的PCIe硬件设备中的数据导入用户空间.
问:如何将"使用/和/通过DMA传输直接I/O连接到用户空间"
通过LDD3读取,似乎我需要执行一些不同类型的IO操作!?
dma_alloc_coherent
给我一个可以传递给硬件设备的物理地址.但是在传输完成时需要设置get_user_pages
并执行copy_to_user
类型调用.这似乎是浪费,要求设备DMA进入内核内存(充当缓冲区),然后再将其传输到用户空间.LDD3 p453:/* Only now is it safe to access the buffer, copy to user, etc. */
我理想的是一些记忆:
我是否需要单页流映射,设置映射和用户空间缓冲区映射get_user_pages
dma_map_page
?
到目前为止,我的代码get_user_pages
在用户空间的给定地址设置(我称之为直接I/O部分).然后,dma_map_page
用一个页面get_user_pages
.我将设备的返回值dma_map_page
作为DMA物理传输地址.
我使用一些内核模块作为参考:drivers_scsi_st.c
和drivers-net-sh_eth.c
.我会看看infiniband代码,但无法找到哪一个是最基本的!
提前谢谢了.
我的问题是:当我[pci_]dma_sync_single_for_{cpu,device}
在设备驱动程序中正确使用时,如何确定何时可以安全地禁用缓存侦听?
我正在研究一种设备驱动程序,它通过PCI Express(DMA)直接写入RAM,并且担心管理缓存一致性.在DMA启动DMA以启用或禁用缓存侦听时,我可以设置一个控制位,显然对于性能我希望尽可能禁用缓存侦听.
在中断例程中,我调用pci_dma_sync_single_for_cpu()
并..._for_device()
在适当时切换DMA缓冲区,但在32位Linux 2.6.18(RHEL 5)上,事实证明这些命令是宏,它们扩展为空...这解释了为什么我的设备返回垃圾在此内核上禁用缓存侦听时!
我已经浏览了内核源代码的历史,似乎直到2.6.25只有64位x86才有DMA同步的钩子.从2.6.26似乎是DMA同步(目前通用的统一间接机制include/asm-generic/dma-mapping-common.h
通过字段)sync_single_for_{cpu,device}
的dma_map_ops
,但到目前为止,我一直没能找到这些操作的任何定义.
我对缓存同步操作有一些疑问.
无效:在cpu尝试读取设备更新的部分内存之前,需要使相应的内存无效.
刷新:在设备读取CPU更新的部分内存之前,CPU必须刷新(写回也是正确的?)从缓存到内存的内容,以便设备从内存中读取更新内容的内容.
如果不执行刷新,则它可以读取存储器中存在的垃圾数据,因为存储器仍未使用写入高速缓存的内容进行更新.
请确认我的上述理解是否正确?
您想什么时候将flush和invalidate结合起来?我听说在使用设备控制描述符时,我们需要通过组合flush和invalidate进行同步.为什么这样?
我们是否需要遵循像flush这样的序列然后无效?
是否有一个场景,其中有效的后续执行无效?
此调用返回的DMA地址是否与物理地址相同?LDD3表示驱动程序应将DMA地址视为不透明.我想mmap这个DMA缓冲区,以便用户空间可以直接读/写它.问题是我应该为remap_pfn_range指定PFN(现在令我惊喜的是(内核3.4+)适用于传统内存,与I/O内存相同).我可以将DMA地址转换为无符号长并将其转换为PFN吗?这不违反LDD3关于不透明性的说法吗?
是否dma_alloc_coherent
总是使用__get_free_pages
内部?这是否意味着该区域可能总是过度分配(因为第一个函数占用字节而第二个函数以页为单位分配)?
有没有办法为从调用中获得的多个连续页面设置单个流映射__get_free_pages
?dma_map_page
仅适用于单个页面.
我试图了解PCI Express如何工作,所以我可以编写一个Windows驱动程序,可以读取和写入没有板载内存的自定义PCI Express设备.
据我所知,PCIE配置空间中的基地址寄存器(BAR)保存了PCI Express应响应/允许写入的存储器地址.(这是正确的理解吗?)
我的问题如下:
我很感激你的时间.
最好的祝福,
我读到如果DMA可用,那么处理器可以将磁盘块的长读或写请求路由到DMA并专注于其他工作.但是,在此传输过程中,DMA到内存数据/控制通道正忙.处理器在此期间还能做些什么?
假设CPU想要从PCI Express设备进行DMA读传输.与PCI Express设备的通信由事务层分组(TLP)提供.从理论上讲,TLP的最大有效载荷大小为1024双字.那么,当CPU向4兆字节大小的PCI Express设备发出DMA读取命令时,DMA控制器如何动作?
我的一个朋友告诉我,在x86架构上,DMA控制器无法在两个不同的RAM位置之间进行传输.它只能在RAM和外设之间传输(如PCI总线).
这是真的?
因为AFAIK DMA控制器应该能够位于BUS上并具有地址的任意设备之间.特别是如果源和destionation地址属于同一物理设备,我认为没有问题.