Ядро Linux не может мягко обрабатывать ситуации с нехваткой памяти. Как побороть?

>Ядро Linux не может мягко обрабатывать ситуации с нехваткой памяти. Как побороть?

https://github.com/hakavlad/le9-patch

https://www.linux.org.ru/forum/general/16334308

Нехватка памяти, фризы: OOM KILLER, le9-patch и пр. (puppyrus forum) https://forum.puppyrus.org/index.php?topic=23160.msg178228#msg178228

Заметка ValdikSS https://notes.valdikss.org.ru/linux-for-old-pc-from-2007/

Заметка на форониксе, см также демо и отзывы в комментариях "le9" Strives To Make Linux Very Usable On Systems With Small Amounts Of RAM https://www.phoronix.com/scan.php?page=news_item&px=le9-Linux-Low-RAM
hakavlad, спасибо за сообщения, буду разбираться.
Для тех кто не знает, или кому некогда вникать в ответ выше -- тезисно даю выжимку.

Есть ли хоть одна причина по которой в 2017 году в линуксе нет штатного механизма ограничения минимального размера памяти, доступной для буферизации/кэширования, чтобы при ее исчерпании не приходилось черт знает сколько смотреть на unresponsive систему и ждать, пока процессы не попробуют использовать еще больше, вызвав срабатывание oom-killer, или не освободят занятую?”

Я хочу ограничить снизу, зарезервировать минимальное количество памяти для кэша, чтобы оом срабатывал быстро. Сейчас перед срабатыванием оом система превращается в тыкву на неопределенное время. Насколько я понимаю, причина в том, что формально памяти еще хватает, но для кэша ее совсем не осталось, и ввод-вывод становится чудовищно медленным".

***
...киллер убивает не рандомное приложение, а процесс с наибольшим oom_score (если vm.oom_kill_allocating_task=0), This normally selects a rogue memory-hogging task that frees up a large amount of memory when killed.
Нормальные админы защищают приложения, которые потенциально могут пострадать от киллера. В защите обычно не нуждаются мелкие процессы, ибо вероятность их убийства крайне мала.

***
С трудом верится, что такое примитивное действие (мягкая защита фиксированного количества случайного файлового кеша), реализованное несколькими строчками, так хорошо работает.

Вот и мейнтейнеры ядра не верят и не понимают. Например, Michal Hocko:
I am afraid there is nothing like that available and I would even argue
it doesn't make much sense either.

***
В итоге для арчлинукс реализацию патча легче всего “получить” от ядра linux-zen.

What is Zen Kernel?
Наиболее близким к «официальному» дистрибутиву ядра Zen Kernel является сборка @heftig в extra репозитории Arch. Он внимательно отслеживает конфигурацию пакета Linux Arch и отклоняется от него там, где ядро Zen рекомендует лучшие значения по умолчанию.

Там же упоминается и Greg Kroah-Hartman. Ниже кое-что о нём.
Грег Кроа-Хартман перешёл на использование Arch Linux

***
Ну и после теории -- практика. Одной картинкой.
Последовательно (насколько смог быстро) запустил 12 процессов:
tail /dev/zero
В общем и целом система полностью сохраняла работоспособность.
Сегодня случайно наткнулся в нашей вики на рекомендации по earlyoom и nohang.
5.5 Improving system responsiveness under low-memory conditions

Кстати, в эксперименте выше никаких дополнительных утилит не было установлено. Проблема с памятью решалась только за счёт ядра linux-zen.
>Проблема с памятью решалась только за счёт ядра linux-zen.

С какими настройками?

В zen недавно были баги:

сначала задержка прихода киллера и зависания https://github.com/zen-kernel/zen-kernel/issues/223 - исправлено

https://github.com/zen-kernel/zen-kernel/issues/225 - двойные убийства и ранние убийства, вроде вышло исправление https://github.com/zen-kernel/zen-kernel/issues/216#issuecomment-892122320 но релиза с ним не было

le9 по умолчанию не работает в zen - ибо включено mg-LRU.
hakavlad
С какими настройками?
Всё по умолчанию.

Установил ядро linux-zen из наших реп. И запустил свой тест. Результат в посте с картинкой.

Описание ниже понял буквально. И всё получилось.
How to get it
* zen-kernel provides le9 since v5.12.18 (commit). Cache protection may not work by default due to mg-LRU enabled.


