2011-09-28 77 views
3

我是Linux内核的新手。最近,我已经通过了内核2.6.33中的sendfile syscall。以下是我的旅程序列:DMA复制在拼接()

do_sendfile() 
=> do_splice_direct() 
=> splice_direct_to_actor() 
=> do_splice_to() 
=> do_splice_from() 
=> splice_read,splice_write 

在整个序列中,我没有找到拼接使用DMA副本的地方。那么DMA复制发生在哪里?

回答

4

接合不做任何DMA副本。事实上,拼接的主要用途是避免复制 - 它试图将引用传递给内存页面,而不是复制缓冲区。

关于拼接提到的DMA将发生在“叶”处 - 这些拼接所经过的引用的起源将由例如磁盘控制器DMA创建到缓冲区中,并将由一个以太网控制器DMA的页面内容作为数据包的一部分 - 至少在一个“完美的”零拷贝的情况下,这是很难实现和罕见的。

Splice不执行DMA - 它不允许在第一个DMA和最后一个DMA之间进行复制。

+1

嗨,感谢您的回答,这真的很有帮助。所以如果我正确地理解你说的话,拼接的顺序将是:从磁盘驱动器复制到fd_in缓冲区; fd_in缓冲区通过管道将页面引用传递给fd_out缓冲区;通过查看fd_out缓冲区中的引用,以太网卡直接进入fd_in缓冲区以查看实际数据。 – sliter

+0

@sliter是的,这是主意。 – gby

1

据我所知splice_ *基础设施是最好的,以尽量减少实际复制的数量。读者最多只能从作者正在填写的同一组页面中阅读。

在LWN上有一些优秀的文章描述了splice()的各个位,包括新的系统调用。

+0

嗨stsquad,谢谢你的回答。我会在那里看一看。 – sliter