贴出原文地址以防止不遵守共享协议:https://lwn.net 对于系统中的资源使用管理来说,控制组是一个非常有用的机制;但是当控制组本身成为资源问题的本身的时候将会发生什么?在2019年Linux存储、文件系统和内存管理全体大会峰会上,Roman Gushchin描述了他面对的一个问题:删除控制组后,在真实生效之前花费的时间。这里面的一些问题已经被修复了,但问题并没有真正的解决。
控制组通过虚拟文件系统来管理;一个特定的控制组的移除通过删除代表他的那个路径即可实现。可是这里面的真相是,如Gushchin所说,当删除控制组的路径,这个控制组会继续存在于内核,直到所有与之存在的关联关系都被去除。如果关联持续存在,那么资源就会一直被消耗。
这个问题在内存控制组特别突出,因为所有由这个控制组负责的内存页都会与之有关联。因此对于一个内存控制组,除非所有他管理的内存页都被回收,否则他不会被真实的删除,而这个回收过程则是相当漫长;如果这其中的一些内存页仍在被活跃的使用,那么回收的期限将更加遥遥无期。这些都加剧删除控制组的缓慢,困扰整个系统;Gushchin在一周的运行中发现了1500次这样的情况。
Gushchin说,这个问题造成的后果并不大,但是让人非常的不开心。每个控制组的存在大概消耗200KB内存,当上千的控制组在等死的时候,这个数字就非常大了。当内核遍历控制组时,所有这些控制组都会造成复杂度增加和开销。这些内存还会脱离内存管理的统计。
坚持要删除控制组也是有一些原因的,因为对于一些问题,删控制组会比用其他方式处理更简单。比如说,在处理用户页时一个园整问题引起最终页不能被回收,这个BUG在所有控制组子系统都有出现,不过现在修复了。另一个问题就是内核栈的统计,在2016年切换虚拟映射栈使引入,这个栈占用内存被算到了第一个alloc他的进程上,当然也会被算在进程所在控制组头的上;当一个栈被其他进程重用,这个统计却没有更新,就会。。。当然,这个问题也修复了。
有一个到现在没有修复的问题,就是从slab申请内核内存的问题。一些缓存了的对象,比如目录对象的结构,是从slab中申请的,由适当的控制组管理;他们同样必须在控制组真实删除前清理。但是在内存压力不大的时候,shrinkers运行的并不主动,这些对象将会存在很久很久。Gushchin试着加入了一个补丁来制造额外的内存压力,可是补丁在XFS文件系统产生了性能退化,随后就会退了。因此现在他正在通过另外的路径:在控制组移除的时候重排slab缓存。已经有一组补丁在审查当中,希望在不远的将来能够修复这个问题。