Почему пользовательский процесс может вызвать Linux OOM-убийцу из-за фрагментации памяти, даже если доступно много оперативной памяти? - PullRequest
1 голос
/ 29 мая 2020

У меня есть система Linux (v3.10.53-1.1.1) на базе ARM, без включенного пространства подкачки, и я иногда вижу, как OOM-killer убивает процессы, хотя оперативной памяти достаточно. доступный.

Периодический запуск echo 1 > /proc/sys/vm/compact_memory, кажется, держит OOM-убийцу в страхе, что заставляет меня думать, что виновата фрагментация памяти, но я не понимаю, зачем пользовательскому процессу когда-либо понадобятся физически непрерывные блоки ; насколько я понимаю, даже в худшем случае (полная фрагментация, доступны только отдельные блоки 4K) ядро ​​может просто выделить необходимое количество отдельных блоков 4K, а затем использовать Magi c виртуальной памяти (tm) чтобы они выглядели смежными с пользовательским процессом.

Может ли кто-нибудь объяснить, почему OOM-killer вызывается в ответ на фрагментацию памяти? Это просто глючное ядро ​​или есть настоящая причина? (И даже если ядру нужно было де-фрагментировать память, чтобы удовлетворить запрос, разве оно не должно делать это автоматически, вместо того, чтобы отказаться и выполнить OOM?)

Я вставил пример OOM -призыв убийцы внизу, на случай, если он проливает свет на вещи. Я могу воспроизвести ошибку по своему желанию; этот вызов произошел, когда на компьютере все еще было доступно ~ 120 МБ ОЗУ (согласно free), в ответ на мою тестовую программу, выделяющую память, 10000 400-байтных распределений за раз.

