Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Linuxがメモリ不足で固まるのを回避する

 Linuxがメモリ不足で固まるのを回避する

E567a535ddc7964130dd086f147a7682?s=128

Kenichiro MATOHARA

July 18, 2021
Tweet

Transcript

  1. Linuxがメモリ不 Linuxがメモリ不 足で固まるのを回 足で固まるのを回 避する 避する Kenichiro Matohara(matoken) <maroken@kagolug.org> 1

    / 28
  2. 南隅から参加(鹿児島の右下) 好きなLinuxディストリビューションはDebian お仕事募集 mailto:work@matohara.org Kenichiro Matohara(matoken) Kenichiro Matohara(matoken) https://matoken.org https://matoken.org

    2 / 28
  3. 最近 最近 EtherpadのURLを変えたり 7/11でApple/Ankerの製品見てきたり 3 / 28

  4. メモリ不足で固まる メモリ不足で固まる メモリ枯渇すると辛い diskゴリゴリしつつ固まり最終的にOOM Killerでプロセス終了 一時的にswapを増やしたり コンソールに降りて( Ctrl+Alt+F1 )プロセスをkillして回避したり MagickSysrqで再起動したり(

    Reboot Even If System Utterly Broken ) $ sudo sh -c 'SWAP=/var/tmp/swap.img;umask 0066 && fallocate -l 2G \ ${SWAP} && mkswap ${SWAP} && swapon ${SWAP}' 4 / 28
  5. OOM Killer OOM Killer メモリ不足(Out Of Memorry)でシステムが停止するのを回避するため にメモリをたくさん使っているプロセスをkillしてくれる(Killer) どのプロセスがkillされるかは前もって優先度を設定していないと わからない

    /proc/<PID>/oom_score のスコアを参考にする /proc/<PID>/oom_adj で重み付けが出来る -16〜+17 の範囲で小さいほど死ににくく, -17 は対象外.既 定値は 0 5 / 28
  6. oom_score, oom_adj の例 oom_score, oom_adj の例 bashに比べてbraveが少し死にやすくなっている $ ps aux|

    grep -m1 bash matoken 4963 0.0 0.0 17600 12492 pts/0 Ss 22:15 0:00 /bin/bash $ cat /proc/4963/oom_adj 0 $ cat /proc/4963/oom_score 666 $ ps aux| grep [b]rave | tail -1 | cut -d\ -f-23 matoken 66250 20.2 1.2 38316376 203852 ? Sl 23:10 3:53 /opt/brave.com/brave/brave $ cat /proc/66250/oom_adj 5 $ cat /proc/66250/oom_score 869 6 / 28
  7. OOM Killer が起こる前のフリー OOM Killer が起こる前のフリー ズを回避するいくつかの試みを ズを回避するいくつかの試みを 知る 知る

    nohang le9 patch その他 "le9" Strives To Make Linux Very Usable On Systems With Small Amounts Of RAM - Phoronix https://github.com/hakavlad/nohang#solution 7 / 28
  8. nohang & le9 patch を試してみる nohang & le9 patch を試してみる

    hakavlad/nohang: A sophisticated low memory handler for Linux GitHub - hakavlad/le9-patch: [PATCH] mm: Protect clean file pages under memory pressure to prevent thrashing, avoid high latency and prevent livelock in near-OOM conditions 8 / 28
  9. nohang導入(Debian Bullseye/sid) nohang導入(Debian Bullseye/sid) 1 パッケージがあるでそれを利用 2 デーモンの起動 or 3

    デスクトップ通知版デーモンの起動 $ sudo apt install nohang $ sudo systemctl enable --now nohang.service $ sudo systemctl enable --now nohang-desktop.service 1 2 3 9 / 28
  10. 導入(Raspberry Pi OS Buster) 導入(Raspberry Pi OS Buster) 1 source

    clone 2 パッケージビルドスクリプトの実行 3 パッケージの導入 4 デーモンの起動 or 5 デスクトップ通知版デーモンの起動 $ git clone https://github.com/hakavlad/nohang $ cd nohang $ deb/build.sh $ sudo apt install ./deb/package.deb $ sudo systemctl enable --now nohang.service $ sudo systemctl enable --now nohang-desktop.service 1 2 3 4 5 10 / 28
  11. デスクトップ通知されないとき デスクトップ通知されないとき パッケージの導入 ※Raspberry Pi buster の notify-osd 0.9.35+15.04.20150126-1 だと

    /etc/xdg/autostart/notify-osd.desktop の Exec を修 正 $ sudo apt install notify-osd - Exec=/usr/lib/notify-osd/notify-osd + Exec=/usr/lib/arm-linux-gnueabihf/notify-osd 11 / 28
  12. le9 patch 導入 le9 patch 導入 Linux Kernel へのpatch Linux

    5.10〜5.13 用と Linux 5.14-rc1 用が用意されている (ドキュメントにはないが, le9db-5.4.patch というファイルも ある) hakavlad/le9-patch: [PATCH] mm: Protect clean file pages under memory pressure to prevent thrashing, avoid high latency and prevent livelock in near- OOM conditions 12 / 28
  13. Debian bullseyeでLinux 5.13 の例 Debian bullseyeでLinux 5.13 の例 1 kernel

    buildに必要なパッケージの導入 2 kernel buildに必要なパッケージの導入 3 kernel source の入手 4 kernel source の解凍(署名確認のため) 5 署名確認(署名 → )  Debian pkg kernel(5.10) の場合 apt source linux でsourceの入 手が出来る $ sudo apt install build-essential flex bison fakeroot gpg2 $ sudo apt build-dep linux $ wget -c https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.13.tar.xz \ https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.13.tar.sign $ unxz ./linux-5.13.tar.xz $ gpg --verify ./linux-5.13.tar.sign $ tar xf ./linux-5.13.tar 1 2 3 4 5 6 https://www.kernel.org/category/signatures.html 13 / 28
  14. 1 現在利用しているkernelの .config をコピー 2 .config の新しい部分を規定値で設定 3 証明書場所を変更 4

    .config カスタマイズ 5 test $ cd linux-5.13 $ cp /boot/config-`uname -r` ./.config $ make olddefconfig $ vi ./.config $ grep ^CONFIG_SYSTEM_TRUSTED_KEYS= ./.config CONFIG_SYSTEM_TRUSTED_KEYS="" $ make xconfig $ make testconfig 1 2 3 4 5 14 / 28
  15. 1 5.10〜5.13用patch入手 2 patch 適用 3 build&package作成 4 kernel pkg

    install $ wget -c https://raw.githubusercontent.com/hakavlad/le9-patch/main/le9db_patches/le9db-5.10.pa -O ../le9db-5.10.patch $ cat ../le9db-5.10.patch | patch -p1 $ time make -j$(nproc) bindeb-pkg LOCALVERSION=-le9 $ sudo apt install ../linux-image-5.13.0-le9_5.13.0-le9-1_amd64.deb \ ../linux-headers-5.13.0-le9_5.13.0-le9-1_amd64.deb \ ../linux-libc-dev_5.13.0-le9-1_amd64.deb 1 2 3 4 15 / 28
  16. secure boot対応 secure boot対応 1 kernelに署名 2 dkms moduleにも署名 

    詳細は → $ sudo sbsign --key ~root/MOK.priv --cert ~root/MOK.pem /boot/vmlinuz-5.13.0-le9 --output ./vml $ sudo mv ./vmlinuz-5.13.0-le9 /boot/vmlinuz-5.13.0-mptcp $ find /lib/modules/5.13.0-le9/updates/dkms/ -type f -print0 | xargs -0 -n1 sudo /usr/lib/linux 2 https://wiki.debian.org/SecureBoot#MOK_- _Machine_Owner_Key 16 / 28
  17. reboot! reboot! $ cowsay -f tux $( uname -sr) |

    lolcat ________________________ < Linux 5.13.2-mptcp+le9 > ------------------------ \ \ .--. |o_o | |:_/ | // \ \ (| | ) /'\_ _/`\ \___)=(___/ 17 / 28
  18. Raspberry Pi OS buster 32bit に le9 Raspberry Pi OS

    buster 32bit に le9 Kernel cross build armhf(Pi2, Pi3, Pi3+, CM3) 1 sourceの入手 2 le9 patch入手 3 le9 patch適用 4 Piで sudo modprobe configs して /proc/configs.gz を 生やしておく 5 .config を用意 $ wget https://github.com/raspberrypi/linux/archive/refs/tags/raspberrypi-kernel_1.20210527-1.z $ tar tvf raspberrypi-kernel_1.20210527-1.zip $ tar xf raspberrypi-kernel_1.20210527-1.zip $ wget https://raw.githubusercontent.com/hakavlad/le9-patch/main/le9db_patches/le9db-5.10.patch $ cd raspberrypi-kernel_1.20210527-1 $ cat ../le9db-5.10.patch | patch -p1 $ rsync -avc raspberrypi.local:/proc/config.gz ../ $ zcat ../config.gz ./.config 3 4 5 18 / 28
  19. 1 cross buildのためのpkg導入 2 .config を既定値で設定 3 build 4 Piにpkg

    cp.転送先でpkg導入. $ sudo apt install crossbuild-essential-armhf $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOCALVERSION=-le9 olddefconfig $ time make -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOCALVERSION=-le9 zImage modules dt $ ls -1 ../linux-*-le9*_armhf.deb ../linux-headers-5.10.17-v7-le9_5.10.17-v7-le9-1_armhf.deb ../linux-image-5.10.17-v7-le9_5.10.17-v7-le9-1_armhf.deb ../linux-libc-dev_5.10.17-v7-le9-1_armhf.deb $ rsync -avc ../linux-*-le9*_armhf.deb pi@raspberrypi.local:~/tmp/ 1 2 4 19 / 28
  20. Piでinstall Piでinstall kernelが置き換わらず駄目だった……宿題に $ sudo mount -o rw,remount /boot $

    sudo apt install ~/tmp/*.deb Kernel building - Raspberry Pi Documentation 20 / 28
  21. Linux に RAMを少なく見せる Linux に RAMを少なく見せる テストのためにRAMを少なくしたいけど物理モジュールを抜き差 しするのは面倒 kernelへのoptionでメモリ量を指定して任意の容量にする 21

    / 28
  22. Document Document — mem=nn[KMG] [KNL,BOOT] Force usage of a specific

    amount of memory Amount of memory to be used in cases as follows: 1 for test; 2 when the kernel is not able to see the whole system memor 3 memory that lies after 'mem=' boundary is excluded from the hypervisor, then assigned to KVM guests. [X86] Work as limiting max address. Use together with memmap= to avoid physical address space collisions. Without memmap= PCI devices could be placed at addresses belonging to unused RAM. Note that this only takes effects during boot time since in above case 3, memory may need be hot added after boot if system memory of hypervisor is not sufficient. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/ad guide/kernel-parameters.txt?h=v5.13.3#n2724 22 / 28
  23. x86 GRUBで起動オプション指定 x86 GRUBで起動オプション指定 GRUBのメニューで編集したいエントリを矢印上下キーで選択し て, e ボタンを押して編集メニューに入る linux /vmlinuz〜

    といった行に移動して末尾に追加の起動オプ ションを追記 今回はメモリを2GBに制限したいので, mem=2048m を指定 ↓ Ctrl + x を押してこのオプションで起動 linux /vmlinuz-5.13.2-mptcp+le9 root=/dev/mapper/yoga— 260— vg-root ro linux /vmlinuz-5.13.2-mptcp+le9 root=/dev/mapper/yoga— 260— vg-root ro mem=2048m 23 / 28
  24. メモリ確認 メモリ確認 1 コマンドラインオプションの確認( mem=2048m が付いている) 2 メモリの確認 3 メモリの確認

    $ cat /proc/cmdline BOOT_IMAGE=/vmlinuz-5.13.2-mptcp+le9 root=/dev/mapper/yoga--260--vg-root ro mem=2048m $ head -1 /proc/meminfo MemTotal: 2032968 kB $ free total used free shared buff/cache available Mem: 2032968 1575032 70032 161360 387904 139588 Swap: 0 0 0 1 2 3 24 / 28
  25. 負荷を掛けてみる 負荷を掛けてみる 大量のメモリ不足のメッセージ以外は快適 通知方法を変えることもできそう( /etc/nohang/nohang.conf ) 重くならない! ChromiumでTweetdeckとかは開いてすぐ死ぬ 25 /

    28
  26.  デモビデオ → https://github.com/hakavlad/nohang#demo 26 / 28

  27. まとめ まとめ nohang + le9 patch で固まり難く! デスクトップ用途には良さそう メモリ増設のできないタブレット等に良さそう zram等との組み合わせも

    メモリ枯渇するとchromium だとページ開けなくなるけどしょうが ないか swapを追加で逃げたり 27 / 28
  28. 奥付 奥付 発表 発表者 利用ソフトウェア ライセンス CC BY-NC-SA 4.0 鹿児島Linux勉強会

    2021.07(オンライン開催) Kenichiro Matohara(matoken) Asciidoctor Reveal.js 28 / 28