"Защита кеша может не работать по умолчанию из-за включенного mg-LRU". А может и работать (как я понял). Попробовал. У меня, как видите, сработала. Почему-то вспомнил эпизод) Но в случае ядра результат положительный.
Механизмов контроля и управления memory в этом топике описано несколько, но по существу многим такие механизмы управления, как earlyoom, nohang не говоря уже об использовании ядра linux-zen не нужны в принципе …. потому что большинство такие жрущие процессы запускает не так часто, а если и запускают, то знают, что этот процесс потребляет много памяти и может повесить систему.
И в этом случае лучшим решением будет не держать постоянно запущенные демоны управления в памяти, а использовать разовые рецепты, что намного удобнее.
Для таких случаев в наше ядро зашит механизм cgroup2 (control group) - механизм/функция, предоставляемая ядром Linux для управления, ограничения и аудита групп процессов.
Раньше версия cgroup1 была не очень удобна и имела определенные минусы … с не давнего времени по дефолту используется cgroup2 - очень удобная и быстро настраиваемая. После того как немного освоил эту фичу, в основном стал использовать только ее … конечно, earlyoom тоже довольно прост и пока его деактивировал (удалять не стал) - нечего занимать зря постоянно память. А вот когда приходится запускать очень жрущее приложение (что случается довольно редко) и не хочется получить фризы, включаю данный процесс в управление cgroup2 в части ограничения памяти, что делается довольно быстро, простым вводом 3-х команд (создаю директорию, указываю PID нужного процесса и указываю максимальный размер памяти для для данного процесса) и нагружаю процесс ни о чем не беспокоясь - как только превысится размер выделенной ему памяти, он будет уничтожен (его сохранение мне и не нужно).
При желани можно настраивать и тоньше, а можно к этому добавить и нагрузку cpu и io.
Почитать для знакомства о cgroup2 - Wiki и DOC
Написано слишком заумно и муторно, подступался несколькот раз, пока не понял, что можно все делать довольно просто.
Ошибки не исчезают с опытом - они просто умнеют
Для наглядности привожу данные тестирования по ограничению памяти процесса с использование cgroup2 - пишу подробнее
В качестве подопыного выбран браузер palemoon
… для удобства даем себе права root (su)
1. Создаем контрольную группу, например, с именем palemoon
mkdir /sys/fs/cgroup/palemoon
Посмотреть что получили (какие файлы) - запустите команду ls -1 /sys/fs/cgroup/palemoon ... вывод большой, поэтому не привожу, но это практически почти то же самое что и в корневой директории /sys/fs/cgroup ...
Файлов много, настраивать можно много чего, но остановимся на самом простом - ограничении максимальной памяти процесса.

2. Зададим параметры управления, точнее укажем PID контролируемого процесса и значение максимально доступной этому процессу памяти
Нас интересую всего 2 файла, в которых прописывается
- PID контролируемого процесса
cat /sys/fs/cgroup/palemoon/cgroup.procs
… пусто …
- максимально доступная память для процесса
cat /sys/fs/cgroup/palemoon/memory.max
max
Видно, что значения не установлены, установим их
Узнаем PID процесса и прописываем его в соотвествующий файл
pidof palemoon
712
echo 712 > /sys/fs/cgroup/palemoon/cgroup.procs
Прописываем нужное максимальное значение памяти (в байтах) в соотвествующий файл, например, установим максимальное значение в 100M
echo 100000000 > /sys/fs/cgroup/palemoon/memory.max
Можно проверить, что получилось
cat /sys/fs/cgroup/palemoon/cgroup.procs
712
cat /sys/fs/cgroup/palemoon/memory.max
99999744
Все готово …. смотрим текущее значение памяти для данного процесса
cat /sys/fs/cgroup/palemoon/memory.current
11325440
порядка 11М, но что бы получить больше информации, открываю в tilix 2-ое окно и запускаю в нем команду
while true ; do cat /sys/fs/cgroup/palemoon/memory.current; sleep 1; done
и начинаю нагружать palemoon путем открытия новых вкладок, выбирал наиболее нагруженные вкладки, вроде бы на 6-ой palemoon был убит.
Привожу вывод команды while true ; do cat /sys/fs/cgroup/palemoon/memory.current; sleep 1; done … (лишние строки удалил, важен смысл)
71213056
73601024
75210752
76365824
77586432
79409152
82599936
90640384
96464896
97550336
98861056
99905536
352256
176128
176128
И как видим при достижении 100М palemoon был убит ... и никаких зависаний, подтормаживаний не наблюдалось (earlyoom деактивирован)

EDIT 1 - По окончании работы лучше удалить созданную директорию, но для этого контролируемый процеес должен быть убит/завершен
rmdir /sys/fs/cgroup/palemoon
ls /sys/fs/cgroup/palemoon
ls: невозможно получить доступ к '/sys/fs/cgroup/palemoon': Нет такого файла или каталога
Ошибки не исчезают с опытом - они просто умнеют
Vasek, спасибо, полезно))
Koluchka
спасибо, полезно
Присоединяюсь.

Однако такой способ не "на каждый день". Вариант ниже, доведённый до стабильного состояния и работающий в ядре по умолчанию, -- на мой взгляд -- предпочтительнее для повседневного использования.
vall
***
С трудом верится, что такое примитивное действие (мягкая защита фиксированного количества случайного файлового кеша), реализованное несколькими строчками, так хорошо работает.
 
Зарегистрироваться или войдите чтобы оставить сообщение.