amarao (amarao_san) wrote,
amarao
amarao_san

The Kernel (part5)

Продолжаем отладку происходящего.

Текущая ситуация (предыдущие чаптеры): Наши герои обнаружили страшный заговор и пытаются найти мастермайнд заговора.

Суть: При выключенном балунинге

Memory: 223500k/262144k available (3675k kernel code, 448k absent, 38196k reserved, 5084k data, 660k init)

38Мб пропадает в неизвестном направлении.

Предположение, что memblock_reserve - это оно не оправдывается, сумма всех memblock_reserve не сходится.

Кстати, вот программа для подсчёта:

dmesg |grep -i memblock_reserve|awk '{print $4}'|tr '[' ' '|tr ']' ' '|awk -F - '{a=a+($2-$1)}END {print a}'

И у меня она выводит 16336354 (что само по себе подозрительно, но явно меньше 38,1Мб).


При этом мы точно знаем, каким образом определяются цифры из вывода Memory: 223500k/262144k

При вызове free_all_bootmem для всех NUMA-nodes (в нашем случае, 1) вызывается reset_node_lowmem_managed_pages, а потом возвращается результат free_low_memory_core_early, это и становится величиной totalram_pages.

Дальше у нас reserved высчитывается как max_pfn (правильная величина в 256Мб) минус totalrampages.

Таким образом, что-то странное происходит в free_low_memory_core_early.

Пропуская лишнее, вся магия творится тут:

for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL){
t=__free_memory_core(start, end);
count +=t;
printk(KERN_ERR "free_low_memory_core_early: start=%lu, end=%lu, __free_memory_core(start, end)=%lu, count=%lu\n", (long unsigned) start, (long unsigned)end,t,count);



Вот вывод:

[ 0.000000] free_low_memory_core_early: start=65536, end=630784, __free_memory_core(start, end)=138, count=138
[ 0.000000] free_low_memory_core_early: start=1048576, end=16777216, __free_memory_core(start, end)=3840, count=3978
[ 0.000000] free_low_memory_core_early: start=27643904, end=31371264, __free_memory_core(start, end)=910, count=4888
[ 0.000000] free_low_memory_core_early: start=31780864, end=31903744, __free_memory_core(start, end)=30, count=4918
[ 0.000000] free_low_memory_core_early: start=54112256, end=54636544, __free_memory_core(start, end)=128, count=5046
[ 0.000000] free_low_memory_core_early: start=54648832, end=54661120, __free_memory_core(start, end)=3, count=5049
[ 0.000000] free_low_memory_core_early: start=54775808, end=134217664, __free_memory_core(start, end)=19394, count=24443
[ 0.000000] free_low_memory_core_early: start=134217728, end=253755392, __free_memory_core(start, end)=29184, count=53627
[ 0.000000] free_low_memory_core_early: start=257949696, end=260026368, __free_memory_core(start, end)=507, count=54134
[ 0.000000] free_low_memory_core_early: start=260042752, end=264241152, __free_memory_core(start, end)=1025, count=55159
[ 0.000000] free_low_memory_core_early: start=264355840, end=267290816, __free_memory_core(start, end)=716, count=55875
[ 0.000000] free_low_memory_core_early: start=267684624, end=267684672, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267684680, end=267684736, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267684740, end=267684800, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267684808, end=267684864, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267684872, end=267684928, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267693247, end=267693248, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267693375, end=267693376, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267693408, end=267693440, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267693544, end=267693568, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267693672, end=267693696, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267693800, end=267693824, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early: start=267694048, end=267694080, __free_memory_core(start, end)=0, count=55875
[ 0.000000] free_low_memory_core_early, size=0

Таким образом, мы видим, что count действительно становится равен нашему MemTotal, то есть проблема в for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL), список each_free_mem_range не содержит всех страниц.

Это был пересказ предыдущих серий. Теперь начинаем новое. Посмотрим на memblock отладку не с точки зрения reserved, а с точки зрения free.

Вызов авкового скрипта с грепом по memblock_free навевает уныние - там всего 10903552.

[ 0.000000] memblock_free: [0x0000000f600000-0x0000000f600000] sparse_mem_maps_populate_node+0xe9/0x12a
[ 0.000000] memblock_free: [0x0000000f7ff000-0x0000000fbff000] sparse_init+0x206/0x246
[ 0.000000] memblock_free: [0x0000000fbff000-0x0000000ffff000] paging_init+0x10/0x16
[ 0.000000] memblock_free: [0x0000000339b000-0x0000000341b000] xen_pagetable_init+0xc5/0x1d3
[ 0.000000] memblock_free: [0x0000000fc1c000-0x0000000fe00000] pcpu_embed_first_chunk+0x181/0x296
[ 0.000000] memblock_free: [0x0000000ff49c40-0x0000000ff4ac40] pcpu_embed_first_chunk+0x26b/0x296
[ 0.000000] memblock_free: [0x0000000ff48c40-0x0000000ff49c40] pcpu_embed_first_chunk+0x285/0x296

Таким образом, проблема в том, что часть памяти не была помечена как free в списке, по которому итерирует for_each_free_mem_range.

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

http://lxr.free-electrons.com/source/mm/memblock.c#L587

(to be continued, для того, чтобы быть совсем добрым, буду дописывать в этот пост).
Tags: linux kernel
Subscribe

  • Вид со стороны Sacré-Cœur

    ЗЫ Обратите внимание на количество ржавых крыш.

  • Лувр

    Весь Лувр просто набит людьми, которые перерисовывают картины. Большая часть из них увешана табличками "не фотографировать", но этот, видимо,…

  • (no subject)

    Тродосовское (в рамках программы "каждый день по равке").

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 0 comments