No kernel do Linux de 64 bits, quanta memória é mapeada de forma contígua pelo kernel?

Aug 21 2020

Examinei o Linux Kernel Development de Robert Love e outras fontes. E em todos os lugares ele menciona que em um sistema x86 de 32 bits o kernel possui o topo de 1 GB do espaço de endereço virtual, dos quais até 896 MB são mapeados de forma contígua na memória física (chamada ZONE_NORMAL) o resto é mapeado nos 128 MB restantes conforme necessário e não pode ser contíguo (ZONE_HIGHMEM).

Em 64 bits, o problema de não ter espaço de endereço virtual suficiente é eliminado. E o mapa de memória é descrito como,

0xffffffffffffffff  +-----------+
                    |           |
                    |           | Kernelspace
                    |           |
0xffff800000000000  +-----------+
                    |           |
                    |           |
                    |   hole    |
                    |           |
                    |           |
0x00007fffffffffff  +-----------+
                    |           |
                    |           |  Userspace
                    |           |
0x0000000000000000  +———————————+

No entanto, não está claro, neste mapa, quanto do espaço do kernel deve ser fisicamente contíguo (conforme definido em ZONE_NORMAL). e quanto é mapeado conforme necessário.

ZONE_HIGHMEM no kernel de 64 bits é sempre 0? Uma vez que toda a memória está dentro do alcance do espaço de endereço virtual?

Mas a memória contígua fixa do kernel (que não é paginável) também precisaria ser pequena, uma vez que esse pedaço de memória física nunca estaria disponível para outros processos do usuário. Portanto, o kernel requereria o uso de memória que não precisa ser contígua (como ZONE_HIGHMEM), conforme necessário. Isso entra em conflito com o ZONE_HIGHMEM sendo vazio em kernels de 64 bits.

Portanto, estou confuso sobre quanto do espaço do kernel é fixo fisicamente contíguo e quanto é não contíguo no caso de kernels de 64 bits.

Respostas

2 StephenKitt Aug 21 2020 at 11:44

Não há HIGHMEMno x86 de 64 bits - CONFIG_HIGHMEMdependeX86_32 .

Existem dois mapeamentos fixos de memória física em x86 de 64 bits :

ffff888000000000 | -119.5  TB | ffffc87fffffffff |   64 TB | direct mapping of all physical memory (page_offset_base)

e a área começando em

ffffffff80000000 |   -2    GB | ffffffff9fffffff |  512 MB | kernel text mapping, mapped to physical address 0

(endereços negativos são deslocamentos do final do espaço de endereço).

Este último corresponde ao que você está pensando, pelo que eu posso dizer, e tende a ser pequeno; veja a linha “Memória” mostrada durante a inicialização:

Memory: 20144992K/20660008K available (14339K kernel code, 2406K rwdata, 8340K rodata, 2488K init, 5116K bss, 515016K reserved, 0K cma-reserved)

(pouco menos de 30 MiB) e qualquer memória bloqueada por módulos carregados posteriormente.