什麼可以使用我的 6GB 交換空間?
我有一個謎:什麼在使用我的 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)的文件描述符可以包含對可交換記憶體的引用?Note
logind
包含這樣的文件描述符。
EDIT1在停止 systemd-logind(本地 Xorg 通過死亡來響應)並重新啟動 Xorg 之後,我看到整個 6GB 的交換空間都被清除了。
第二次之後,我可以確認這是 systemd-logind 中的一個錯誤。
logind
記得關閉它持有的 DRM fd 的副本,但它無法關閉保存在 PID1 中的副本(用於支持 logind 的“無縫”重啟):$ sudo lsof /dev/dri/card0 | grep systemd [sudo] password for alan-sysop: lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs Output information may be incomplete. systemd 1 root 16u CHR 226,0 0t0 14690 /dev/dri/card0 systemd 1 root 87u CHR 226,0 0t0 14690 /dev/dri/card0 systemd 1 root 101u CHR 226,0 0t0 14690 /dev/dri/card0 systemd 1 root 106u CHR 226,0 0t0 14690 /dev/dri/card0 systemd 1 root 110u CHR 226,0 0t0 14690 /dev/dri/card0 systemd-l 860 root 21u CHR 226,0 0t0 14690 /dev/dri/card0 systemd-l 860 root 25u CHR 226,0 0t0 14690 /dev/dri/card0
這感覺很像一個已知的錯誤,應該已經在 systemd 的 v238 中修復。
實際上,每次我登錄和退出 GNOME 時,logind 似乎都會以這種方式洩漏 DRM fd。大概只有當顯示伺服器不干淨地關閉時,此錯誤才會變得明顯,因此它們沒有機會釋放附加到其 DRM fd 的緩衝區。
EDIT2:我是否正確猜測圖形設備(DRM)的文件描述符可以包含對可交換記憶體的引用?注意 logind 持有這樣的文件描述符。
回答:是的。
菲利普
SHMEM 文件節點用作可交換緩衝區對象的備份儲存。
– https://www.kernel.org/doc/html/v4.15/gpu/drm-mm.html
據我了解,這裡的“SHMEM 文件節點”與 tmpfs 文件/memfd 的工作完全相同。上面的引用是關於“GEM 緩衝區對象”…
mmap 系統呼叫不能直接用於映射 GEM 對象,因為它們沒有自己的文件句柄。目前有兩種替代方法可以將 GEM 對象映射到使用者空間……第二種方法使用 DRM 文件句柄上的 mmap 系統呼叫。
– https://01.org/linuxgraphics/gfx-docs/drm/drm-memory-management.html#id-1.3.4.6.6.8
**結論:**有人真的應該仔細檢查 logind 中的目前程式碼,因為它與文件句柄的關閉有關:)。
附錄:如何嘗試排除 memfds
有沒有人有一個很好的方法來檢查 memfds 的記憶體使用情況?
memfds 的記憶體使用情況可以
stat --dereference
通過. 要麼是文件描述符,要麼 - 你忘記了 -記憶體映射對象。du -D``/proc/$PID``fd/$FD``map_files/...
我對此並沒有非常好的便利,但您至少可以搜尋最大的單個 FD 或映射文件。(下面的範例不是額外的證據;它是在 6GB 的交換使用量消失後拍攝的)。
$ sudo du -aLh /proc/*/map_files/ /proc/*/fd/ | sort -h | tail -n 10 du: cannot access '/proc/self/fd/3': No such file or directory du: cannot access '/proc/thread-self/fd/3': No such file or directory 108M /proc/10397/map_files/7f1e141b4000-7f1e1ad84000 111M /proc/14862/map_files/ 112M /proc/10397/map_files/ 113M /proc/18324/map_files/7efdda2fb000-7efddaafb000 121M /proc/18324/map_files/7efdea2fb000-7efdeaafb000 129M /proc/18324/map_files/7efdc82fb000-7efdc8afb000 129M /proc/18324/map_files/7efdd42fb000-7efdd4afb000 129M /proc/18324/map_files/7efde52fb000-7efde5afb000 221M /proc/26350/map_files/ 3.9G /proc/18324/map_files/ $ ps -x -q 18324 PID TTY STAT TIME COMMAND 18324 pts/1 S+ 0:00 journalctl -b -f $ ps -x -q 26350 PID TTY STAT TIME COMMAND 26350 ? Sl 4:35 /usr/lib64/firefox/firefox $ sudo ls -l /proc/18324/map_files/7efde52fb000-7efde5afb000 lr--------. 1 root root 64 Mar 19 00:32 /proc/18324/map_files/7efde52fb000-7efde5afb000 -> /var/log/journal/f211872a957d411a9315fd911006ef03/user-1001@c3f024d4b01f4531b9b69e0876e42af8-00000000002e2acf-00055bbea4d9059d.journal