HMM and CDM原文
作者: Jonathan Corbet 于2017年3月22日
2017年Linux存储,文件系统和内存管理峰会的内存管理单元中的第一个主题继续在上一次全会期间开始讨论 ,该会议介绍了异构内存管理(heterogeneous memory management,HMM)问题,并对该组人员更新了那些补丁的状态。 在本届会议上,杰瑞斯·格里斯(Jérôme Glisse)着重讨论需要做些什么来推动这项工作。 接着,Balbir Singh随后采取了一种不同的处理HMM问题的方法,即更多的硬件支持。
推动HMM向前
HMM的讨论从社团的一个问题开始:像GPU这样的设备需要哪些功能以便能够支持HMM? 答案是,它需要某种页表结构,可用于设置每页内存的访问权限。 例如,这取决于在相关页面中找到哪种类型的代码,设置权限使得其可以执行在CPU或GPU上(但不是在两者上)。 HMM还需要能够防止两个处理器的同时写入,因此GPU需要能够处理故障(handle faults)。
Dave Hansen询问是否比I/O内存管理单元(IOMMU)能提供的还需要更多支持。 Glisse回应说,IOMMU主要是为了保护系统免受I/O设备的影响,这是一个不同的用例。 Mel Gorman补充说,HMM需要能够在特定页面上捕获写入故障,并在每一方面提供不同的保护 - IOMMU不能做的事情。
正在开展使用KSM机制进行写保护的工作; 那些补丁会很快发布。KSM允许将相同的页面映射到多个地址空间,这将是有用的一个功能,特别是在具有多个GPU的系统上,所有这些都需要访问相同的数据。
Andrea Arcangeli开始讨论写入故障的处理。通常,共享页面上的这种故障会导致写时复制(copy-on-write,COW)操作,但这里的情况不同; HMM设置中的响应是确保写入端对所讨论的内存进行独占访问。 Gorman对使用HMM的进程进行fork()调用后,写入的语义(emantics of writes)提出了一些担忧。 fork()通过标记可写页面给COW来工作,但是不清楚如果页面被COW映射到父和子两者中会发生什么; 写入故障最终可以以时序依赖(即Racy)的方式将页面的所有权赋予一个进程或另一个进程。
为了避免这种情况,Gorman建议使用madvise()系统调用将所有使用HMM的内存标记为MADV_DONTFORK; 这将导致无法向fork()的子进程提供内存。的确,他说这应该是强制性的。不过,后来他心软了,因为有人解释说明了在fork()时间之后,所有的HMM内存都被拉入父进程,而GPU中没有任何内存。 只要清楚HMM内存与父进程关联并且对子进程不可见,他就愿意接受这种情况。
随着这一点的解决,Gorman问是否有任何剩余的障碍影响合并。 Hansen提到,HMM不能与已经安装了最大内存的系统配合使用; GPU内存根本就没有物理地址空间。Gorman回答说,这个问题确实会在实践中出现,用户将被影响,但这是硬件的限制,而不是阻止HMM补丁合并的原因。
Dan Williams表示担心HMM补丁将GPU内存放入ZONE_DEVICE区域,该区域也用于持久性内存。这两个用途是不同的,可以相处,但是如果不了解所有该代码用户的开发者进行了更改,ZONE_DEVICE周围的代码就会变得更容易被破坏。 Gorman建议,Williams应从ZONE_DEVICE角度对HMM代码进行详细的审查; 他说,这个长期可维护性是一个根本的守则问题,需要仔细考虑。约翰内斯·韦纳( Jannann Weiner)建议,可以使用ZONE_HIGHMEM来代替。对于此,Gorman告诉他,“回家吧”。
最后的关注是缺乏为HMM代码写的驱动程序; 如果它以当前的形式合并,将不会有用户,是死亡代码。 不过似乎还有一些希望,在4.12合并窗口打开时,有一个基于Nouveau的NVIDIA GPU驱动程序将可用。Gorman建议安德鲁·莫顿(Andrew Morton)说,HMM代码可以保存在-mm树中,直到至少有一个驱动程序可用,但是Morton问就目前的代码去上游,是否真的是一个问题。他最喜欢的是对代码的有一个坚实的解释,所以当时间到了时,他可以为此向Linus Torvalds解释。
最终的结果是,HMM还有几个障碍需要破除,但是进入主线的路径开始看起来已经更加清晰了。
一致的设备内存节点(Coherent device memory nodes)
Singh然后向前迈进,以描述IBM对HMM的看法; 对于IBM来说,这个问题大多已经在硬件上解决了。 在设备齐全的系统(suitably equipped systems)中,设备内存显示为在自己的NUMA节点上,且恰好没有CPU。 该内存与系统的其余部分完全缓存一致(entirely cache-coherent), 虽然。 正在开发一个补丁系列 ,以在Linux上支持这些 “一致设备内存节点”(coherent device memory nodes,或CDM)。
还有一些关于这种硬件如何应用于Linux的问题。愿望是提供选择性的内存分配:用户空间应用程序可以选择是否在正常或CDM内存中分配内存。尽管如此,需要仔细处理回收,因为内核可能没有关于如何使用CDM上的内存的完整视图。 由于显而易见的原因,需要禁用正常的NUMA平衡(NUMA balancing),否则页面将不正确地迁入和迁出CDM。 当需要迁移时,应使用DMA引擎来加速迁移。
CDM内存的计划是将其在CPU上分配,然后在CDM处理器上运行使用该内存的软件。 该设备能够通过指针透明地访问自己的内存和普通的系统内存。 希望基于观察到的使用模式将内存迁移到最合适的节点。 Hansen指出,内核中的NUMA平衡代码工作得很好,但大多数人仍然关闭它; 在这个环境下真的会有必要如此吗? 辛格回应说可以有很大的区别; 来自应用程序的提示也可以帮助。
到目前为止,补丁包括使用cpuset机制隔离CDM的支持。 但系统没有足够的信息来正确地进行内存平衡(memory balancing)。区域列表(zone lists)已被拆分以分离CDM内存; 这用于将其从大多数系统中隐藏起来,并避免与常规内存混淆。 在会议结束时,透明的hugepage迁移(transparent hugepage migration)被提出,作为另一个缺失的一部分,但该主题被推迟到以后的讨论了。