Что показывают vm.kvm_size и vm.kmem_size?
- Bot
- 13.11.2020
- 2 800
- 0
- 10.01.2021
- 1
- 1
- 0
- Содержание статьи
Описание
Такой вопрос обычно возникает вслед за желанием оптимизировать распределение памяти в ядре.
Для начала стоит понять, как в общем выглядит виртуальное адресное пространство FreeBSD. В его нижней части расположен текущий процесс, а верхнюю всегда занимает ядро. Отрезок виртуального адресного пространства, занятый ядром, -- kernel virtual memory (KVM) он же kernel virtual address space (KVA) -- ограничен адресами KERNBASE снизу и VM_MAX_KERNEL_ADDRESS сверху. Эти величины меняются только от платформы к платформе, а vm.kvm_size возвращает их разность:
vm.kvm_size = VM_MAX_KERNEL_ADDRESS - KERNBASE
На живой машине ядро фиксирует конец используемой части KVM в переменной ядра kernel_vm_end. Отрезок от kernel_vm_end до VM_MAX_KERNEL_ADDRESS и есть свободная часть KVM:
vm.kvm_free = VM_MAX_KERNEL_ADDRESS - kernel_vm_end
Очевидно, что переменные vm.kvm_size и vm.kvm_free чисто информационные, настраивать их нельзя.
В KVM есть участок, который ядро использует для динамического распределения памяти посредством malloc(9) и zone(9). Длина этого участка вычисляется при загрузке системы по формуле:
vm.kmem_size = min(max(max(VM_KMEM_SIZE, Physical_memory / VM_KMEM_SIZE_SCALE), VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX)
Выглядит жутковато, но суть простая: vm.kmem_size_{min,max} задает диапазон для автонастройки, которая сводится к выбору большего из VM_KMEM_SIZE (это #define) и ОЗУ / vm.kmem_size_scale.
Также можно жестко указать vm.kmem_size из loader.conf. Наконец, при любых настройках kmem_size не может быть более двух размеров ОЗУ.
Обратите внимание, что kmem -- это участок виртуального адресного пространства, а не физической памяти. Именно поэтому ядро может упасть в панику "kmem_map too small", хотя ОЗУ еще в избытке, если какая-то из подсистем ядра пытается выделить слишком много памяти для своих нужд. Типичный пример этого -- виртуальный диск, созданный с помощью "mdmfs -M".
Добавить комментарий