Нововведения при работе с памятью RHEL/CentOS 6 или история одной перезагрузки

В один прекрасный вечер хост, на который заливались по сети резервные копии, начал самопроизвольно перезагружаться. Хост во время резервного копирования был не плохо загружен, трафик порядка 100 Мбайт/с. Поиск в интернете дал множество похожих проблем с RHEL/CentOS 6.2, при этом люди жаловались на то, что до обновления, на RHEL/CentOS 5 никаких проблем не было. Под катом пример сообщения об ошибке из системного журнала, информация о ее причинах и обходное решение.

Пример ошибки:

kernel: bma: page allocation failure. order:0, mode:0x20
kernel: Pid: 25564, comm: bma Not tainted 2.6.32-279.14.1.el6.x86_64 #1
kernel: Call Trace:
kernel:   [] ? __alloc_pages_nodemask+0x77f/0x940
kernel: [] ? tcp_v4_do_rcv+0x280/0x430
kernel: [] ? kmem_getpages+0x62/0x170
kernel: [] ? fallback_alloc+0x1ba/0x270
kernel: [] ? cache_grow+0x2cf/0x320
kernel: [] ? ____cache_alloc_node+0x99/0x160
kernel: [] ? __alloc_skb+0x6d/0x190
kernel: [] ? kmem_cache_alloc_node_notrace+0x6f/0x130
kernel: [] ? __kmalloc_node+0x7b/0x100
kernel: [] ? __netif_receive_skb+0x49b/0x6f0
kernel: [] ? __alloc_skb+0x6d/0x190
kernel: [] ? dev_alloc_skb+0x1d/0x40
kernel: [] ? vmxnet3_rq_rx_complete+0x15b/0x880 [vmxnet3]
kernel: [] ? nommu_map_page+0x0/0xc0
kernel: [] ? vmxnet3_poll_rx_only+0x43/0xc0 [vmxnet3]
kernel: [] ? net_rx_action+0x103/0x2f0
kernel: [] ? hrtimer_get_next_event+0xc3/0x100
kernel: [] ? __do_softirq+0xc1/0x1e0
kernel: [] ? handle_IRQ_event+0x60/0x170
kernel: [] ? call_softirq+0x1c/0x30
kernel: [] ? do_softirq+0x65/0xa0
kernel: [] ? irq_exit+0x85/0x90
kernel: [] ? do_IRQ+0x75/0xf0
kernel: [] ? ret_from_intr+0x0/0x11
kernel:   [] ? skb_release_data+0x9f/0x110
kernel: [] ? skb_release_head_state+0x6a/0x110
kernel: [] ? __kfree_skb+0x1e/0xa0
kernel: [] ? tcp_recvmsg+0xda8/0xe90
kernel: [] ? inet_recvmsg+0x5a/0x90
kernel: [] ? sock_aio_read+0x181/0x190
kernel: [] ? do_sync_read+0xfa/0x140
kernel: [] ? autoremove_wake_function+0x0/0x40
kernel: [] ? ktime_get_ts+0xa9/0xe0
kernel: [] ? security_file_permission+0x16/0x20
kernel: [] ? vfs_read+0x181/0x1a0
kernel: [] ? audit_syscall_entry+0x272/0x2a0
kernel: [] ? sys_read+0x51/0x90
kernel: [] ? system_call_fastpath+0x16/0x1b

Ядро в RHEL/CentOS 5 при утилизации памяти выше 90% и запросе на выделение страницы памяти переиспользовало память занятуе под кэш. У ядра же в RHEL/CentOS 6 на этот счет иное мнение. Поэтому, даже если 90% памяти использовано под кэш, ядро может отказать приложению в выделении памяти, если размер запрошенной памяти превышает параметр vm.min_free_kbytes.

Кроме того в RHEL/CentOS 6.2 и 6.3 параметр vm.zone_reclaim_mode по умолчанию раверн 0, в предыдущих версиях было 1.

Обходное решение в такой ситуации может быть следующим:

vm.zone_reclaim_mode=1
vm.min_free_kbytes = 524288