How do I get the Linux OOM killer to not kill my processes when physical memory is low but there is plenty of swap space?
I have disabled OOM killing and overcommit with sysctl vm.overcommit_memory=2.
The VM has 3 GB of absolutely free unfragmented swap and the processes that is being OOM killed has max memory usage less than 200MB.
I know that long term swapping will be horrible for performance, but I need to use the swap right now to do functional testing under valgrind where memory requirements are much greater.
Mar 7 02:43:11 myhost kernel: memcheck-amd64- invoked oom-killer: gfp_mask=0x24002c2, order=0, oom_score_adj=0
Mar 7 02:43:11 myhost kernel: memcheck-amd64- cpuset=/ mems_allowed=0
Mar 7 02:43:11 myhost kernel: CPU: 0 PID: 3841 Comm: memcheck-amd64- Not tainted 4.4.0-x86_64-linode63 #2
Mar 7 02:43:11 myhost kernel: Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Mar 7 02:43:11 myhost kernel: 0000000000000000 0000000000000000 ffffffff8158cbcc ffff880032d7bc18
Mar 7 02:43:11 myhost kernel: ffffffff811c6a55 00000015118e701d ffffffff81044a8d 00000000000003e2
Mar 7 02:43:11 myhost kernel: ffffffff8110f5a1 0000000000000000 00000000000003e2 ffffffff81cf15cc
Mar 7 02:43:11 myhost kernel: Call Trace:
Mar 7 02:43:11 myhost kernel: [<ffffffff8158cbcc>] ? dump_stack+0x40/0x50
Mar 7 02:43:11 myhost kernel: [<ffffffff811c6a55>] ? dump_header+0x59/0x1dd
Mar 7 02:43:11 myhost kernel: [<ffffffff81044a8d>] ? kvm_clock_read+0x1b/0x1d
Mar 7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e
Mar 7 02:43:11 myhost kernel: [<ffffffff81183316>] ? oom_kill_process+0xc0/0x34f
Mar 7 02:43:11 myhost kernel: [<ffffffff811839b2>] ? out_of_memory+0x3bf/0x406
Mar 7 02:43:11 myhost kernel: [<ffffffff81187bbd>] ? __alloc_pages_nodemask+0x8ba/0x9d8
Mar 7 02:43:11 myhost kernel: [<ffffffff811b82e8>] ? alloc_pages_current+0xbc/0xe0
Mar 7 02:43:11 myhost kernel: [<ffffffff811b096c>] ? __vmalloc_node_range+0x12d/0x20a
Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar 7 02:43:11 myhost kernel: [<ffffffff811b0a83>] ? __vmalloc_node+0x3a/0x3f
Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar 7 02:43:11 myhost kernel: [<ffffffff811b0ab0>] ? vmalloc+0x28/0x2a
Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar 7 02:43:11 myhost kernel: [<ffffffff811e1338>] ? dup_fd+0x103/0x1f0
Mar 7 02:43:11 myhost kernel: [<ffffffff810dd143>] ? copy_process+0x5aa/0x160d
Mar 7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e
Mar 7 02:43:11 myhost kernel: [<ffffffff810de2fc>] ? _do_fork+0x7d/0x291
Mar 7 02:43:11 myhost kernel: [<ffffffff810ea186>] ? __set_current_blocked+0x47/0x52
Mar 7 02:43:11 myhost kernel: [<ffffffff810ea1f2>] ? sigprocmask+0x61/0x6a
Mar 7 02:43:11 myhost kernel: [<ffffffff81998eae>] ? entry_SYSCALL_64_fastpath+0x12/0x71
Mar 7 02:43:11 myhost kernel: Mem-Info:
Mar 7 02:43:11 myhost kernel: active_anon:15 inactive_anon:18 isolated_anon:0
Mar 7 02:43:11 myhost kernel: active_file:7 inactive_file:8 isolated_file:0
Mar 7 02:43:11 myhost kernel: unevictable:0 dirty:3 writeback:26 unstable:0
Mar 7 02:43:11 myhost kernel: slab_reclaimable:1798 slab_unreclaimable:3674
Mar 7 02:43:11 myhost kernel: mapped:8 shmem:1 pagetables:752 bounce:0
Mar 7 02:43:11 myhost kernel: free:1973 free_pcp:0 free_cma:0
Mar 7 02:43:11 myhost kernel: Node 0 DMA free:3944kB min:60kB low:72kB high:88kB active_anon:0kB inactive_anon:0kB active_file:28kB inactive_file:32kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB
mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:72kB slab_unreclaimable:236kB kernel_stack:48kB pagetables:60kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:36
0 all_unreclaimable? yes
Mar 7 02:43:11 myhost kernel: lowmem_reserve[]: 0 972 972 972
Mar 7 02:43:11 myhost kernel: Node 0 DMA32 free:3948kB min:3956kB low:4944kB high:5932kB active_anon:60kB inactive_anon:72kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1032064kB manag
ed:999552kB mlocked:0kB dirty:12kB writeback:104kB mapped:32kB shmem:4kB slab_reclaimable:7120kB slab_unreclaimable:14460kB kernel_stack:2112kB pagetables:2948kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_t
mp:0kB pages_scanned:792 all_unreclaimable? yes
Mar 7 02:43:11 myhost kernel: lowmem_reserve[]: 0 0 0 0
Mar 7 02:43:11 myhost kernel: Node 0 DMA: 20*4kB (UM) 17*8kB (UM) 13*16kB (M) 14*32kB (UM) 8*64kB (UM) 4*128kB (M) 4*256kB (M) 0*512kB 1*1024kB (M) 0*2048kB 0*4096kB = 3944kB
Mar 7 02:43:11 myhost kernel: Node 0 DMA32: 934*4kB (UM) 28*8kB (UM) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3960kB
Mar 7 02:43:11 myhost kernel: 71 total pagecache pages
Mar 7 02:43:11 myhost kernel: 42 pages in swap cache
Mar 7 02:43:11 myhost kernel: Swap cache stats: add 245190, delete 245148, find 77026/136093
Mar 7 02:43:11 myhost kernel: Free swap = 3118172kB
Mar 7 02:43:11 myhost kernel: Total swap = 3334140kB
Mar 7 02:43:11 myhost kernel: 262014 pages RAM
Mar 7 02:43:11 myhost kernel: 0 pages HighMem/MovableOnly
Mar 7 02:43:11 myhost kernel: 8149 pages reserved
Mar 7 02:43:11 myhost kernel: [ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents oom_score_adj name
Mar 7 02:43:11 myhost kernel: [ 2054] 0 2054 5101 1 15 4 283 0 upstart-udev-br
Mar 7 02:43:11 myhost kernel: [ 2063] 0 2063 12362 1 28 4 184 -1000 systemd-udevd
Mar 7 02:43:11 myhost kernel: [ 3342] 102 3342 9780 1 23 3 89 0 dbus-daemon
Mar 7 02:43:11 myhost kernel: [ 3423] 0 3423 10864 1 26 3 85 0 systemd-logind
Mar 7 02:43:11 myhost kernel: [ 3441] 0 3441 15344 0 34 3 184 -1000 sshd
Mar 7 02:43:11 myhost kernel: [ 3450] 0 3450 4786 0 14 3 43 0 atd
Mar 7 02:43:11 myhost kernel: [ 3451] 0 3451 5915 0 17 4 65 0 cron
Mar 7 02:43:11 myhost kernel: [ 3457] 101 3457 63962 0 28 3 202 0 rsyslogd
Mar 7 02:43:11 myhost kernel: [ 3516] 0 3516 3919 1 13 3 156 0 upstart-file-br
Mar 7 02:43:11 myhost kernel: [ 3518] 0 3518 4014 0 13 3 265 0 upstart-socket-
Mar 7 02:43:11 myhost kernel: [ 3557] 0 3557 66396 0 32 3 1802 0 fail2ban-server
Mar 7 02:43:11 myhost kernel: [ 3600] 0 3600 3956 1 13 3 39 0 getty
Mar 7 02:43:11 myhost kernel: [ 3601] 0 3601 3198 1 12 3 37 0 getty
Mar 7 02:43:11 myhost kernel: [ 3673] 0 3673 26411 1 55 3 252 0 sshd
Mar 7 02:43:11 myhost kernel: [ 3740] 1000 3740 26411 1 52 3 253 0 sshd
Mar 7 02:43:11 myhost kernel: [ 3741] 1000 3741 5561 0 16 3 431 0 bash
Mar 7 02:43:11 myhost kernel: [ 3820] 103 3820 7863 1 21 3 152 0 ntpd
Mar 7 02:43:11 myhost kernel: [ 3837] 1000 3837 31990 0 58 4 12664 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3841] 1000 3841 32006 0 59 4 12812 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3844] 1000 3844 31950 0 57 4 12035 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3849] 1000 3849 31902 0 56 4 11482 0 memcheck-amd64-
Mar 7 02:43:11 myhost kernel: [ 3853] 1000 3853 1087 0 7 3 27 0 lsof
Mar 7 02:43:11 myhost kernel: [ 3854] 0 3854 26140 5 55 3 230 0 sshd
Mar 7 02:43:11 myhost kernel: [ 3855] 104 3855 15699 0 33 3 202 0 sshd
Mar 7 02:43:11 myhost kernel: Out of memory: Kill process 3841 (memcheck-amd64-) score 11 or sacrifice child
Mar 7 02:43:11 myhost kernel: Killed process 3841 (memcheck-amd64-) total-vm:128024kB, anon-rss:0kB, file-rss:0kB
This is /proc/meminfo
MemTotal: 1015460 kB
MemFree: 277508 kB
MemAvailable: 322032 kB
Buffers: 8336 kB
Cached: 42208 kB
SwapCached: 46088 kB
Active: 58844 kB
Inactive: 116100 kB
Active(anon): 34784 kB
Inactive(anon): 89620 kB
Active(file): 24060 kB
Inactive(file): 26480 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 3334140 kB
SwapFree: 3215756 kB
Dirty: 16 kB
Writeback: 0 kB
AnonPages: 121128 kB
Mapped: 15072 kB
Shmem: 4 kB
Slab: 22668 kB
SReclaimable: 8028 kB
SUnreclaim: 14640 kB
KernelStack: 2016 kB
PageTables: 2532 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3841868 kB
Committed_AS: 380460 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
DirectMap4k: 14208 kB
DirectMap2M: 1034240 kB
DirectMap1G: 0 kB
Best Answer
This appears to be problem in combination of two factors:
This is partly one of the lines which describes why this happens:
The other line is this:
|The first line is the GFP mask assigned for the allocation. It basically describes what the kernel is allowed/not allowed to do to satify this request. The mask indicates a bunch of standard flags. The last bit, '2' however indicates the memory allocation should come from the
HighMem
zone.If you look closely at the OOM output, you'll see no
HighMem/Normal
zone actually exists.HighMem
(generally also calledNormal
on x86_64) tends to map memory for zones outside of the standard 896MiB ranges directly kernel accessible on 32 bit systems. On x86_64HighMem/Normal
seems to cover all pages above 3GiB in size.DMA32
contains a zone used for memory that would be accessible on 32-bit DMA devices, that is you can address them with 4 byte pointers. I believeDMA
is for 16-bit DMA devices.Generally speaking, on low memory systems
Normal
wouldn't exist, given thatDMA32
covers all available virtual addresses already.The reason you OOM kill is because there is a memory allocation for a
HighMem
zone with 0 pages available. Given the out of memory handler has absolutely no way to satisfy making this zone have pages to use by swapping, killing other processes or any other trick, OOM-killer just kills it.I believe this is caused by the host VM ballooning on boot up. On KVM systems, there are two values you can set.
The way this works is that you can hot-add memory to your server up to the available memory. Your system however is actually given the current memory.
When a KVM VM boots up, it starts with the maximum allotment of memory possible to be given (the available memory). Gradually during the boot phase of the system KVM claws back this memory using its ballooning, leaving you instead with the current memory setting you have.
Its my belief thats what happened here. Linode allow you to expand the memory, giving you much more at system start.
This means that there is a
Normal/HighMem
zone at the beginning of the systems lifetime. When the hypervisor balloons it away, the normal zone rightly disappears from the memory manager. But, I suspect that the flag setting whether the said zone is available to allocate from is not cleared when it should. This leads the kernel to attempt to allocate from a zone that does not exist.In terms of resolving this you have two options.
Bring this up on the kernel mailing lists to see if this really is a bug, behaviour expected or nothing at all to do with what I'm saying.
Request that linode set the 'available memory' on the system to be the same 1GiB assignment as the 'current memory'. Thus the system never balloons and never gets a Normal zone at boot, keeping the flag clear. Good luck getting them to do that!
You should be able to test that this is the case by setting up your own VM in KVM setting available to 6GiB, current to 1GiB and running your test using the same kernel to see if this behaviour you see above occurs. If it does, change the 'available' setting to equal the 1GiB current and repeat the test.
I'm making a bunch of educated guesses here and reading inbetween the lines somewhat to come up with this answer, but what I'm saying seems to fit the facts outlined already.
I suggest testing my hypothesis and letting us all know the outcome.