ctFS

背景

PM的访问

​ PM 的出现降低了非易失性内存和DRAM的性能差距,并且带来了可字节访问的特性。当前一些针对 PM 优化的文件系统,要么使用DAX技术来绕过 Page Cache ;要么通过将不同的文件系统数据结构映射到用户空间来绕过内核,以减少由用户态切换到内核态的开销。

Ext4-DAX Index path

​ 然而上述文件系统的索引结构还是传统的 tree-based。这种树型的索引结构是在 unix 系统时期提出的,当时内存和持久存储(磁盘)的访问速度相差几个数量级,主要的开销主要是对持久外存的访问。然而,PM 的出现让这种速度差异已经显着缩小到几乎可以忽略不计的程度。并且PM的低延迟反过来又将瓶颈从 I/O 转移到了文件索引开销上。据作者的实验显示,即便是ext4-dax模式,某些情况内存索引的开销占总开销的 45%。

image-20220721212356546

方案与设计

提出ctFS文件系统使用连续文件分配来代替文件索引。

​ ctFS使用持久页表 (PPT,Persistent Page Table) 管理文件的虚拟到物理映射。 PPT 与 DRAM 中的常规易失页表具有相似的结构,不同之处在于 PPT 永久存储在 PM 上。在 ctFS 内存区域内的地址出现页面错误时,操作系统会查找 PPT 并在基于 DRAM 的页表中创建相同的映射。因此,子序列访问由 MMU 提供查询DRAM中页表的服务,从而避免了索引成本。


ctFS的架构

ctFS的架构

​ ctFS 的架构如图所示,由两个组件组成:(1) 提供文件系统抽象的用户空间文件系统库 ctU,以及 (2) 提供虚拟内存抽象的内核子系统 ctK。 ctU 实现文件系统结构并将其映射到虚拟内存空间。 ctK 使用存储在 PM 中的持久页表 (PPT) 将虚拟地址映射到 PM 的物理地址。ctU 地址范围内的虚拟地址上的任何页面错误都由 ctK 处理。如果 PPT 中不包含故障地址的映射,ctK 将分配一个 PM 页,在 PPT 中建立映射,然后将映射从 PPT 复制到内核的 DRAM 页表,从而实现虚拟到 PM 地址的转换由 MMU 执行。当 PPT 中的任何映射过时 时,ctK 将从 DRAM 页表中删除相应的映射,并删除 TLB 中的映射。

ctU

​ ctFS 的用户空间库 ctU 将文件系统的虚拟内存空间组织成分层分区,以促进连续分配。ctFS采用类似于Linux 的伙伴分配算法来管理虚拟地址空间,并将它们分层,每个level之间的大小差距是8倍,和地址的对应的关系对应如下:

size of partition

​ 虚拟内存区域被划分为两个 L9 分区。第一个 L9 分区是用于存储文件系统元数据的特殊分区:超级块、inode 的位图以及 inode 本身。每个 inode 存储文件的元数据(例如,所有者、组、保护、大小等)和一个字段,用于标识包含文件数据的分区的虚拟内存地址。 inode 位图用于跟踪是否分配了 inode。第二个 L9 分区用于数据存储。

Layout of ctFS

​ 对于空闲页的查找,ctFS设置了一个表头来加速查找,对于L4-L9,会利用第一个页去保存使用状态,对于后面的三个层级,用一个页去表述空闲资源有些浪费,转为利用bitmap去表示。

ctK:

​ 由于地址空间布局随机化,内存区域可能会在不同进程中映射到不同的起始虚拟地址,并且硬件重新配置可能会更改 PM 的起始物理地址。虽然每个进程都有自己的 DRAM 页表,但 ctK 有一个 PPT,其中包含 ctU 内存范围内所有虚拟地址的映射(即分区内的那些)。 MMU 无法访问 PPT,因此 PPT 中的映射用于按需填充 DRAM 页表中的条目,作为页面错误处理的一部分。

ctK 负责管理PPT,对于虚拟地址和物理地址,ctFS都采用的相对地址,为每个进程映射到不同的虚拟地址


Pswap系统调用:

​ 最初,一个文件被分配在一个分区中,该分区的大小刚好足以容纳该文件。当文件超出其分区时,它会被移动到虚拟内存中更大的分区,而无需复制任何物理持久内存。 ctFS 通过使用 pswap 将文件的物理页面重新映射到新分区来做到这一点,这是一种新的操作系统系统调用,可以原子地交换虚拟到物理的映射。原子交换还可以在多块写入时实现高效的崩溃一致性,而无需重复写入数据。 ctFS 中的原子写入只是将数据写入新空间,然后将其与旧数据进行 pswaps。

Pswap

​ 上图展示了一个例子,其中 pswap 需要交换两个页面序列 A 和 B, 两个序列都包含 262658 (512 × 512 + 512 + 2) 个页面。 交换两个序列的数据时,使用pswap 只需要交换 4 对页表条目或目录,因为所有 262,658 个页面都被单个 PUD 条目覆盖(覆盖 512×512 个页面),单个 PMD 条目(涵盖 512 页)和两个 PTE 条目(涵盖 2 页)。