tags:

views:

41

answers:

1

am trying to move data from a buffer in kernel space into the hard disk without having to incur any additional copies from kernel buffer to user buffers or any other kernel buffers. Any ideas/suggestions would be most helpful.

The use case is basically a demux driver which collects data into a demux buffer in kernel space and this buffer has to be emptied periodically by copying the contents into a FUSE-based partition on the disk. As the buffer gets full, a user process is signalled which then determines the sector numbers on the disk the contents need to be copied to.

I was hoping to mmap the above demux kernel buffer into user address space and issue a write system call to the raw partition device. But from what I can see, the this data is being cached by the kernel on its way to the Hard Disk driver. And so I am assuming that involves additional copies by the linux kernel.

At this point I am wondering if there is any other mechansim to do this without involving additional copies by the kernel. I realize this is an unsual usage scenario for non-embedded environments, but I would appreciate any feedback on possible options.

BTW - I have tried using O_DIRECT when opening the raw partition, but the subsequent write call fails if the buffer being passed is the mmapped buffer.

Thanx!

+2  A: 

You need to expose your demux buffer as a file descriptor (presumably, if you're using mmap() then you're already doing this - great!).

On the kernel side, you then need to implement the splice_read member of struct file_operations.

On the userspace side, create a pipe(), then use splice() twice - once to move the data from the demux file descriptor into the pipe, and a second time to move the data from the pipe to the disk file. Use the SPLICE_F_MOVE flag.

As documented in the splice() man page, it will avoid actual copies where it can, by copying references to pages of kernel memory rather than the pages themselves.

caf
SPLICE_F_MOVE is no op in latest kernel code.. 2.6.31 onwards. So, I am not sure if splice implementation actually tries for zero-copy transfer. Can you please confirm?
I tried to do some hands on testing but could not find any sample implementation of splice_read() and splice_write() in device drivers. Seems like no one has started using splice() yet. Do you have any references for splice_read()?