我正在尝试从I/O内存(HIGHMEM)写入一些数据到HDD上。我已经使用io_remap_pfn_range()映射了内存缓冲区。我的应用程序使用O_DIRECT进行磁盘读/写操作。使用O_DIRECT时,写操作返回EFAULT(错误的地址)。我追踪到了mm/memory.c中的__get_user_pages函数,其中拒绝了IO页面。这就是我目前所了解的内核深度。我不明白为什么不允许IO指针。我们的项目需要超快速的磁盘IO,因此任何复制都不是一个选项。感谢您提供任何提示。谢谢!
VM_PFNMAP
标志 (http://elixir.free-electrons.com/linux/v4.11.7/source/include/linux/mm.h#L174)。当您使用io_remap_pfn_range
时,它设置了VM_PFNMAP
标志(http://elixir.free-electrons.com/linux/v4.11.7/source/mm/memory.c#L1914),表明“这些页面不是具有常规struct page的普通页面”(请参见上面代码中的注释)。而__get_user_pages
检查这个标志并返回错误(http://elixir.free-electrons.com/linux/v4.11.7/source/mm/nommu.c#L136)。
P.S. io_remap_pfn_range
和__get_user_pages
中也有VM_IO
标志,因此内核页面映射到用户空间时不会有任何I/O,否则将重写内核内存。