LWN:KDE中的资源管理!

关注了就能看到更多这么棒的文章哦~

Resource management in KDE

October 19, 2020
This article was contributed by Marta Rybczyńska
Akademy
DeepL assisted translation
https://lwn.net/Articles/834329/

近年来,在 Linux 桌面上运行的应用程序底层其实发生了很大的变化。例如,它们使用的进程比以前更多了。桌面环境(desktop environment)需要适应这种变化。在 Akademy 2020 期间,KDE 开发者 David Edmundson 和 Henri Chain 发表了一场演讲,讲述了 KDE 如何与其他桌面环境合作,开始使用更先进的内核功能,让用户可以对系统有更多的控制。这个演讲是对 GNOME 开发者的一个演讲的补充,这个演讲最近在 LWN 有介绍(https://lwn.net/Articles/834329/)。

Process-management issues in Plasma

Edmundson 首先解释说,桌面环境的工作是向用户提供应用程序。他说,用户 "需要拥有掌控权"。近年来,用户角色变得更加复杂。此前,用户运行 Firefox 这样的网页浏览器或 Kopete 这样的聊天应用时,用户可以很容易管理这些运行进程。只要运行一个 ps 命令,就会看到每个应用程序。这很容易理解,都不用多解释。

现在,情况就 "大不相同 "了。用户打开一个 Firefox 实例时,他们可能会创建十几个进程。在 Flatpak ("因为它现在很流行")中的 Discord 程序启动了 13 个进程。ps 的输出是很难理解的,它包含一些 "做随机的事情的随机的进程名 "组成。光是去理解这些输出就很困难,而要想将结果汇总来了解应用程序使用了多少 CPU 时间和计算量,就更加困难了。因此,大家需要在桌面环境中正确地跟踪进程,现有的数据不再有任何意义。我们 "需要一些 metadata(元数据)",Edmundson 总结道。

公平性也是一个越来越重要的问题。Edmundson 举了一个高级图形应用(advanced graphics applications) Krita 的例子。它会执行许多繁重的处理任务,都包含在一个进程中。另一方面,Discord 有那 13 个进程,其中许多进程将大量使用 CPU,"因为它是用 Electron 编写的"。系统的 CPU 调度器会将这两个应用程序视为 14 个不同的进程,不知道它们对应的是什么。这意味着 Krita 只能获得 1/14 的可用 CPU 时间,尽管它代表了运行中的两个应用中的一半。他说,关于运行中的应用程序的 metadata 需要能经过整个软件堆栈传播给 kernel,才能让 scheduler 用来进行更合理的决策。

Plasma 的任务之一是将窗口(windows)映射到应用程序。更准确地说,它试图将窗口映射到它们相关的桌面文件(desktop files),也就是包含了 metadata 的配置文件,比如可以用来创建菜单项。应用程序显示某个窗口后,"我们希望能把它们全部匹配起来"。Plasma 的开发人员使用了很多黑客和启发式方法来执行这种匹配工作。但 "我们不喜欢猜测",他说。他举了一个例子,一个 firefox 窗口被用来观看 Akademy 演讲,在那个窗口里面有一个音频图标,但这个图标与控制更外部窗口的那个音频图标不是由同一个进程管理的。Plasma 需要找到它们之间的联系,"这是一个很容易猜错的做法"。

Introducing control groups

Chain 接下来介绍说:"好消息是,这个问题基本上已经解决了"。这个解决方案以控制组(也就是 cgroups)的形式实现的,这是 2008 年 1 月发布的 2.6.24 内核的一个功能。控制组实现了进程空间的分层结构。他补充说,最初 cgroups 是为服务器设计的,在容器中也有很多使用。

资源控制器(resource controller)可以绑定到特定的控制组,这里主要有三种:CPU、memory 和 I/O(用于磁盘访问)的 cgroup。它们的基本功能是用来限制整体资源的使用,影响调度器的决策,并以 group 为单位来统计资源使用情况。cgroups 的另一个特点是对内存不足情况下的处理策略可以控制得更加精细。CPU cgroup 控制时会通过 "weights(权重) "来影响调度,权重可以根据进程树中的兄弟进程来决定。权重较高的组会按比例获得更多的 CPU 时间。对于桌面来说,权重策略比用 nice 设置优先级更有优势。其中,权重可以用来提高 cgroup 中进程的优先级,也可以用来降低优先级。

Cgroups 可以通过 sysfs 直接控制,但实际上来说还是需要一个中心控制进程来管理这些进程该放在哪个 cgroup 里面。在 Linux 系统中,systemd "永远 "都在支持这一功能,Chain 说,每个 systemd 单元都已经被放置到自己的 cgroup 中。systemd 能够将 cgroup 树的管理委托给另一个用户空间进程,这是由一个单独的 systemd 实例来完成的。systemd 还提供了一个可以从用户空间使用的 D-Bus 接口,允许从任何应用程序中控制 cgroup。配置问题也得到了解决,因为它可以在各个不同 level 来进行配置。

Cgroups 在 2015 年经过了重新设计,从而解决了一些问题。由此产生的新 API 被称为 cgroups v2.然而,大多数发行版将 systemd 配置为使用混合层次结构(在本文档中描述:https://systemd.io/CGROUP_DELEGATION/) 模式,这样并没有使用到所有新功能。目前除了 Fedora 之外,所有现代发行版都在使用这种模式。因此,systemd 通常不能在 user level 来配置分组。

Chain 解释说,即使是 cgroups v2 也有一些限制。例如,内部节点(inner nodes)不能包含进程,原因是为了让内核里的统计功能保持简单性。这也包括一种情况,也就是 cgroup 有其他 cgroup 作为子节点的情况。在这种情况下,不可能将进程绑定到父 parent cgroup 上。这些 inner node 在 systemd 中被称为 slices。

cgroups 的配置可以事先准备好。在没有进行配置的情况下,有两种方法可以利用 systemd 来实现新的应用。其中一种是使用 scopes 工具(https://www.freedesktop.org/software/systemd/man/systemd.scope.html) :像往常一样启动进程,然后要求 systemd 将其放入一个 cgroup 中。这样,一个 scope 就包含了一组与 systemd 分开启动的进程。另一种模式使用了 services(https://www.freedesktop.org/software/systemd/man/systemd.service.html ):像典型的守护进程一样,在这种情况下,systemd 启动应用程序并管理它的生命周期。

 (systemd-cgls output)

Chain 展示了一个 systemd-cgls 命令的输出示例,可以看到控制组的层次结构。这个输出有包含 slides 和 services,systemd 用户实例也可以看到(user:@1000.slice)。

Edmundson 解释说,Plasma 5.19 会在自己的 cgroup 中生成各个应用程序。他说,这只是 KIO 中代码的一小部分,但整个 KDE 代码库需要付出很多努力来统一启动应用程序的方法。"这在过去 20 年里变得很零散",他指出,"所以无论如何都值得统一"。开发人员发现了几十个需要修复的 edge case。他们的目标是安全地完成迁移。

引入 cgroups 是一个相当大的变化。第一步要开始利用 scopes 工具来使用 cgroups,与之前的设置相比改动尽可能小。启动应用程序进程后,它们就被标记为属于这个 cgroup。一切正常的话,开发人员将可以开始使用更多的 metadata。目前,调度器用上这些 metadata 了。任务管理器也有个 patch,正在 review;libksysguard 可以将这些信息暴露给用户。Edmundson 展示了旧版的 ksysguard 和重写后的版本,它们显示了相同的信息,但组织方式不同。在新版本中,主列表只显示应用程序名称,进程列表则单独显示。他指出,归类的算法比以前更可靠了。

Cooperation with GNOME

"Plasma 自己做的话,是走不远的",Edmundson 在解释如何与其他项目合作时说。Plasma 团队开始着手解决这个问题的时候就与 GNOME 开发者进行过交流。结果发现两个团队都想做同样的事情(尽管原因不同,GNOME 专注于内存用完情况下的处理流程)。他们开始合作,统一了 desktop file 的标签,将应用程序名称映射到 cgroup 名称。他们提出了一套通用的应用程序运行的 slices。KDE 和 GNOME 团队与一些内核开发者会面,研究这个问题。他们提出了一个共同的解决方案。"这将是通用的方案",Edmundson 说。

Upcoming features

基本功能已经实现了,Plasma 团队正在计划下一步的工作。其中之一包括为一些服务和程序静态地分配权重,以控制它们可以占用的 CPU 时间。会有三个 slides,其中一个是 KWin 和 Plasma 的专门的 session。这在 Wayland 上尤其重要,因为在 Wayland 上 "KWin 正在做一些非常重要的工作"。另一个 slice 将包括所有的用户运行应用程序,它们将在这个 slice 中竞争系统资源。最后,background slice 将包括那些在某些时候需要运行、但可以以较低优先级运行的进程(如对文件进行索引)。

未来,用户将可以对应用进行限制,例如,可以限制文件索引器只占用 10%的 CPU,设置 out-of-memory 的参数,阻止 fork bombs 攻击。

Chain 一直在研究根据运行时的信息来改变资源分配。他创建了一个包装 systemd DBus API 的小函数库,用来把当前运行的应用程序的资源控制权限暴露出来。鼓励听众们查看一下。该库包括一个演示应用程序(https://www.youtube.com/watch?v=o6_uq5AQOHg) ,它可以和窗口管理器交流, 来获取当前获取了焦点的应用程序,从而改变其权重。这个功能对于提高移动系统的电池寿命很有用,Chain 在回答观众的问题时解释道。

另一个即将进行的变化是从 scopes 改为 systemd service。届时,进程的生命周期管理将由 systemd 完成。与 scopes 相比,多了一些配置选项。使用 service 也避免了 systemd 238 以上版本中的一个 bug,即无法将应用程序分组到 scopes 中。这方面的实现代码已经准备好了,隐藏在一个 flag 中,但开发者在 systemd 中遇到了问题,现在的体验还不如使用 scopes。Chain 补充说,还需要更多的工作来让 crash handling 能正常工作起来。

剩下的工作就是转换 Plasma 的其他部分,包括后台服务。目标是让 Plasma session 能作为一个 systemd 单元。另一个目标是让 sysadmins 熟悉这种体验。这是来自一个发行版提供方的要求,这样就不会需要学习新的一层管理界面,管理员可以继续使用熟悉的工具。依赖 Benjamin Berg(来自 GNOME 团队)的工作,desktop files 正在被 "神奇地 "转换为 systemd。另外,所有的环境变量都应该能 "正常工作"。

Conclusion

KDE 和 GNOME 团队已经完成了一些重要的工作,为桌面使用 cgroups 做好了准备。由于基本的基础架构已经建立起来,用户可以看到这些改进如何影响现在的整体体验了。完成这项工作还需要更多的工作,在未来的几个月和几年里,我们应该会看到这方面的进展。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~