May 28 18:51:34 g2 user.warn kernel: [ 4228.307769] cored invoked oom-killer: gfp_mask=0x2084d0, order=0, oom_score_adj=0
May 28 18:51:35 g2 user.warn kernel: [ 4228.315295] CPU: 2 PID: 19687 Comm: cored Tainted: G           O 3.10.53-1.1.1_ga+gf57416a #1
May 28 18:51:35 g2 user.warn kernel: [ 4228.323843] Backtrace:
May 28 18:51:35 g2 user.warn kernel: [ 4228.326340] [<c0011c54>] (dump_backtrace+0x0/0x10c) from [<c0011e68>] (show_stack+0x18/0x1c)
May 28 18:51:35 g2 user.warn kernel: [ 4228.334804]  r6:00000000 r5:00000000 r4:c9784000 r3:00000000
May 28 18:51:35 g2 user.warn kernel: [ 4228.340566] [<c0011e50>] (show_stack+0x0/0x1c) from [<c04d0dd8>] (dump_stack+0x24/0x28)
May 28 18:51:35 g2 user.warn kernel: [ 4228.348684] [<c04d0db4>] (dump_stack+0x0/0x28) from [<c009b474>] (dump_header.isra.10+0x84/0x19c)
May 28 18:51:35 g2 user.warn kernel: [ 4228.357616] [<c009b3f0>] (dump_header.isra.10+0x0/0x19c) from [<c009ba3c>] (oom_kill_process+0x288/0x3f4)
May 28 18:51:35 g2 user.warn kernel: [ 4228.367230] [<c009b7b4>] (oom_kill_process+0x0/0x3f4) from [<c009bf8c>] (out_of_memory+0x208/0x2cc)
May 28 18:51:35 g2 user.warn kernel: [ 4228.376323] [<c009bd84>] (out_of_memory+0x0/0x2cc) from [<c00a0278>] (__alloc_pages_nodemask+0x8f8/0x910)
May 28 18:51:35 g2 user.warn kernel: [ 4228.385921] [<c009f980>] (__alloc_pages_nodemask+0x0/0x910) from [<c00b6c34>] (__pte_alloc+0x2c/0x158)
May 28 18:51:35 g2 user.warn kernel: [ 4228.395263] [<c00b6c08>] (__pte_alloc+0x0/0x158) from [<c00b9fe0>] (handle_mm_fault+0xd4/0xfc)
May 28 18:51:35 g2 user.warn kernel: [ 4228.403914]  r6:c981a5d8 r5:cc421a40 r4:10400000 r3:10400000
May 28 18:51:35 g2 user.warn kernel: [ 4228.409689] [<c00b9f0c>] (handle_mm_fault+0x0/0xfc) from [<c0019a00>] (do_page_fault+0x174/0x3dc)
May 28 18:51:35 g2 user.warn kernel: [ 4228.418575] [<c001988c>] (do_page_fault+0x0/0x3dc) from [<c0019dc0>] (do_translation_fault+0xb4/0xb8)
May 28 18:51:35 g2 user.warn kernel: [ 4228.427824] [<c0019d0c>] (do_translation_fault+0x0/0xb8) from [<c00083ac>] (do_DataAbort+0x40/0xa0)
May 28 18:51:35 g2 user.warn kernel: [ 4228.436896]  r6:c0019d0c r5:00000805 r4:c06a33d0 r3:103ffea8
May 28 18:51:35 g2 user.warn kernel: [ 4228.442643] [<c000836c>] (do_DataAbort+0x0/0xa0) from [<c000e138>] (__dabt_usr+0x38/0x40)
May 28 18:51:35 g2 user.warn kernel: [ 4228.450850] Exception stack(0xc9785fb0 to 0xc9785ff8)
May 28 18:51:35 g2 user.warn kernel: [ 4228.455918] 5fa0:                                     103ffea8 00000000 b6d56708 00000199
May 28 18:51:35 g2 user.warn kernel: [ 4228.464116] 5fc0: 00000001 b6d557c0 0001ffc8 b6d557f0 103ffea0 b6d55228 10400038 00000064
May 28 18:51:35 g2 user.warn kernel: [ 4228.472327] 5fe0: 0001ffc9 beb04990 00000199 b6c95d84 600f0010 ffffffff
May 28 18:51:35 g2 user.warn kernel: [ 4228.478952]  r8:103ffea0 r7:b6d557f0 r6:ffffffff r5:600f0010 r4:b6c95d84
May 28 18:51:35 g2 user.warn kernel: [ 4228.485759] Mem-info:
May 28 18:51:35 g2 user.warn kernel: [ 4228.488038] DMA per-cpu:
May 28 18:51:35 g2 user.warn kernel: [ 4228.490589] CPU    0: hi:   90, btch:  15 usd:   5
May 28 18:51:35 g2 user.warn kernel: [ 4228.495389] CPU    1: hi:   90, btch:  15 usd:  13
May 28 18:51:35 g2 user.warn kernel: [ 4228.500205] CPU    2: hi:   90, btch:  15 usd:  17
May 28 18:51:35 g2 user.warn kernel: [ 4228.505003] CPU    3: hi:   90, btch:  15 usd:  65
May 28 18:51:35 g2 user.warn kernel: [ 4228.509823] active_anon:92679 inactive_anon:47 isolated_anon:0
May 28 18:51:35 g2 user.warn kernel: [ 4228.509823]  active_file:162 inactive_file:1436 isolated_file:0
May 28 18:51:35 g2 user.warn kernel: [ 4228.509823]  unevictable:0 dirty:0 writeback:0 unstable:0
May 28 18:51:35 g2 user.warn kernel: [ 4228.509823]  free:28999 slab_reclaimable:841 slab_unreclaimable:2103
May 28 18:51:35 g2 user.warn kernel: [ 4228.509823]  mapped:343 shmem:89 pagetables:573 bounce:0
May 28 18:51:35 g2 user.warn kernel: [ 4228.509823]  free_cma:29019
May 28 18:51:35 g2 user.warn kernel: [ 4228.541416] DMA free:115636kB min:1996kB low:2492kB high:2992kB active_anon:370716kB inactive_anon:188kB active_file:752kB inactive_file:6040kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:524288kB managed:2
May 28 18:51:35 g2 user.warn kernel: [ 4228.583833] lowmem_reserve[]: 0 0 0 0
May 28 18:51:35 g2 user.warn kernel: [ 4228.587577] DMA: 2335*4kB (UMC) 1266*8kB (UMC) 1034*16kB (UMC) 835*32kB (UC) 444*64kB (C) 28*128kB (C) 103*256kB (C) 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB 0*32768kB = 121100kB
May 28 18:51:35 g2 user.warn kernel: [ 4228.604979] 502 total pagecache pages
May 28 18:51:35 g2 user.warn kernel: [ 4228.608649] 0 pages in swap cache
May 28 18:51:35 g2 user.warn kernel: [ 4228.611979] Swap cache stats: add 0, delete 0, find 0/0
May 28 18:51:35 g2 user.warn kernel: [ 4228.617210] Free swap  = 0kB
May 28 18:51:35 g2 user.warn kernel: [ 4228.620110] Total swap = 0kB
May 28 18:51:35 g2 user.warn kernel: [ 4228.635245] 131072 pages of RAM
May 28 18:51:35 g2 user.warn kernel: [ 4228.638394] 30575 free pages
May 28 18:51:35 g2 user.warn kernel: [ 4228.641293] 3081 reserved pages
May 28 18:51:35 g2 user.warn kernel: [ 4228.644437] 1708 slab pages
May 28 18:51:35 g2 user.warn kernel: [ 4228.647239] 265328 pages shared
May 28 18:51:35 g2 user.warn kernel: [ 4228.650399] 0 pages swap cached
May 28 18:51:35 g2 user.info kernel: [ 4228.653546] [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
May 28 18:51:35 g2 user.info kernel: [ 4228.661408] [  115]     0   115      761      128       5        0         -1000 udevd
May 28 18:51:35 g2 user.info kernel: [ 4228.669347] [  237]     0   237      731       98       5        0         -1000 udevd
May 28 18:51:35 g2 user.info kernel: [ 4228.677278] [  238]     0   238      731      100       5        0         -1000 udevd
May 28 18:51:35 g2 user.info kernel: [ 4228.685224] [  581]     0   581     1134       78       5        0         -1000 sshd
May 28 18:51:35 g2 user.info kernel: [ 4228.693074] [  592]     0   592      662       15       4        0             0 syslogd
May 28 18:51:35 g2 user.info kernel: [ 4228.701184] [  595]     0   595      662       19       4        0             0 klogd
May 28 18:51:35 g2 user.info kernel: [ 4228.709113] [  633]     0   633     6413      212      12        0             0 g2d
May 28 18:51:35 g2 user.info kernel: [ 4228.716877] [  641]     0   641      663       16       3        0             0 getty
May 28 18:51:35 g2 user.info kernel: [ 4228.724827] [  642]     0   642      663       16       5        0             0 getty
May 28 18:51:35 g2 user.info kernel: [ 4228.732770] [  646]     0   646     6413      215      12        0             0 g2d
May 28 18:51:35 g2 user.info kernel: [ 4228.740540] [  650]     0   650    10791      572      10        0             0 avbd
May 28 18:51:35 g2 user.info kernel: [ 4228.748385] [  651]     0   651     9432     2365      21        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.756322] [  652]     0   652    52971     4547      42        0             0 g2d
May 28 18:51:35 g2 user.info kernel: [ 4228.764104] [  712]     0   712    14135     2458      24        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.772053] [  746]     0   746     1380      248       6        0             0 dhclient
May 28 18:51:35 g2 user.info kernel: [ 4228.780251] [  779]     0   779     9419     2383      21        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.788187] [  780]     0   780     9350     2348      21        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.796127] [  781]     0   781     9349     2347      21        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.804074] [  782]     0   782     9353     2354      21        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.812012] [  783]     0   783    18807     2573      27        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.819955] [  784]     0   784    17103     3233      28        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.827882] [  785]     0   785    13990     2436      24        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.835819] [  786]     0   786     9349     2350      21        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.843764] [  807]     0   807    13255     4125      25        0             0 cored
May 28 18:51:35 g2 user.info kernel: [ 4228.851702] [ 1492]   999  1492      512       27       5        0             0 avahi-autoipd
May 28 18:51:35 g2 user.info kernel: [ 4228.860334] [ 1493]     0  1493      433       14       5        0             0 avahi-autoipd
May 28 18:51:35 g2 user.info kernel: [ 4228.868955] [ 1494]     0  1494     1380      246       7        0             0 dhclient
May 28 18:51:35 g2 user.info kernel: [ 4228.877163] [19170]     0 19170     1175      131       6        0             0 sshd
May 28 18:51:35 g2 user.info kernel: [ 4228.885022] [19183]     0 19183      750       70       4        0             0 sh
May 28 18:51:35 g2 user.info kernel: [ 4228.892701] [19228]     0 19228      663       16       5        0             0 watch
May 28 18:51:35 g2 user.info kernel: [ 4228.900636] [19301]     0 19301     1175      131       5        0             0 sshd
May 28 18:51:35 g2 user.info kernel: [ 4228.908475] [19315]     0 19315      751       69       5        0             0 sh
May 28 18:51:35 g2 user.info kernel: [ 4228.916154] [19365]     0 19365      663       16       5        0             0 watch
May 28 18:51:35 g2 user.info kernel: [ 4228.924099] [19443]     0 19443     1175      153       5        0             0 sshd
May 28 18:51:35 g2 user.info kernel: [ 4228.931948] [19449]     0 19449      750       70       5        0             0 sh
May 28 18:51:35 g2 user.info kernel: [ 4228.939626] [19487]     0 19487     1175      132       5        0             0 sshd
May 28 18:51:35 g2 user.info kernel: [ 4228.947467] [19500]     0 19500      750       70       3        0             0 sh
May 28 18:51:35 g2 user.info kernel: [ 4228.955148] [19540]     0 19540      662       17       5        0             0 tail
May 28 18:51:35 g2 user.info kernel: [ 4228.963002] [19687]     0 19687    63719    56396     127        0             0 cored
May 28 18:51:35 g2 user.err kernel: [ 4228.970936] Out of memory: Kill process 19687 (cored) score 428 or sacrifice child
May 28 18:51:35 g2 user.err kernel: [ 4228.978513] Killed process 19687 (cored) total-vm:254876kB, anon-rss:225560kB, file-rss:24kB

