The following program leads to OOM after some time when quarantine is enabled.
Without quarantine it runs without OOMs and top shows:
KiB Mem: 6837036 total, 96560 used, 6740476 free, 4636 buffers
KiB Mem: 6837036 total, 96160 used, 6740876 free, 4636 buffers
KiB Mem: 6837036 total, 96232 used, 6740804 free, 4636 buffers
KiB Mem: 6837036 total, 96664 used, 6740372 free, 4636 buffers
KiB Mem: 6837036 total, 97024 used, 6740012 free, 4636 buffers
KiB Mem: 6837036 total, 96840 used, 6740196 free, 4636 buffers
With quarantine top shows:
KiB Mem: 6837036 total, 6788916 used, 48120 free, 2576 buffers
KiB Mem: 6837036 total, 6711124 used, 125912 free, 2576 buffers
KiB Mem: 6837036 total, 6779400 used, 57636 free, 2576 buffers
KiB Mem: 6837036 total, 6757508 used, 79528 free, 2576 buffers
KiB Mem: 6837036 total, 6778356 used, 58680 free, 2576 buffers
KiB Mem: 6837036 total, 6777832 used, 59204 free, 2576 buffers
KiB Mem: 6837036 total, 6768796 used, 68240 free, 2576 buffers
And after some time the program crashes with:
fork: Cannot allocate memory
During the crash kernel says:
[ 1303.352092] a.out: page allocation failure: order:4, mode:0x2080d0
[ 1303.352757] CPU: 5 PID: 2609 Comm: a.out Not tainted 3.18.0-rc1+ #55
[ 1303.353414] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
[ 1303.354226] dfffe90000000000 ffff8800b1a5f880 ffffffff82c2de0e 0000000000000036
[ 1303.354956] 1ffff1001634bf14 ffff8800b1a5f9a0 ffffffff81322f28 0000000000000001
[ 1303.355735] 0000000400000004 0000000041b58ab3 ffffffff8321b8ec ffffffff81322d50
[ 1303.356494] Call Trace:
[ 1303.356744] [<ffffffff82c2de0e>] dump_stack+0x46/0x58
[ 1303.357290] [<ffffffff81322f28>] warn_alloc_failed+0x1d8/0x260
[ 1303.357870] [<ffffffff81322d50>] ? zone_watermark_ok_safe+0x290/0x290
[ 1303.358542] [<ffffffff8132ab4e>] ? __alloc_pages_direct_compact+0x58e/0x630
[ 1303.359260] [<ffffffff81321cd0>] ? drain_pages+0x1c0/0x1c0
[ 1303.359801] [<ffffffff8132a5c0>] ? get_page_from_freelist+0x18d0/0x18d0
[ 1303.360463] [<ffffffff813226e3>] ? drain_all_pages+0x183/0x220
[ 1303.361061] [<ffffffff813ea0b2>] ? memset+0xa2/0x260
[ 1303.361532] [<ffffffff82c394b3>] ? __schedule+0x893/0x1ad0
[ 1303.362087] [<ffffffff8132af48>] __alloc_pages_nodemask+0x358/0x1320
[ 1303.362682] [<ffffffff8132abf0>] ? __alloc_pages_direct_compact+0x630/0x630
[ 1303.363464] [<ffffffff813db5ec>] ? set_track+0x6c/0x140
[ 1303.363999] [<ffffffff810a6d5b>] ? native_flush_tlb_others+0x6b/0x80
[ 1303.364639] [<ffffffff810b06d7>] ? copy_process.part.41+0x207/0x52b0
[ 1303.365309] [<ffffffff813e904f>] ? kasan_poison_shadow+0x2f/0x40
[ 1303.365893] [<ffffffff813e9f94>] ? kasan_unpoison_shadow+0x14/0x40
[ 1303.366544] [<ffffffff813e904f>] ? kasan_poison_shadow+0x2f/0x40
[ 1303.367167] [<ffffffff813ea001>] ? kasan_kmalloc+0x41/0x50
[ 1303.367707] [<ffffffff813eacbd>] ? kasan_slab_alloc+0xd/0x10
[ 1303.368297] [<ffffffff8132bf7c>] alloc_kmem_pages_node+0x6c/0x90
[ 1303.368900] [<ffffffff810b06f5>] copy_process.part.41+0x225/0x52b0
[ 1303.369534] [<ffffffff81388f14>] ? handle_mm_fault+0xd84/0x1900
[ 1303.370146] [<ffffffff8137215b>] ? vmacache_find+0x13b/0x2d0
[ 1303.370701] [<ffffffff8109895c>] ? __do_page_fault+0x43c/0xbf0
[ 1303.371304] [<ffffffff810b04d0>] ? __cleanup_sighand+0x40/0x40
[ 1303.371874] [<ffffffff8138fee4>] ? remove_vma+0x124/0x170
[ 1303.372442] [<ffffffff810b5b71>] do_fork+0x161/0x790
[ 1303.372939] [<ffffffff8138fee4>] ? remove_vma+0x124/0x170
[ 1303.373504] [<ffffffff810b5a10>] ? fork_idle+0x230/0x230
[ 1303.374056] [<ffffffff811f45f0>] ? do_futex+0x1510/0x1510
[ 1303.374584] [<ffffffff810991aa>] ? trace_do_page_fault+0x6a/0x1d0
[ 1303.375228] [<ffffffff810b6221>] SyS_clone+0x11/0x20
[ 1303.375717] [<ffffffff82c44ce9>] stub_clone+0x69/0x90
[ 1303.376250] [<ffffffff82c449a9>] ? system_call_fastpath+0x12/0x17
[ 1303.376836] Mem-Info:
[ 1303.377103] Node 0 DMA per-cpu:
[ 1303.377429] CPU 0: hi: 0, btch: 1 usd: 0
[ 1303.377890] CPU 1: hi: 0, btch: 1 usd: 0
[ 1303.378490] CPU 2: hi: 0, btch: 1 usd: 0
[ 1303.378957] CPU 3: hi: 0, btch: 1 usd: 0
[ 1303.379447] CPU 4: hi: 0, btch: 1 usd: 0
[ 1303.379915] CPU 5: hi: 0, btch: 1 usd: 0
[ 1303.380402] CPU 6: hi: 0, btch: 1 usd: 0
[ 1303.380876] CPU 7: hi: 0, btch: 1 usd: 0
[ 1303.381352] Node 0 DMA32 per-cpu:
[ 1303.381691] CPU 0: hi: 186, btch: 31 usd: 0
[ 1303.382172] CPU 1: hi: 186, btch: 31 usd: 0
[ 1303.382638] CPU 2: hi: 186, btch: 31 usd: 0
[ 1303.383130] CPU 3: hi: 186, btch: 31 usd: 0
[ 1303.383600] CPU 4: hi: 186, btch: 31 usd: 0
[ 1303.384102] CPU 5: hi: 186, btch: 31 usd: 0
[ 1303.384569] CPU 6: hi: 186, btch: 31 usd: 0
[ 1303.385051] CPU 7: hi: 186, btch: 31 usd: 0
[ 1303.385516] Node 0 Normal per-cpu:
[ 1303.385860] CPU 0: hi: 186, btch: 31 usd: 0
[ 1303.386342] CPU 1: hi: 186, btch: 31 usd: 0
[ 1303.386807] CPU 2: hi: 186, btch: 31 usd: 1
[ 1303.387291] CPU 3: hi: 186, btch: 31 usd: 0
[ 1303.387756] CPU 4: hi: 186, btch: 31 usd: 0
[ 1303.388241] CPU 5: hi: 186, btch: 31 usd: 0
[ 1303.388713] CPU 6: hi: 186, btch: 31 usd: 26
[ 1303.389199] CPU 7: hi: 186, btch: 31 usd: 0
[ 1303.389663] active_anon:2613 inactive_anon:31 isolated_anon:0
[ 1303.389663] active_file:3308 inactive_file:1353 isolated_file:0
[ 1303.389663] unevictable:0 dirty:4 writeback:0 unstable:0
[ 1303.389663] free:42113 slab_reclaimable:1638744 slab_unreclaimable:13886
[ 1303.389663] mapped:1994 shmem:37 pagetables:292 bounce:0
[ 1303.389663] free_cma:0
[ 1303.392672] Node 0 DMA free:15876kB min:24kB low:28kB high:36kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:32kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
[ 1303.396613] lowmem_reserve[]: 0 2949 6656 6656
[ 1303.397145] Node 0 DMA32 free:81304kB min:4620kB low:5772kB high:6928kB active_anon:4224kB inactive_anon:48kB active_file:6008kB inactive_file:1988kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:3129332kB managed:3024924kB mlocked:0kB dirty:4kB writeback:0kB mapped:3356kB shmem:56kB slab_reclaimable:2907768kB slab_unreclaimable:19368kB kernel_stack:2816kB pagetables:448kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
[ 1303.401154] lowmem_reserve[]: 0 0 3707 3707
[ 1303.401621] Node 0 Normal free:71272kB min:5804kB low:7252kB high:8704kB active_anon:6228kB inactive_anon:76kB active_file:7224kB inactive_file:3424kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:3796204kB mlocked:0kB dirty:12kB writeback:0kB mapped:4620kB shmem:92kB slab_reclaimable:3647208kB slab_unreclaimable:36144kB kernel_stack:5952kB pagetables:720kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
[ 1303.405762] lowmem_reserve[]: 0 0 0 0
[ 1303.406197] Node 0 DMA: 1*4kB (U) 0*8kB 0*16kB 0*32kB 2*64kB (U) 1*128kB (U) 1*256kB (U) 0*512kB 1*1024kB (U) 1*2048kB (R) 3*4096kB (M) = 15876kB
[ 1303.407729] Node 0 DMA32: 262*4kB (UEM) 2634*8kB (UEM) 2869*16kB (UEM) 412*32kB (UEM) 8*64kB (UR) 1*128kB (R) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 81848kB
[ 1303.409728] Node 0 Normal: 119*4kB (UE) 2876*8kB (UEM) 2602*16kB (UEM) 206*32kB (UEMR) 1*64kB (M) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 71772kB
[ 1303.411378] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[ 1303.412194] 4697 total pagecache pages
[ 1303.412561] 0 pages in swap cache
[ 1303.412892] Swap cache stats: add 0, delete 0, find 0/0
[ 1303.413416] Free swap = 0kB
[ 1303.413702] Total swap = 0kB
[ 1303.413988] 2097051 pages RAM
[ 1303.414291] 0 pages HighMem/MovableOnly
[ 1303.414667] 361669 pages reserved
Reproducer program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
void myerror(const char *what) {
perror(what);
exit(1);
}
static void* thr(void *arg) {
for (int i = 0;; i++) {
if ((i % 1000) == 0) {
printf(".");
fflush(0);
}
int pipefd[2];
if (pipe(&pipefd[0]))
myerror("pipe");
if (write(pipefd[1], "a", 1) <= 0)
myerror("write");
if (close(pipefd[0]))
myerror("close");
if (close(pipefd[1]))
myerror("close");
void *p = mmap(0, 4096, PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0);
if (p == MAP_FAILED)
myerror("mmap");
if (munmap(p, 4096))
myerror("munmap");
int pid = fork();
if (pid == 0) {
exit(0);
} else if (pid > 0) {
int res = waitpid(pid, 0, 0);
if (res != pid && (res != -1 || errno != ECHILD))
myerror("waitpid");
} else {
myerror("fork");
}
}
return 0;
}
int main() {
pthread_t th[16];
for (int t = 0; t < 16; t++)
pthread_create(&th[t], 0, thr, 0);
pthread_join(th[0], 0);
return 0;
}