Io 从mmapped缓冲区写入'O_DIRECT'输出文件

Io 从mmapped缓冲区写入'O_DIRECT'输出文件,io,linux-kernel,mmap,Io,Linux Kernel,Mmap,我有一个可以写入视频缓冲区的设备。这个缓冲区是使用CMA在系统内存中分配的,我想实现从这个缓冲区到块设备的流式写入。我的应用程序使用mmap打开视频缓冲区,我希望使用O_DIRECTwrite来避免与页面缓存相关的开销。基本上,应用程序的伪代码如下所示: f_in = open("/dev/videobuf", O_RDONLY); f_mmap = mmap(0, BUFFER_SIZE, PROT_READ, MAP_SHARED, f_in, 0); f_out = open("/dev/

我有一个可以写入视频缓冲区的设备。这个缓冲区是使用CMA在系统内存中分配的,我想实现从这个缓冲区到块设备的流式写入。我的应用程序使用mmap打开视频缓冲区,我希望使用
O_DIRECT
write来避免与页面缓存相关的开销。基本上,应用程序的伪代码如下所示:

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);
其中块大小为扇区对齐值。f_out打开时没有任何错误,但写入结果为
EFAULT
。我试图追踪这个问题,结果发现视频缓冲区驱动程序中的mmap实现使用了
remap_pfn_range()
,它为VMA设置
VM_IO
VM_PFNMAP
标志。块设备驱动程序中的
O_DIRECT
路径检查这些标志并返回
EFAULT
。据我所知,
O_DIRECT
写入需要固定内存页,但VMA标志表示底层内存缺少导致错误的
struct page
。我就在这里吗

主要的问题是如何正确地实现从mmapped缓冲区写入的
O_DIRECT
?我有视频缓冲驱动程序,可以适当地修改它


我找到了,但没有明确的答案。

在修改视频缓冲区驱动程序之前,我首先要看看是否有效:
off\u t offset=0L;ssize_t byteSent=sendfile(f_out、f_in和offset、BLOCK_SIZE)
,假设视频缓冲区驱动程序不支持
lseek()
或其他跟踪文件偏移量。(或
ssize\u t byteSent=sendfile(f\u out,f\u in,NULL,BLOCK\u SIZE);
)如果它能工作,就可以避免
mmap()
和完全锁定用户空间页的需要。@AndrewHenle我测试了
sendfile()
,在我的情况下它不起作用。如果
f_in
是一个常规文件,但如果
f_in
是一个视频缓冲区,则此函数将返回
EINVAL
。在修改视频缓冲区驱动程序之前,我首先要看看是否有效:
off\u t offset=0L;ssize_t byteSent=sendfile(f_out、f_in和offset、BLOCK_SIZE)
,假设视频缓冲区驱动程序不支持
lseek()
或其他跟踪文件偏移量。(或
ssize\u t byteSent=sendfile(f\u out,f\u in,NULL,BLOCK\u SIZE);
)如果它能工作,就可以避免
mmap()
和完全锁定用户空间页的需要。@AndrewHenle我测试了
sendfile()
,在我的情况下它不起作用。如果
f_-in
是一个常规文件,则其工作原理与预期不同,但如果
f_-in
是一个视频缓冲区,则此函数将返回
EINVAL