struct iov_iter的作用是什么?此结构在Linux内核中使用,而不是struct iovec。iter接口没有任何好的文档。我找到了一份关于LWN的文件,但我无法理解。有没有人可以帮助我理解Linux内核中使用的iter接口?
rn0zuynd1#
iovec的一个用途,LWN article预先声明,是处理多个块中的数据。如果你有许多离散的缓冲区,用指针链接,并且想一次性读/写它们,你可以用几个读/写操作来完成。然而,在某些情况下,语义与读/写边界相关联,因此在不改变操作语义的情况下,操作不能被拆分(一个简单的假设示例:涉及多于1次写入的原子操作)。另一种方法是将所有数据复制到一个连续的缓冲区中或从其中复制出来,但是这是浪费的,您可能希望避免这种情况。使用POSIX readv/writev,或者在本例中使用iov_iter API,可以减少系统调用的数量,从而降低开销。虽然仅在内核代码的上下文中,这不会转化为像上下文切换这样昂贵的操作,但它仍然是一个问题。当驱动程序无法知道在不久的将来是否会有更多的数据时,驱动程序也可能比处理大量较小的数据块更有效地处理大块的数据-这对于网络驱动程序来说尤其如此,但是现在iovec/iov_iter/* API无处不在,因为_copy_to_iter/_copy_from_iter用于实现数据包处理代码的核心功能,例如,skb_copy_datagram_from_iter。相同情况的另一个示例是对原始磁盘设备的I/O,它只允许对块边界的开始和结束进行I/O。用户可能偶尔想要执行随机访问或覆盖缓冲区的一小部分,比如说,在块的开始和/或将其余部分归零。这样的场景正是iovec的目标所在;你可以构造一个iovec,它使你能够在几个离散的缓冲区上进行整个块的操作,其中甚至可能包括一个“临时”缓冲区,用于转储你读取的块中不关心处理的部分,以及一个预置零缓冲区,用于在writev的末尾进行链接,以将块的其余部分置零。我再次指出,您可以使用具有相关复制和/或清零功能的连续缓冲区,但iov_iter API提供了一种替代抽象,它涉及的开销更少,并且可以说在阅读代码时更容易推理。在向量处理或并行计算中,这些操作的术语是“* 分散/聚集处理 *”。
iovec
readv
writev
iov_iter
_copy_to_iter
_copy_from_iter
skb_copy_datagram_from_iter
1条答案
按热度按时间rn0zuynd1#
iovec
的一个用途,LWN article预先声明,是处理多个块中的数据。如果你有许多离散的缓冲区,用指针链接,并且想一次性读/写它们,你可以用几个读/写操作来完成。然而,在某些情况下,语义与读/写边界相关联,因此在不改变操作语义的情况下,操作不能被拆分(一个简单的假设示例:涉及多于1次写入的原子操作)。另一种方法是将所有数据复制到一个连续的缓冲区中或从其中复制出来,但是这是浪费的,您可能希望避免这种情况。
使用POSIX
readv
/writev
,或者在本例中使用iov_iter
API,可以减少系统调用的数量,从而降低开销。虽然仅在内核代码的上下文中,这不会转化为像上下文切换这样昂贵的操作,但它仍然是一个问题。当驱动程序无法知道在不久的将来是否会有更多的数据时,驱动程序也可能比处理大量较小的数据块更有效地处理大块的数据-这对于网络驱动程序来说尤其如此,但是现在iovec
/iov_iter
/* API无处不在,因为_copy_to_iter
/_copy_from_iter
用于实现数据包处理代码的核心功能,例如,skb_copy_datagram_from_iter
。相同情况的另一个示例是对原始磁盘设备的I/O,它只允许对块边界的开始和结束进行I/O。用户可能偶尔想要执行随机访问或覆盖缓冲区的一小部分,比如说,在块的开始和/或将其余部分归零。这样的场景正是
iovec
的目标所在;你可以构造一个iovec
,它使你能够在几个离散的缓冲区上进行整个块的操作,其中甚至可能包括一个“临时”缓冲区,用于转储你读取的块中不关心处理的部分,以及一个预置零缓冲区,用于在writev
的末尾进行链接,以将块的其余部分置零。我再次指出,您可以使用具有相关复制和/或清零功能的连续缓冲区,但iov_iter
API提供了一种替代抽象,它涉及的开销更少,并且可以说在阅读代码时更容易推理。在向量处理或并行计算中,这些操作的术语是“* 分散/聚集处理 *”。