Eu tenho um mistério: o que está usando 6 GB do meu swap? Minha versão do kernel é 4.15.9-300.fc27.x86_64
.
Isso aconteceu após alguns travamentos. dmesg
mostra que tive um segfault em um processo gnome-shell (que pertencia ao gdm) e posteriormente em alguns processos do firefox (Chrome_~dThread, em libxul.so). coredumpctl -r
não mostra nenhuma outra falha na minha inicialização atual.
1. free
edf -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
Também verifiquei manualmente o namespace de montagem de cada processo, para qualquer tmpfs extra. Não havia outros tmpfs montados (ou eram os mesmos - portanto, apenas 17M e havia menos de 10 namespaces de montagem diferentes).
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. Memória de processo
O script de uso de troca por processo diz que a memória do processo representa apenas 54 MB de troca:
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
Até agora, estou assumindo que não há nenhum programa negligente usado
umount -l
em um tmpfs completo. Eu não tentei raspar /proc/*/fd para ninguém segurando um tmpfs tão oculto aberto.Suponho que também estou assumindo que ninguém construiu um gigante
memfd
e o mantém aberto ... haha, por que eu suspeitaria de tal coisa ... soluço.
Os nomes memfd anexados aos processos parecem inocentes para mim:
# 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)
Esses memfds parecem inocentes porque: O processo 20889 é meu arquivo Xorg
, que é posterior aos 6 GB de swap. Da mesma forma, o processo 21004 é, de fato, meu processo pulseaudio, e o tempo de criação desse processo é posterior aos 6 GB de swap acumulados.
Em teoria, aqueles com os quais estou preocupado também podem estar no limbo, anexados a uma mensagem de soquete unix e nunca lidos.
EDIT1
Depois de parar systemd-logind
- ao qual o Xorg nativo responde morrendo - e reiniciar o Xorg, vejo todos os 6 GB de troca eliminados.
Observe que esqueci que precisava iniciar o logind novamente. Embora Lennart tenha me dito que o logind não deveria ser ativado por barramento, o logind foi reiniciado imediatamente. Isso é de journalctl -b
, ou seja, o log do sistema, sem nenhuma mensagem removida no meio:
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...
Isso é relevante porque o logind passou por um ciclo de algumas falhas. Isso é esperado para esta versão do logind (PRs para corrigi-lo foram mesclados upstream, seguindo meus relatórios de problemas).
Portanto, isso não isola uma causa individual, e eu realmente deveria ter verificado o fds que o logind estava segurando antes de eliminá-lo.
Pergunta
Existe algum possível usuário de troca que eu perdi nas verificações acima? (Os não destrutivos, anteriores ao EDIT1).
Existe uma maneira melhor de obter relatórios de uso para qualquer um dos possíveis usuários listados acima? Ou seja, alguma alternativa que corrija alguma imprecisão que não percebi? Ou algo que será mais fácil de executar e obter um resultado rápido quando isso acontecer novamente?
Alguém tem um bom script para verificar se há fds mantendo aberto um tmpfs "oculto" (um tmpfs que foi desanexado com umount -l
)?
Alguém tem uma boa maneira de verificar o uso de memória de memfds?
Existe alguma maneira de verificar se memfds massivos foram deixados no limbo em uma mensagem de soquete unix não lida? (Algum desses gênios pensou nisso ao implementar memfds, que foram explicitamente destinados a passar por soquetes unix?)
EDIT2 : Estou certo em adivinhar que um descritor de arquivo de um dispositivo gráfico (DRM) pode conter uma referência à memória trocável? A nota logind
contém esses descritores de arquivo.
Após a segunda vez, posso confirmar que este é um bug no systemd-logind.
logind
lembra-se de fechar a cópia do DRM fd que ele contém, mas falha ao fechar a cópia que é mantida no PID1 (suporta o reinício "contínuo" usado do logind):Isso se parece muito com um bug conhecido, que já deve ter sido corrigido na v238 do systemd .
De fato, o logind parece estar vazando um DRM fd dessa maneira toda vez que eu entro e saio do GNOME. Presumivelmente, esse bug só se torna óbvio quando você desliga os servidores de exibição de maneira imprópria, para que eles não tenham a chance de desalocar os buffers anexados ao DRM fd.
Resposta: sim.
-- https://www.kernel.org/doc/html/v4.15/gpu/drm-mm.html
Pelo que entendi, "nó de arquivo SHMEM" aqui é algo que faz exatamente o mesmo trabalho que um arquivo tmpfs / memfd. A citação acima é sobre um "objeto de buffer GEM"...
-- https://01.org/linuxgraphics/gfx-docs/drm/drm-memory-management.html#id-1.3.4.6.6.8
CONCLUSÃO: alguém deve realmente verificar novamente o código atual em logind no que se refere ao fechamento de identificadores de arquivo :).
Apêndice: como você pode tentar descartar memfds
O uso de memória de memfds pode ser lido usando
stat --dereference
oudu -D
no link simbólico mágico em/proc/$PID
. Emfd/$FD
um descritor de arquivo ou - o que você esqueceu -map_files/...
em objetos mapeados na memória.Não tenho uma conveniência muito boa para isso, mas você pode pelo menos procurar os FDs individuais mais massivos ou arquivos mapeados. (O exemplo abaixo não é uma evidência adicional; foi obtido depois que os 6 GB de uso de swap foram eliminados).