在块层/设备

时间:2015-06-02 00:39:36

标签: linux linux-kernel filesystems linux-device-driver

我们正在开发一种ssd类型的存储硬件设备,它可以同时接收大块大小> 4KB的读/写请求(即使是MB大小)。 我的理解是linux及其文件系统会将文件“砍掉”成4KB的块大小,这些块大小将被传递给块设备驱动程序,这需要用来从设备中物理填充块(例如,用于写入)

我也知道内核页面大小在此限制中起作用,因为它设置为4KB。

对于实验,我想知道是否有办法实际增加这个块大小,这样我们就可以节省一些时间(而不是进行多次4KB写入,我们可以用更大的块大小来实现)。

我可以查看任何FS或任何现有项目吗? 如果没有,那么做这个实验需要什么 - 需要修改linux的哪些部分? 试图找出所需的困难和资源水平。或者,如果甚至不可能这样做和/或任何理由我们甚至不需要这样做。任何评论都表示赞赏。

感谢。

2 个答案:

答案 0 :(得分:2)

4k限制是由于页面缓存造成的。主要问题是,如果你有一个4k的页面大小,但块大小为32k,如果文件长度只有2000字节会发生什么,所以你只分配一个4k的页面来覆盖块的前4k。现在有人试图抵消20000,并写一个字节。现在假设系统承受了很大的内存压力,而前一个2000字节的4k页面是干净的,会被推出内存。如何跟踪32k块的哪些部分包含有效数据,以及当系统需要在偏移20000处写出脏页时会发生什么?

另外,我们假设系统存在巨大的内存压力,我们需要写出最后一页;如果没有足够的内存可用于实例化32k块中的其他28k,那么我们可以执行读 - 修改 - 写周期只是为了更新那个脏的4k页偏移20000?

这些问题都可以解决,但需要在VM层进行大量手术。 VM层需要知道对于这个文件系统,页面需要一次以8个页面的块进行实例化,如果有内存压力推出特定页面,则需要写出所有8个页面同时如果它是脏的,然后同时从页面缓存中删除所有8个页面。所有这一切都意味着您想要在4k页面级别跟踪页面使用情况和页面脏,而在复合32k页面/"块"水平。它基本上将涉及对VM子系统的几乎每个部分的更改,从页面清理器到页面错误处理程序,页面扫描程序,写回算法等等。

还要考虑即使你聘请了一位Linux VM专家来完成这项工作,(硬盘供应商也会非常喜欢你,因为他们也希望能够以32k或64k部署硬盘驱动器)在这样一个经过修改的VM层出现在Red Hat Enterprise Linux内核或SuSE或Ubuntu的等效企业或LTS内核之前,将需要5到7年的时间。因此,如果您正在一家希望将您的SSD产品销售到企业市场的初创公司工作 - 您现在也可以放弃这种方法。在你没钱之前,它就不会工作了。

现在,如果您正在为一家正在制作自己的硬件(Facebook,亚马逊,谷歌等)的大型云公司工作,也许您可​​以走这条特定的道路,因为他们不能使用企业内核以极快的速度添加新功能 - 但出于这个原因,他们希望相对靠近上游内核以最大限度地降低维护成本。

如果您为其中一家大型云计算公司工作,我强烈建议您联系同一空间的其他公司,也许您可​​以与他们合作,看看是否可以一起做这种开发工作和共同尝试在上游进行这种改变。实际上,真的并不是一个微不足道的变化,但是 - 特别是因为上游Linux内核开发人员会要求这不会对常见情况下的性能产生负面影响,这将涉及> 4k块设备在不久的将来的任何时间。如果你在Facebook,谷歌,亚马逊等地工作,这不是你想要作为内核的私人改变而维护的那种改变,而是你想要上游的东西,因为其他方面它将是一个巨大的,侵略性的变化,支持它作为一个树外补丁将是巨大的头痛。

答案 1 :(得分:0)

虽然我从来没有为 Linux 编写设备驱动程序,但我发现这不太可能是驱动程序接口的真正限制。我想你可能希望将I / O分解为分散 - 收集列表,其中列表中的每个条目长一页(以提高内存分配性能并减少内存碎片),但大多数设备类型现在可以直接处理这些,我认为driver interface中的任何内容都不需要它。实际上,向块设备发出请求的最简单方法(在第13页上描述 - 标记为该文本的第476页)看起来像是收到:

  • 扇区起始编号
  • 要转移的多个行业(没有提及限制,更不用说限制为8 512B个行业)
  • 指向将数据写入/读取数据的指针(对于这个简单的情况,我猜不是分散 - 收集列表)
  • 这是读取还是写入

我怀疑如果你只看到4K访问,这可能是调用者一次不要求超过4K的结果 - 如果你在设备上运行的文件系统只发出4K读取,或者其他什么使用文件系统一次只能访问一个块,设备驱动程序无法自行更改它!

一次使用一个块对于数据库读取工作负载等随机访问模式很常见,但是传统(非写入时复制)文件系统上的数据库日志或FS日志写入或大型串行文件读取会发出大量I / O更像你期待的。如果您想尝试直接针对您的设备发出大量读取以查看是否可以通过您现有的任何驱动程序,您可以使用dd if=/dev/rdiskN of=/dev/null bs=N查看将bs参数从4K增加到1M是否显示吞吐量增加。