Также вот моя тестовая программа, которую я использую, чтобы нагружать систему и вызывать OOM-killer (с командой echo 1 > /proc/sys/vm/compact_memory, запускаемой так часто, OOM-killer появляется, когда free сообщает, что системная RAM близка к нулю, как и ожидалось; без него OOM-убийца появляется задолго до этого, когда free сообщает о наличии 130+ МБ ОЗУ, но после того, как cat /proc/buddyinfo показывает, что ОЗУ становится фрагментированным):

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
  while(1)
  {
     printf("PRESS RETURN TO ALLOCATE BUFFERS\n");
     const int numBytes = 400;
     char buf[64]; fgets(buf, sizeof(buf), stdin);
     for (int i=0; i<10000; i++)
     {
        void * ptr = malloc(numBytes); // yes, a deliberate memory leak
        if (ptr)
        {
           memset(ptr, 'J', numBytes);  // force the virtual memory system to actually allocate the RAM, and not only the address space
        }
        else printf("malloc() failed!\n");
     }
     fprintf(stderr, "Deliberately leaked 10000*%i bytes!\n", numBytes);
  }
  return 0;
}

1 Ответ

2 голосов
/ 04 сентября 2020

Ты на правильном пути, Джереми. То же самое случилось со мной на моей настольной системе CentOS. Я компьютерный консультант, и я работаю с Linux с 1995 года. Я безжалостно забиваю свои системы Linux, загружая множество файлов и занимаясь другими видами деятельности, которые доводят их до предела. После того, как мой основной рабочий стол проработал около 4 дней, он стал очень медленным (например, медленнее, чем 1/10 от нормальной скорости), сработало отключение OOM, и я сидел, задаваясь вопросом, почему моя система работает таким образом. У него было много оперативной памяти, но убийца OOM работал, когда ему нечего было делать. Итак, я перезагрузил его, и он работал нормально ... около 4 дней, затем проблема вернулась. Вытащил из меня сопли, не зная почему.

