- Memory management в ядре Linux. Семинар в Яндексе
- Задачи подсистемы управления памятью и компоненты, из которых она состоит
- Аппаратные возможности платформы x86_64
- Как описывается в ядре физическая и виртуальная память?
- API подсистемы управления памятью
- Высвобождение ранее занятой памяти (memory reclaim)
- Модель «LRU»
- Инструменты мониторинга
- Memory cgroups
- Информация об оперативной памяти в Linux. Свободная, занятая и тип памяти
- Свободная и занятая оперативная память
- Команда free
- Команда vmstat
- Команда top
- Команда htop
- Файл /proc/meminfo
- Тип памяти и частота
- Заключение
- Memory mapping¶
- Lab objectives¶
- Overview¶
- Structures used for memory mapping¶
- struct page ¶
- struct vm_area_struct ¶
- struct mm_struct ¶
- Device driver memory mapping¶
Memory management в ядре Linux. Семинар в Яндексе
Привет! Меня зовут Роман Гущин. В Яндексе я занимаюсь ядром Linux. Некторое время назад я провел для системных администраторов семинар, посвященный общему описанию подсистемы управления памятью в Linux, а также некоторым проблемам, с которыми мы сталкивались, и методам их решения. Большая часть информации описывает «ванильное» ядро Linux (3.10), но некоторая часть специфична для ядра, использующегося в Яндексе. Вполне возможно, семинар окажется интересен не только системным администраторам, но и всем, кто хочет узнать, как в Linux устроена работа с памятью.
Основные темы, затронутые на семинаре:
- Задачи и компоненты подсистемы управления памятью;
- Аппаратные возможности платформы x86_64;
- Как описывается в ядре физическая и виртуальная память;
- API подсистемы управления памятью;
- Высвобождение ранее занятой памяти;
- Инструменты мониторинга;
- Memory Cgroups;
- Compaction — дефрагментация физической памяти.
Под катом вы найдете более подробный план доклада с раскрытием основных понятий и принципов.
Задачи подсистемы управления памятью и компоненты, из которых она состоит
Основная задача подсистемы — выделение физической памяти ядру и userspace-процессам, а также высвобождение и перераспределение в тех случаях, когда вся память занята.
Основные компоненты:
- Buddy allocator занимается менеджментом пула свободной памяти.
- Page replacent («LRU» reclaim model) решает, у кого отобрать память, когда закончилась свободная.
- PTE management — блок управления таблицами трансляции.
- Slub kernel allocator — внутренний ядерный аллокатор.
- и др.
Аппаратные возможности платформы x86_64
Схема NUMA подразумевает, что к каждому физическому процессору присоединен некоторый объем памяти, к которому он может обращаться быстрее всего. Обращение к участкам памяти других процессоров происходит значительно медленнее.
Как описывается в ядре физическая и виртуальная память?
Физическая память в ядре описывается тремя структурами: ноды (pg_data_t), зоны (struct zone), страницы (struct page). Виртуальная память у каждого процесса своя и описывается при помощи структуры struct mm_struct. Они, в свою очередь, делятся на регионы (struct vm_area_struct).
API подсистемы управления памятью
Ядро взаимодействует с подсистемой memory management при помощи таких функцций функций, как __get_free_page(), kmalloc(), kfree(), vmalloc(). Они отвечают за выделение свободных страниц, больших и малых участков памяти, а также их высвобождение. Существует целое семейство подобных функций, отличающихся небольшими особенностями, например, будет ли занулена область при высвобождении.
Пользовательские программы взаимодействуют с mm-подсистемой при помощи функций mmap(), munmap(), brk(), mlock(), munlock(). Также есть функции posix_fadvice() и madvice(), которые могут давать ядру «cоветы». Но учитывать их в своих эвристиках оно строго говоря не обязано.
Высвобождение ранее занятой памяти (memory reclaim)
Система всегда старается поддерживать некоторый объем свободной памяти (free pool). Таким образом, память выделяется гораздо быстрее, т.к. не приходится высвобождать ее в тот момент, когда она уже действительно нужна.
Те страницы в памяти, которые используются постоянно (системные библиотеки и т.п), называются working set. Вытеснение их из памяти приводит к замедлению работы всей системы. Общая скорость потребления памяти в системе называется memory pressure. Эта величина может очень сильно колебаться в зависимости от того, насколько загружена система.
Всю незанятую ядром память в системе можно поделить на две части: анонимная память и файловая. Отличаются они тем, что про первую мы точно знаем, что каждый ее кусок соответствует какому-либо файлу, и его можно туда сбросить.
Модель «LRU»
LRU расшифровывается как least recently used. Это абстракция, которая предлагает выкидывать страницы, к которым мы дольше всего не обращались. Реализовать ее в Linux полноценно невозможно, т.к. все что нам известно — было ли когда-либо обращение к той или иной странице. Чтобы как-то отслеживать частоту обращений к страницам используются списки active, inactive и unevictable. В последнем находятся залоченные пользователем страницы, которые не будут выбрасываться из памяти ни при каких условиях.
Существуют четкие правила перемещения между списками inactive и active. Под воздействием memory pressure, страницы из неактивного списка могут быть либо выброшены из памяти, либо перейти в активный. Страницы из активного списка перемещаются в неактивный, если к ним давно не было обращений.
Инструменты мониторинга
Утилита top демонстрирует статистику потребления памяти в системе. Програмка vmtouch — показывает какая часть определенного файла находится в памяти. Исчерпывающую информацию по количеству файловых, активных и неактивных страниц можно найти в /proc/vmstat. Статистика buddy allocator есть в /proc/buddyinfo, а статистика slub allocator, соответственно, в /proc/slabinfo. Часто бывает полезно посмотреть на perf top, где отлично видны все проблемы с фрагментацией.
Memory cgroups
Сигруппы зародились из желания выделить группу из нескольких процессов, объединить их логически и ограничить их суммарное потребление памяти определенным. При этом, если они достигнут своего лимита, память должна высвобождаться именно из выделенного им объема. В этом случае нужно освободить память, принадлежащую именно этой сигруппе (это называется target reclaim). Если в системе просто закончилась память и нужно пополнить free pool — это называется global reclaim. C точки зрения аккаунтинга каждая страница принадлежит только одной сигруппе: той, которая ее первой прочитала.
Источник
Информация об оперативной памяти в Linux. Свободная, занятая и тип памяти
В этой статье мы рассмотрим, как получить информацию об оперативной памяти (RAM) в Linux.
Мы воспользуемся утилитами командной строки доступными для большинства Linux дистрибутивов.
Свободная и занятая оперативная память
Для получения информации о количестве свободной и занятой оперативной памяти в Linux можно использовать различные утилиты и команды. Рассмотрим несколько распространенных способов.
Команда free
Команда free очень простая, она выводит информацию о общем количестве оперативной памяти, о количестве занятой и свободной памяти, а также об использовании файла подкачки.
По умолчанию объем памяти выводится в килобайтах. Используя опции, можно выводить объем памяти в других форматах. Некоторые опции:
- -m — в мегабайтах
- -g — в гигабайтах
- -h — автоматически определить формат
Команда vmstat
Команда vmstat выводит различную статистику по использованию памяти. Используя ключ -s можно вывести подробную статистику в табличном виде.
Команда top
top — это утилита командной строки, которая используется для мониторинга процессов и используемых ресурсов компьютера.
Запуск утилиты top :
В заголовке выводится информация об использованной оперативной памяти.
Команда htop
Утилита htop, также как и top, используется для мониторинга ресурсов и процессов.
Для установки утилиты htop в Ubuntu Linux (Linux Mint и других Ubuntu/Debian-дистрибутивах) выполните команду:
Запуск утилиты htop :
Файл /proc/meminfo
Описанные выше команды, в качестве источника информации используют системные файлы из файлов, хранящихся в виртуальной файловой системе /proc . В файле /proc/meminfo содержится информация об использовании памяти. Выведем содержимое файла /proc/meminfo :
Тип памяти и частота
Рассмотрим, как получить информацию об установленных в компьютер модулях оперативной памяти. Воспользуемся командной dmidecode
Используем следующую команду:
В выводе команды будет информация о слотах оперативной памяти. Для каждого слота отображается установленный модуль оперативной памяти, его тип (поле Type ), размер (поле Size ), скорость/частота (поле Speed ) и другая информация.
В зависимости от системы и оборудования не всегда удается получить все данные, поэтому некоторые поля могут быть пустыми или иметь надписи Not provided/Unknown.
Заключение
Мы рассмотрели различные способы для просмотра информации о доступной и занятой оперативной памяти, а также показали, как вывести информацию об установленных модулях оперативной памяти.
Для отслеживания использования ресурсов компьютера существует множество графических программ. Найти их можно в нашем каталоге программ для Linux в разделе Система/Мониторинг.
Источник
Memory mapping¶
Lab objectives¶
- Understand address space mapping mechanisms
- Learn about the most important structures related to memory management
- address space
- mmap()
- struct page
- struct vm_area_struct
- struct vm_struct
- remap_pfn_range
- SetPageReserved()
- ClearPageReserved()
Overview¶
In the Linux kernel it is possible to map a kernel address space to a user address space. This eliminates the overhead of copying user space information into the kernel space and vice versa. This can be done through a device driver and the user space device interface ( /dev ).
This feature can be used by implementing the mmap() operation in the device driver’s struct file_operations and using the mmap() system call in user space.
The basic unit for virtual memory management is a page, which size is usually 4K, but it can be up to 64K on some platforms. Whenever we work with virtual memory we work with two types of addresses: virtual address and physical address. All CPU access (including from kernel space) uses virtual addresses that are translated by the MMU into physical addresses with the help of page tables.
A physical page of memory is identified by the Page Frame Number (PFN). The PFN can be easily computed from the physical address by dividing it with the size of the page (or by shifting the physical address with PAGE_SHIFT bits to the right).
For efficiency reasons, the virtual address space is divided into user space and kernel space. For the same reason, the kernel space contains a memory mapped zone, called lowmem, which is contiguously mapped in physical memory, starting from the lowest possible physical address (usually 0). The virtual address where lowmem is mapped is defined by PAGE_OFFSET .
On a 32bit system, not all available memory can be mapped in lowmem and because of that there is a separate zone in kernel space called highmem which can be used to arbitrarily map physical memory.
Memory allocated by kmalloc() resides in lowmem and it is physically contiguous. Memory allocated by vmalloc() is not contiguous and does not reside in lowmem (it has a dedicated zone in highmem).
Structures used for memory mapping¶
Before discussing the mechanism of memory-mapping a device, we will present some of the basic structures related to the memory management subsystem of the Linux kernel.
Before discussing about the memory mapping mechanism over a device, we will present some of the basic structures used by the Linux memory management subsystem. Some of the basic structures are: struct page , struct vm_area_struct , struct mm_struct .
struct page ¶
struct page is used to embed information about all physical pages in the system. The kernel has a struct page structure for all pages in the system.
There are many functions that interact with this structure:
- virt_to_page() returns the page associated with a virtual address
- pfn_to_page() returns the page associated with a page frame number
- page_to_pfn() return the page frame number associated with a struct page
- page_address() returns the virtual address of a struct page ; this functions can be called only for pages from lowmem
- kmap() creates a mapping in kernel for an arbitrary physical page (can be from highmem) and returns a virtual address that can be used to directly reference the page
struct vm_area_struct ¶
struct vm_area_struct holds information about a contiguous virtual memory area. The memory areas of a process can be viewed by inspecting the maps attribute of the process via procfs:
A memory area is characterized by a start address, a stop address, length, permissions.
A struct vm_area_struct is created at each mmap() call issued from user space. A driver that supports the mmap() operation must complete and initialize the associated struct vm_area_struct . The most important fields of this structure are:
- vm_start , vm_end — the beginning and the end of the memory area, respectively (these fields also appear in /proc/
/maps );
struct mm_struct ¶
struct mm_struct encompasses all memory areas associated with a process. The mm field of struct task_struct is a pointer to the struct mm_struct of the current process.
Device driver memory mapping¶
Memory mapping is one of the most interesting features of a Unix system. From a driver’s point of view, the memory-mapping facility allows direct memory access to a user space device.
To assign a mmap() operation to a driver, the mmap field of the device driver’s struct file_operations must be implemented. If that is the case, the user space process can then use the mmap() system call on a file descriptor associated with the device.
The mmap system call takes the following parameters:
To map memory between a device and user space, the user process must open the device and issue the mmap() system call with the resulting file descriptor.
The device driver mmap() operation has the following signature:
The filp field is a pointer to a struct file created when the device is opened from user space. The vma field is used to indicate the virtual address space where the memory should be mapped by the device. A driver should allocate memory (using kmalloc() , vmalloc() , alloc_pages() ) and then map it to the user address space as indicated by the vma parameter using helper functions such as remap_pfn_range() .
remap_pfn_range() will map a contiguous physical address space into the virtual space represented by vm_area_struct :
remap_pfn_range() expects the following parameters:
- vma — the virtual memory space in which mapping is made;
- addr — the virtual address space from where remapping begins; page tables for the virtual address space between addr and addr + size will be formed as needed
- pfn — the page frame number to which the virtual address should be mapped
- size — the size (in bytes) of the memory to be mapped
- prot — protection flags for this mapping
Here is an example of using this function that contiguously maps the physical memory starting at page frame number pfn (memory that was previously allocated) to the vma->vm_start virtual address:
To obtain the page frame number of the physical memory we must consider how the memory allocation was performed. For each kmalloc() , vmalloc() , alloc_pages() , we must used a different approach. For kmalloc() we can use something like:
Источник