Motivação
Eu escrevi uma resposta aqui: Qual é o tamanho das reservas de memória de "marca d'água" no meu sistema? A marca d'água "min" para a zona "Normal" apareceu como 31449 páginas. Isso é 125796 KiB - maior que o meu inteiro min_free_kbytes
(67584).
A redefinição min_free_kbytes
define a min
marca d'água desta zona para um nÃvel esperado (por exemplo, 9582 páginas). Mas depois de um tempo, ele volta para o nÃvel superior.
Estou confiante de que isso se deve a boost_watermark() . Aumenta as marcas d'água "min", "low" e "high" na mesma quantidade . watermark_boost_factor é 15000, então o aumento máximo deve ser 150% da marca d'água "alta" original...
Pergunta
Por que minha marca d'água "alta" é tão alta em primeiro lugar? (e também a marca d'água "baixa"):
Como meu watermark_scale_factor é 10, a distância entre "min", "low" e "high" deve ser de apenas 0,1% do tamanho da zona. Mas se eu olhar imediatamente após a redefinição min_free_kbytes
, a diferença entre "min" e "low" é de 2% do tamanho da zona. Por quê?
(Também a diferença entre "baixo" e "alto" é de 0,2% do tamanho da zona. Portanto, isso também não é o que esperamos!).
O código que eu pensei que configura as marcas d'água está em __setup_per_zone_wmarks() .
Versão do kernel: 5.0.17-200.fc29.x86_64
De /proc/zoneinfo
:
Node 0, zone Normal
pages free 74597
min 9582
low 34505
high 36900
spanned 1173504
present 1173504
managed 1140349
Não vejo essa enorme discrepância na zona DMA32. Também não parece que a marca d'água "min" seja aumentada na zona DMA32, talvez porque o kernel prefira alocar da zona "Normal".
Node 0, zone DMA
...
pages free 3961
min 33
low 41
high 49
spanned 4095
present 3996
managed 3961
...
Node 0, zone DMA32
pages free 334671
min 7280
low 9100
high 10920
spanned 1044480
present 888973
managed 866356
Descobri por que a distância entre as marcas d'água não correspondia ao número de 0,1%.
Em "sistemas pequenos", a distância entre as marcas d'água é um quarto da marca d'água "min" (não reforçada). Ou seja, a distância documentada
managed * watermark_scale_factor / 10000
não é usada, se for menor quemin / 4
(para uma determinada zona).tmp >> 2
é equivalente atmp / 4
.Link do código-fonte: linux-5.0.17/mm/page_alloc.c:7531
Eu também notei que havia um bug recente aqui. Não deve haver uma diferença entre "high-low" e "low-min"! Isso pode acontecer porque
min_wmark_pages(zone)
depende dezone->watermark_boost
ter sido definido, mas é chamado antes que isso aconteça. Eu relatei o bug para os mantenedores.