Поэтому я надел шляпу инженера-испытателя и провел на машине всевозможные стресс-тесты, чтобы проверить, смогу ли я воспроизвести симптомы намеренно. После нескольких месяцев этого я смог воссоздать проблему по своему желанию и доказать, что мое решение для нее будет работать каждый раз.

«Оборот кеша» в этом контексте - это когда система должна удалить существующий кеш для создания большего объема кеш-памяти для поддержки записи новых файлов. Поскольку система спешит с повторным развертыванием ОЗУ, не требуется времени для дефрагментации освобождаемой памяти. Таким образом, со временем, по мере того, как происходит все больше и больше операций записи файлов, кеш постоянно обновляется. И память, в которой он находится, становится все более и более фрагментированной. В своих тестах я обнаружил, что после того, как кеш диска перевернулся примерно 15 раз, память становится настолько фрагментированной, что система не может разорвать, а затем выделить память достаточно быстро, чтобы предотвратить запуск убийцы OOM из-за отсутствия свободной оперативной памяти. в системе, когда происходит всплеск потребности в памяти. Такой всплеск может быть вызван выполнением чего-то столь же простого, как

find /dev /etc /home /opt /tmp /usr -xdev > /dev/null

. В моей системе эта команда создает потребность примерно в 50 МБ нового кеша. Во всяком случае, это именно то, что показывает

free -mt 

.

Решение этой проблемы включает расширение того, что вы уже обнаружили.

/bin/echo 3 > /proc/sys/vm/drop_caches
export CONFIG_COMPACTION=1
echo 1 > /proc/sys/vm/compact_memory

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

Если вы настроили задание cron для выполнения те, что раз в день, должны устранить вашу проблему убийцы OOM. Если после этого вы все еще видите проблемы с OOM killer, рассмотрите возможность их более частого выполнения. Он будет варьироваться в зависимости от того, сколько файлов вы записываете по сравнению с объемом оперативной памяти вашего устройства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...