我有一个写入视频缓冲区的设备。使用CMA在系统内存中分配此缓冲区,我想实现从此缓冲区到块设备的流写入。我的应用程序使用mmap打开视频缓冲区,我想使用O_DIRECT
写入来避免与页面缓存相关的开销。基本上,应用程序的伪代码如下所示:
f_in = open("/dev/videobuf", O_RDONLY);
f_mmap = mmap(0, BUFFER_SIZE, PROT_READ, MAP_SHARED, f_in, 0);
f_out = open("/dev/sda", O_WRONLY | O_DIRECT);
write(f_out, f_mmap, BLOCK_SIZE);
其中BLOCK_SIZE是扇区对齐值。打开f_out时没有任何错误,但在EFAULT
中写入结果。我试图追踪这个问题,结果发现视频缓冲区驱动程序中的mmap实现使用了remap_pfn_range()
,它为VMA设置了VM_IO
和VM_PFNMAP
标志。块设备驱动程序中的O_DIRECT
路径检查这些标志并返回EFAULT
。据我所知,O_DIRECT
写入需要固定内存页面,但VMA标志表示缺少struct page
底层内存会导致错误。我在这儿吗?
主要问题是如何从mmapped缓冲区正确实现O_DIRECT
写入?我有视频缓冲驱动程序,可以适当修改它。
我找到了similar question,但这些都没有明确答案。