【发布时间】:2011-03-30 09:40:59
【问题描述】:
谁能说出直到 Linux Kernel 2.4 之前使用的 struct buffer_head 结构效率低下的原因,以及在内核 2.5.1 重新设计的新块层中使用的 struct bio 结构中实现了什么?
【问题讨论】:
标签: linux operating-system kernel block
谁能说出直到 Linux Kernel 2.4 之前使用的 struct buffer_head 结构效率低下的原因,以及在内核 2.5.1 重新设计的新块层中使用的 struct bio 结构中实现了什么?
【问题讨论】:
标签: linux operating-system kernel block
在 2.5 之前的内核中,buffer_head 曾经是 IO 的 单元。但是,根据 buffer_head 执行 IO 可能效率低下。例如,跨越多个块的单个写入将导致创建多个 buffer_head 对象,从而浪费空间和时间。因此,buffer_head 结构最适合用于提供块到物理内存的映射,这正是它在 2.5 中所做的事情(也是它所做的唯一事情)从内核开始。
另一方面,struct bio 被设计为以后内核版本中的 IO 单元。 **它代表当前在内核.** 请注意,块到内存的映射仍保留在 buffer_head 中。但是,buffer_head 现在没有被包含有关当前活动 IO 信息的字段重载。因此,当文件系统等更高级别的代码发出 IO 时,会将请求添加到 request_queue。该请求又包含一个指向 bio 结构的指针。控制发出 IO 的设备的设备驱动程序接收请求并提供服务。
struct bio 结构也用于分割 IO,例如 RAID 磁盘设备驱动程序。查看 struct bio 定义,您会发现它维护了一个 io_vectors 数组(它们只是内存页的偏移量)。此外,bi_idx 用于索引这些 io_vec。通过为不同的磁盘使用不同的 bi_idx 值,每个磁盘将选择一组不同的 io_vec 来写入(或读取),因此 IO 将以真正的并行方式完成。
【讨论】:
使用源代码,卢克!
来自include/linux/buffer_head.h:
/*
* Historically, a buffer_head was used to map a single block
* within a page, and of course as the unit of I/O through the
* filesystem and block layers. Nowadays the basic I/O unit
* is the bio, and buffer_heads are used for extracting block
* mappings (via a get_block_t call), for tracking state within
* a page (via a page_mapping) and for wrapping bio submission
* for backward compatibility reasons (e.g. submit_bh).
*/
struct buffer_head {
[ ... ]
来自linux/include/bio.h:
/*
* main unit of I/O for the block layer and lower layers (ie drivers and
* stacking drivers)
*/
struct bio {
[ ... ]
“高级”(通过文件系统的 I/O)和“低级”(通过块开发的 I/O)的两个分离 I/O 特征和操作。这允许更高的性能,因为在某处等待的缓冲层不会阻止块层在其他地方执行工作。关于它的一些解释可以在here 找到,Jens Axboe 简单地谈论它in this interview。
【讨论】:
Robert Love 的 LKD 3rd 对此有非常详细的解释。
旧与新
缓冲头和新的区别 bio 结构很重要。bio 结构代表一个 I/O 操作,它可能包括内存中的一个或多个页面。在另一 手,buffer_head结构代表一个单独的缓冲区,它 描述磁盘上的单个块。因为缓冲头被绑定到 单个页面中的单个磁盘块,缓冲区头导致 将请求不必要地划分为块大小的块,只是为了 稍后重新组装它们。由于生物结构重量轻,它 可以描述不连续的块并且不会不必要地拆分 I/O 操作。从 struct buffer_head 切换到 struct bio 提供 还有其他好处:
bio结构可以很容易的表示高内存,因为struct bio 只处理物理页而不处理直接指针。
bio 结构既可以表示普通页面 I/O,也可以表示直接 I/O(I/O 不通过页面缓存的操作——参见第 16 章,“ 页面缓存和页面写回”,用于讨论页面缓存)。
生物结构使得执行分散收集(矢量化)变得容易 块 I/O 操作,以及操作中涉及的数据 源自多个物理页面。
- 生物结构多 比缓冲头更轻量,因为它只包含 表示块 I/O 操作所需的最少信息,而不是 与缓冲区本身相关的不必要信息。
【讨论】: