我是linux内核的新手。最近,我通过了内核 2.6.33 中的 sendfile 系统调用。以下是我的旅程顺序:
do_sendfile()
=> do_splice_direct()
=> splice_direct_to_actor()
=> do_splice_to()
=> do_splice_from()
=> splice_read,splice_write
在整个序列中,我没有找到 splice 使用 DMA 副本的地方。那么 DMA 复制发生在哪里?
我是linux内核的新手。最近,我通过了内核 2.6.33 中的 sendfile 系统调用。以下是我的旅程顺序:
do_sendfile()
=> do_splice_direct()
=> splice_direct_to_actor()
=> do_splice_to()
=> do_splice_from()
=> splice_read,splice_write
在整个序列中,我没有找到 splice 使用 DMA 副本的地方。那么 DMA 复制发生在哪里?
Splice 不进行任何 DMA 复制。事实上 splice 的主要用途是完全避免复制 - 它尝试将引用传递给内存页面而不是复制缓冲区。
提到的与拼接相关的 DMA 将发生在“叶子”——拼接传递引用的这些页面的来源将由例如磁盘控制器 DMA 创建到缓冲区中,并将由以太网控制器 DMA 发送将页面内容作为数据包的一部分 - 至少在“完美”的零复制场景中,这很难实现且很少见。
Splice 不执行 DMA - 它无法在第一个 DMA 到最后一个 DMA 之间进行复制。
据我了解, splice_* 基础架构最好将实际复制的数量降至最低。充其量,读者正在阅读作者正在填写的同一组页面。
有一些关于 LWN 的优秀文章描述了 splice() 的各个位,包括新的系统调用。