Page allocation failure: order:N, gfp_mask — Устранение сбоя памяти Linux
Архитектура ошибки и симптомы сбоя
Сообщение «Page allocation failure: order:N, mode:0x..., gfp_mask» генерируется аллокатором физических страниц ядра Linux (Buddy Allocator). Ошибка возникает, когда поток ядра или драйвер устройства (сетевая карта, контроллер RAID) запрашивает непрерывный блок физической памяти размером 2^N страниц (где order:0 = 4KB, order:3 = 32KB и т.д.), но из-за сильной внешней фрагментации ОЗУ ядро не может найти непрерывный фрагмент нужной длины, даже если общий объем свободной памяти достаточен.
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| order:N | 2^N страниц | Порядок непрерывного блока страниц (например, order:3 требует 8 непрерывных страниц = 32 KB). |
| gfp_mask | GFP Flags (Hex) | Get Free Page флаги аллокатора (GFP_ATOMIC, GFP_KERNEL), определяющие допустимость сна/блокировки при выделении. |
| GFP_ATOMIC | Non-blocking | Запрос памяти из прерывания/драйвера, при котором ядро не может уйти в сон или выполнить компактификацию. |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Принудительная дефрагментация (компактификация) памяти
Для экстренного объединения свободных страниц в крупные непрерывные блоки выполните:
# Запуск компактификации памяти вручную:
echo 1 | sudo tee /proc/sys/vm/compact_memory
# Проверка распределения блоков по порядкам (фрагментация):
cat /proc/buddyinfoСценарий 2: Увеличение системного резерва памяти (min_free_kbytes)
Увеличение vm.min_free_kbytes резервирует пул непрерывной памяти для атомарных запросов сетевых карт (Jumbo Frames) и контроллеров:
# Увеличение резерва до 512MB / 1GB (актуально для 64GB+ RAM):
sudo sysctl -w vm.min_free_kbytes=1048576
# Повышение агрессивности дефрагментации:
sudo sysctl -w vm.extfrag_threshold=100
sudo sysctl -w vm.compaction_proactiveness=50
# Закрепление в /etc/sysctl.d/99-memory.conf:
cat <<EOF | sudo tee -a /etc/sysctl.d/99-memory.conf
vm.min_free_kbytes = 1048576
vm.compaction_proactiveness = 50
EOF
sudo sysctl -p /etc/sysctl.d/99-memory.confСценарий 3: Настройка сетевых буферов драйвера
Если сбой вызывает высокоскоростной сетевой адаптер (10G/40G/100G Mellanox/Intel), отключите Jumbo Frames или оптимизируйте кольцевые буферы через ethtool -G eth0 rx 4096.
Инженеры ITSTM настроят тонкий тюнинг подсистемы памяти, параметры HugePages и распределение очередей сетевых карт (RSS/RFS) для бесперебойной работы ваших серверов.
Частые вопросы (FAQ)
Почему ошибка происходит, если команда free показывает много свободной памяти?
Свободная память может быть сильно фрагментирована на мелкие блоки по 4KB. Если драйвер запрашивает блок order:3 (32KB непрерывно) с флагом GFP_ATOMIC, ядро не может ждать дефрагментации и сразу фиксирует отказ выделения.
Как расшифровать gfp_mask в сообщении об ошибке?
Шестнадцатеричное значение gfp_mask представляет собой битовую маску флагов (например, 0x2080020 указывает на комбинацию GFP_ATOMIC | __GFP_HIGH | __GFP_NOWARN). Расшифровать точный набор флагов можно по исходному коду include/linux/gfp.h.