死不掉的控制组

对于系统中的资源使用管理来说,控制组是一个非常有用的机制;但是当控制组本身成为资源问题的本身的时候将会发生什么?在2019年Linux存储、文件系统和内存管理全体大会峰会上,Roman Gushchin描述了他面对的一个问题:删除控制组后,在真实生效之前花费的时间。这里面的一些问题已经被修复了,但问题并没有真正的解决。

控制组通过虚拟文件系统来管理;一个特定的控制组的移除通过删除代表他的那个路径即可实现。可是这里面的真相是,如Gushchin所说,当删除控制组的路径,这个控制组会继续存在于内核,直到所有与之存在的关联关系都被去除。如果关联持续存在,那么资源就会一直被消耗。

这个问题在内存控制组特别突出,因为所有由这个控制组负责的内存页都会与之有关联。因此对于一个内存控制组,除非所有他管理的内存页都被回收,否则他不会被真实的删除,而这个回收过程则是相当漫长;如果这其中的一些内存页仍在被活跃的使用,那么回收的期限将更加遥遥无期。这些都加剧删除控制组的缓慢,困扰整个系统;Gushchin在一周的运行中发现了1500次这样的情况。

Gushchin说,这个问题造成的后果并不大,但是让人非常的不开心。每个控制组的存在大概消耗200KB内存,当上千的控制组在等死的时候,这个数字就非常大了。当内核遍历控制组时,所有这些控制组都会造成复杂度增加和开销。这些内存还会脱离内存管理的统计。

坚持要删除控制组也是有一些原因的,因为对于一些问题,删控制组会比用其他方式处理更简单。比如说,在处理用户页时一个园整问题引起最终页不能被回收,这个BUG在所有控制组子系统都有出现,不过现在修复了。另一个问题就是内核栈的统计,在2016年切换虚拟映射栈使引入,这个栈占用内存被算到了第一个alloc他的进程上,当然也会被算在进程所在控制组头的上;当一个栈被其他进程重用,这个统计却没有更新,就会。。。当然,这个问题也修复了。

有一个到现在没有修复的问题,就是从slab申请内核内存的问题。一些缓存了的对象,比如目录对象的结构,是从slab中申请的,由适当的控制组管理;他们同样必须在控制组真实删除前清理。但是在内存压力不大的时候,shrinkers运行的并不主动,这些对象将会存在很久很久。Gushchin试着加入了一个补丁来制造额外的内存压力,可是补丁在XFS文件系统产生了性能退化,随后就会退了。因此现在他正在通过另外的路径:在控制组移除的时候重排slab缓存。已经有一组补丁在审查当中,希望在不远的将来能够修复这个问题。

在这些修复之后,Gushchin看到的问题已经被解决了,可是在这之外存在着其他潜在的问题。从vmalloc()申请的内存以及per-cpu页都会使潜在的问题区域。总的来说,Gushchin认为,很容易就会创建隐秘的对控制组的关联,进而妨碍控制组的清除,这是容易发生退步的区域。

在最后阶段,Michal Hocko说问题的一部分是简化用于表示内存控制组的结构体的大小。如果把结构体分成两部分,在控制组删除后仅保留核心的部分,可能问题会缓解一点。但是Johannes Weiner回复说现在内存压力是唯一能削弱这些被删除的控制组的东西;如果他们变得更小,他们将会累积的更深。因此,尽管这一问题的一些表象都被处理了,死不掉的控制组的问题,会和控制组们本身,陪伴我们一段时间。

发布了4 篇原创文章 · 获赞 3 · 访问量 1944

猜你喜欢

转载自blog.csdn.net/ytfy339784578/article/details/103945788
今日推荐