ZONE_DEVICE and the future of struct pag原文
作者: Jonathan Corbet 于2017年3月21日
2017年的Linux存储,文件系统和内存管理峰会的开幕会议涵盖了一个大家熟悉的主题 :如何将(可能是大规模的)持久性内存阵列(persistent-memory arrays)表示到内核的各个子系统。 本次会议由Dan Williams主持,特别关注对ZONE_DEVICE的抽象,讨论内核是否应该使用struct page结构来表示持久性内存(persistent memory)。
ZONE_DEVICE被绑定到内存分配器的区域系统(zone system)中(它根据诸如NUMA节点或DMA可达性之类的属性来隔离内存),但是以特殊的方式。它是为满足在持久性内存(persistent memory)上执行DMA操作的需要而创建的; 这些操作需要struct page结构来设置映射。 他说,ZONE_DEVICE基本上是内存热插拔机制(memory hotplug mechanism)的上半部分; 它执行内存设置,但实际上并不将页面联机(put the pages online)以供一般的使用。 因此,位于ZONE_DEVICE中的内存不能以正常方式分配,页面也不能迁移到该空间中,等等。但是可以在该Zone中获取内存的struct page结构。
在过去几年中,随着大型持久性内存(persistent memory)阵列对开发团体的影响,开发人员开始关注使用struct page结构的成本 - 每个4KB内存页面需要64字节。这种用法似乎是浪费的,所以已经有人做出一些重要的努力,尝试完全避免使用struct page结构; 相反,据认为,持久性内存(persistent memory)的管理可以完全用页框号(PFN)完成。pfn_t类型以及一大堆支持结构被添加到该目标,开发人员试图将整个DMA API转换为使用PFN。但是,他们遇到了SPARC64架构,它不能在不使用struct page结构的情况下创建DMA映射。威廉姆斯说,pfn_t的努力在那里死亡。
现在他说,也许现在是停止尝试避免struct page的时候了 。 如果我们让驱动程序假设struct page结构可用,那么我们将在具有TB级持久内存的系统中支付一些内存使用成本,但是我们将可以避免处理大量不一致行为的自定义驱动程序代码。 这将解决DMA问题,但这可能是这方面最简单的问题; struct page往往会出现在很多地方。
Matthew Wilcox观察到,事实上,很少有驱动真正关心struct page本身; 它只是作为一个方便的手段来引用物理内存。 他建议回顾一下,看看为什么SPARC不得不使用struct page结构, 威廉姆斯说,它与缓存混叠状态的管理(management of cache aliasing state)有关。 James Bottomley建议可能还有其他方法来解决这个问题,比如使用单独的数组来保存别名信息。 这只是说服SPARC维护者戴夫·米勒(Dave Miller)的问题。
如果可以实现这种说服,那么pfn_t几乎可以在任何地方使用,而不需要担心struct page结构的可用性。剩下的问题可能是解决那些需要直接到达DMA缓冲区的驱动程序的问题,但是Wilcox表示,他们应该只使用ioremap()来获取可用的地址来处理。
避免使用持久性内存(persistent memory)阵列的struct page的一个大动机就是这些结构可能最终填满系统普通内存的大部分。 避免这种情况的方法当然是在持久记忆本身中分配结构; Wilcox表示,只要将新内存添加到系统中,其关联的struct page结构应始终位于该新内存中。 问题是struct page可能是一个使用量很大的结构,所以有能力控制它的位置是很有用的。
内存使用问题的一个可能的解决方案是允许struct page结构引用较大的页面 - 例如2MB的大页面。这里的问题是,使大小可变(making the size variable)会增加内核中一些最热的代码路径的开销。 在某些方面将节省CPU时间,因为要管理的struct page结构数量将大大减少,但是有人怀疑节省的开销会增加页面分配器等的成本。
威廉姆斯说,另一个选择是在需要时动态分配struct page结构。 持久性内存(persistent memory)阵列的大小可以是TB级别,但是可能只需要struct page结构的一小部分。如果struct page结构的分配代价可以降低,那么只在需要时使它们存在是有意义的。
这个谈话以徘徊的方式伤痕累累(wound down in a wandering manner)。 Bottomley建议使用基数树(radix trees)跟踪内存的范围。 Kirill Shutemov指出,不同页面尺寸需要不同类型的信息; 在透明大页面(transparent huge pages)的情况下,可能需要将4KB页面称为单页面(single page)和巨大页面的组件(component of a huge page)。 Rik van Riel表示, struct page结构只是动态RAM的一个问题; 它们可以被用于持久性内存(persistent memory),因为当不再使用文件系统时,可以将文件系统计数为可用内存。 Bottomley回答说这种方法是可行的,但是迄今为止没有人愿意实施这一方法,这导致威廉姆斯观察到,该社团将在明年再次谈论同样的问题。