我有一个谜:什么在使用我的 6GB 交换空间?我的内核版本是4.15.9-300.fc27.x86_64
.
这发生在一些崩溃之后。 dmesg
显示我在 gnome-shell 进程(属于 gdm)和后来的一些 firefox 进程(Chrome_~dThread,在 libxul.so 中)中有段错误。 coredumpctl -r
在我当前的启动中没有显示其他崩溃。
1.free
和df -t tmpfs
# free -h
total used free shared buff/cache available
Mem: 7.7G 1.2G 290M 5.4G 6.1G 761M
Swap: 7.8G 6.0G 1.8G
# swapoff -a
swapoff: /dev/dm-1: swapoff failed: Cannot allocate memory
# df -h -t tmpfs
Filesystem Size Used Avail Use% Mounted on
tmpfs 3.9G 17M 3.9G 1% /dev/shm
tmpfs 3.9G 1.9M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs 3.9G 40K 3.9G 1% /tmp
tmpfs 786M 20K 786M 1% /run/user/1000
我还手动检查了每个进程的挂载命名空间是否有任何额外的 tmpfs。没有其他挂载的 tmpfs(或者它们是相同的 - 所以只有 17M,并且有不到 10 个不同的挂载命名空间)。
2.ipcs
# ipcs --human
------ Message Queues --------
key msqid owner perms size messages
------ Shared Memory Segments --------
key shmid owner perms size nattch status
0x00000000 20643840 alan-sysop 600 512K 2 dest
0x00000000 22970369 alan-sysop 600 36K 2 dest
0x00000000 20774914 alan-sysop 600 512K 2 dest
0x00000000 20905987 alan-sysop 600 3.7M 2 dest
0x00000000 23461892 alan-sysop 600 2M 2 dest
0x00000000 20873221 alan-sysop 600 3.7M 2 dest
0x00000000 22511622 alan-sysop 600 2M 2 dest
0x00000000 28278791 alan-sysop 600 60K 2 dest
0x00000000 23003144 alan-sysop 600 36K 2 dest
0x00000000 27394057 alan-sysop 600 60K 2 dest
0x00000000 29622282 alan-sysop 600 156K 2 dest
0x00000000 27426828 alan-sysop 600 60K 2 dest
0x00000000 28246029 alan-sysop 600 60K 2 dest
0x00000000 29655054 alan-sysop 600 156K 2 dest
0x00000000 29687823 alan-sysop 600 512K 2 dest
------ Semaphore Arrays --------
key semid owner perms nsems
0x002fa327 98304 root 600 2
3.进程内存
每个进程的交换使用脚本说进程内存只占 54MB 的交换:
PID=1 swapped 2292 KB (systemd)
PID=605 swapped 4564 KB (systemd-udevd)
PID=791 swapped 324 KB (auditd)
PID=793 swapped 148 KB (audispd)
PID=797 swapped 232 KB (sedispatch)
PID=816 swapped 120 KB (mcelog)
PID=824 swapped 1544 KB (ModemManager)
PID=826 swapped 152 KB (rngd)
PID=827 swapped 300 KB (avahi-daemon)
PID=829 swapped 1688 KB (abrtd)
PID=830 swapped 836 KB (systemd-logind)
PID=831 swapped 432 KB (dbus-daemon)
PID=843 swapped 368 KB (chronyd)
PID=848 swapped 312 KB (avahi-daemon)
PID=854 swapped 476 KB (gssproxy)
PID=871 swapped 1140 KB (abrt-dump-journ)
PID=872 swapped 1280 KB (abrt-dump-journ)
PID=873 swapped 1236 KB (abrt-dump-journ)
PID=874 swapped 14196 KB (firewalld)
PID=911 swapped 592 KB (mbim-proxy)
PID=926 swapped 1356 KB (NetworkManager)
PID=943 swapped 17936 KB (libvirtd)
PID=953 swapped 200 KB (atd)
PID=955 swapped 560 KB (crond)
PID=1267 swapped 284 KB (dnsmasq)
PID=1268 swapped 316 KB (dnsmasq)
PID=10397 swapped 160 KB (gpg-agent)
PID=14862 swapped 552 KB (systemd-journal)
PID=18131 swapped 28 KB (login)
PID=18145 swapped 384 KB (bash)
Overall swap used: 54008 KB
到目前为止,我假设没有
umount -l
在完整的 tmpfs 上使用过的程序。我没有尝试为任何持有这种隐藏 tmpfs 打开的人抓取 /proc/*/fd 。我想我也假设没有人建造了一个巨人
memfd
并把它打开……哈哈,我为什么会怀疑这样的事情……呜咽。
附加到进程的 memfd 名称对我来说似乎是无辜的:
# ls -l /proc/*/fd/* 2>/dev/null|grep /memfd:
lrwx------. 1 alan-sysop alan-sysop 64 Mar 18 22:52 /proc/20889/fd/37 -> /memfd:xshmfence (deleted)
lrwx------. 1 alan-sysop alan-sysop 64 Mar 18 22:52 /proc/20889/fd/53 -> /memfd:xshmfence (deleted)
lrwx------. 1 alan-sysop alan-sysop 64 Mar 18 22:52 /proc/20889/fd/54 -> /memfd:xshmfence (deleted)
lrwx------. 1 alan-sysop alan-sysop 64 Mar 18 22:52 /proc/20889/fd/55 -> /memfd:xshmfence (deleted)
lrwx------. 1 alan-sysop alan-sysop 64 Mar 18 22:52 /proc/20889/fd/57 -> /memfd:xshmfence (deleted)
lrwx------. 1 alan-sysop alan-sysop 64 Mar 18 22:52 /proc/20889/fd/60 -> /memfd:xshmfence (deleted)
lrwx------. 1 alan-sysop alan-sysop 64 Mar 18 22:52 /proc/21004/fd/6 -> /memfd:pulseaudio (deleted)
这些 memfd 看起来是无辜的,因为: Process 20889 是我当前的Xorg
,它在 6GB 交换之后。同样,进程 21004 确实是我的 pulseaudio 进程,并且该进程的创建时间晚于建立 6GB 的交换。
理论上,我担心的那些也可能处于不确定状态,附加到 unix 套接字消息并且从未阅读过。
编辑1
在停止systemd-logind
(本地 Xorg 通过死亡来响应)并重新启动 Xorg 之后,我看到整个 6GB 的交换空间都被清除了。
注意我忘了我需要重新开始登录。虽然 lennart 告诉我 logind 不应该被总线激活,但 logind 立即重新启动。这是来自journalctl -b
,即系统日志,中间没有删除任何消息:
Mar 18 23:14:12 alan-laptop systemd[1]: Stopped Login Service.
Mar 18 23:14:12 alan-laptop dbus-daemon[831]: [system] Activating via systemd: service name='org.freedesktop.login1' unit='dbus-org.freedesktop.login1
Mar 18 23:14:12 alan-laptop systemd[1]: Starting Login Service...
这与 logind 相关,然后经历了几次崩溃的循环。这是这个版本的 logind 的预期结果(修复它的 PR 已在上游合并,在我的问题报告之后)。
所以这并不能完全隔离一个单独的原因,我真的应该在杀死它之前检查 fds logind 所持有的。
问题
我在上述检查中是否遗漏了任何可能的交换用户? (非破坏性的,在 EDIT1 之前)。
有没有更好的方法来获取我上面列出的任何可能的用户的使用报告?也就是说,是否有一种替代方法可以纠正我没有注意到的一些不准确之处?或者更容易运行,并在再次发生这种情况时获得快速结果的东西?
有没有人有一个很好的脚本来检查 fds 打开一个“隐藏的”tmpfs(一个与 tmpfs 分离的 tmpfs umount -l
)?
有没有人有一个很好的方法来检查 memfds 的内存使用情况?
有什么方法可以检查在未读的 unix 套接字消息中是否存在大量 memfds?(这些天才中的任何一个在实现 memfds 时是否考虑过这一点,memfds 是明确用于传递 unix 套接字的?)
EDIT2:我是否正确猜测图形设备(DRM)的文件描述符可以包含对可交换内存的引用?Notelogind
包含这样的文件描述符。
第二次之后,我可以确认这是 systemd-logind 中的一个错误。
logind
记得关闭它持有的 DRM fd 的副本,但它无法关闭保存在 PID1 中的副本(用于支持 logind 的“无缝”重启):这感觉很像一个已知的错误,应该已经在 systemd 的 v238 中修复。
实际上,每次我登录和退出 GNOME 时,logind 似乎都会以这种方式泄漏 DRM fd。大概只有当显示服务器不干净地关闭时,此错误才会变得明显,因此它们没有机会释放附加到其 DRM fd 的缓冲区。
回答:是的。
-- https://www.kernel.org/doc/html/v4.15/gpu/drm-mm.html
据我了解,这里的“SHMEM 文件节点”与 tmpfs 文件/memfd 的工作完全相同。上面的引用是关于“GEM 缓冲区对象”...
-- https://01.org/linuxgraphics/gfx-docs/drm/drm-memory-management.html#id-1.3.4.6.6.8
结论:有人真的应该仔细检查 logind 中的当前代码,因为它与文件句柄的关闭有关:)。
附录:如何尝试排除 memfds
memfds 的内存使用情况可以
stat --dereference
通过. 要么是文件描述符,要么 - 你忘记了 -内存映射对象。du -D
/proc/$PID
fd/$FD
map_files/...
我对此并没有非常好的便利,但您至少可以搜索最大的单个 FD 或映射文件。(下面的示例不是额外的证据;它是在 6GB 的交换使用量消失后拍摄的)。