Интерфейс слябового распределителя памяти

Интерфейс слябового распределителя памяти

Новый кэш можно создать с помощью вызова следующей функции.

kmem_cache_t * kmem_cache_create(const char *name, size_t size,

 size_t offset, unsigned long flags,

void (*ctor)(void*, kmem_cache_t*, unsigned long),

void (*dtor)(void*, kmem_cache_t*, unsigned long));

Первый параметр — это строка, которая содержит имя кэша. Второй параметр — это размер каждого элемента кэша. Третий параметр — это смещение первого объекта в слябе. Он нужен для того, чтобы обеспечить необходимое выравнивание по границам страниц памяти. Обычно достаточно указать значение, равное нулю, которое соответствует выравниванию по умолчанию. Параметр flags указывает опциональные параметры, которые управляют поведением кэша. Он может быть равен нулю, что выключает все специальные особенности поведения, или состоять из одного или более значений, показанных ниже и объединенных с помощью логической операции ИЛИ.

• SLAB_NO_REAP — этот флаг указывает, что кэш не должен автоматически "убирать мусор" (т.е. освобождать память, в которой хранятся неиспользуемые объекты) при нехватке памяти в системе. Обычно этот флаг не нужно устанавливать, поскольку если этот флаг установлен, то созданный кэш может помешать нормальной работе системы при нехватке памяти.

• SLAB_HWCACHE_ALIGN — этот флаг указывает уровню слябового распределения памяти, что расположение каждого объекта в слябе должно выравниваться по строкам процессорного кэша. Это предотвращает так называемое "ошибочное распределение", когда два или более объектов отображаются в одну и ту же строку системного кэша, несмотря на то что они находятся по разным адресам памяти. При использовании этого флага возрастает производительность, но это делается ценой увеличения занимаемой памяти, потому что строгое выравнивание приводит к тому, что часть памяти сляба не используется. Степень увеличения занимаемой памяти зависит от размера объектов кэша и от того, каким образом происходит их выравнивание по отношению к строкам системного кэша. Для кэшей, которые часто используются в коде, критичном к производительности, будет правильным установить этот флаг, в остальных случаях следует подумать, стоит ли это делать.

• SLAB_MUST_HWCACHE_ALIGN. Если включен режим отладки, то может оказаться невозможным одновременная отладка и выравнивание положения объектов по строкам системного кэша. Этот флаг указывает уровню слябового распределения памяти, что необходимо форсировать выравнивание положения объектов по строкам системного кэша. В обычной ситуации этот флаг указывать необязательно, и достаточно использовать предыдущий. Установка этого флага в режиме отладки слябового распределителя памяти (по умолчанию отладка запрещена) может привести к значительному увеличению затрат памяти. Только для объектов, которые критичны к выравниванию по строкам системного кэша, таких как дескрипторы процессов, необходимо указывать данный флаг.

• SLAB_POISON — этот флаг указывает на необходимость заполнения слябов известным числовым значением (a5a5a5a5). Эта операция называется "отравлением" (poisoning) и служит для отслеживания доступа к неинициализированной памяти.

• SLAB_RED_ZONE — этот флаг указывает на необходимость выделения так называемых "красных зон" (red zone) для облегчения детектирования переполнений буфера.

• SLAB_PANIC — этот флаг указывает на необходимость перевода ядра в состояние паники, если выделение памяти было неудачным. Данный флаг полезен, если выделение памяти всегда должно завершаться успешно, как, например, в случае создания кэша структур VMA (областей виртуальной памяти, см. главу 14, "Адресное пространство процесса") при загрузке системы.

• SLAB_CACHE_DMA — этот флаг указывает уровню слябового распределения, что все слябы должны выделяться в памяти, с которой возможны операции прямого доступа к памяти. Это необходимо, когда объекты используются в операциях ПДП и должны находиться в зоне ZONE_DMA. В противном случае эта возможность не нужна и этот флаг не нужно устанавливать.

Два последних параметра ctor и dtor — это конструктор и деструктор кэша соответственно. Конструктор вызывается, когда в кэш добавляются новые страницы памяти. Деструктор вызывается, когда из кэша удаляются страницы памяти. Если указан деструктор, то должен быть указан и конструктор. На практике кэши ядра ОС Linux обычно не используют функции конструктора и деструктора. В качестве этих параметров можно указывать значение NULL.

В случае успешного выполнения функция kmem_cache_create() возвращает указатель на созданный кэш. В противном случае возвращается NULL. Данная функция не может вызываться в контексте прерывания, так как она может переводить процесс в состояние ожидания. Для ликвидации кэша необходимо вызвать следующую функцию.

int kmem_cache_destroy(kmem_cache_t *cachep);

Эта функция ликвидирует указанный кэш. Она обычно вызывается при выгрузке модуля, который создает свой кэш. Из контекста прерывания эту функцию вызывать нельзя, так как она может переводить вызывающий процесс в состояние ожидания. Перед вызовом этой функции необходимо, чтобы были выполнены следующие два условия.

• Все слябы кэша являются пустыми. Действительно, если в каком-либо слябе существует объект, который все еще используется, то как можно ликвидировать кэш?

• Никто не будет обращаться к кэшу во время и особенно после вызова функции kmem_cache_destroy(). Эту синхронизацию должен обеспечить вызывающий код.

В случае успешного выполнения функция возвращает нуль, в других случаях возвращается ненулевое значение.

После того как кэш создан, из него можно получить объект путем вызова следующей функции.

void* kmem_cache_alloc(kmem_cache_t *cachep, int flags);

Эта функция возвращает указатель на объект из кэша, на который указывает параметр cachep. Если ни в одном из слябов нет свободных объектов, то уровень слябового распределения должен получить новые страницы памяти с помощью функции kmem_getpages(), значение параметра flags передается в функцию __get_free_pages(). Это те самые флаги, которые были рассмотрены ранее. Скорее всего, необходимо указывать GFP_KERNEL или GFP_ATOMIC.

Далее для удаления объекта и возвращения его в сляб, из которого он был выделен, необходимо использовать следующую функцию.

void kmem_cache_free(kmem_cache_t *cachep, void *objp);

Данная функция помечает объект, на который указывает параметр objp, как свободный.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Сегменты памяти

Из книги Основы AS/400 автора Солтис Фрэнк

Сегменты памяти Каждый объект состоит из одного или нескольких не перекрывающихся сегментов. При создании сегмента должны быть заданы несколько характеристик. Одна из них — начальный размер. На основании начального размера компонент управления дисками выделяет


Распределение памяти

Из книги Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT автора Фролов Александр Вячеславович

Распределение памяти Стандартная библиотека компиляторов содержит специальные функции управления памятью – malloc, free, а также другие разновидности этих функций. Они позволяют получить для использования блок оперативной памяти, и затем отдать его обратно операционной


2.8. Тип памяти CSV

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.


13.2. Отображение в памяти

Из книги Язык Си - руководство для начинающих автора Прата Стивен

13.2. Отображение в памяти Операционная система Linux позволяет процессу отображать файлы в их адресное пространство. Такое отображение создает взаимно однозначное соответствие между данными в файле и в отображаемой области памяти. Отображение в памяти обладает рядом


20.4.2. Объем памяти

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

20.4.2. Объем памяти Иногда нужно указать объем ОЗУ, отличный от того, который имеется на самом деле. Например, у вас чипсет Intel 810 с интегрированной видеоплатой, тогда вам нужно указать объем ОЗУ на 1 Мб меньше (а иногда даже на 2 Мб). Это связано с аппаратной особенностью


Выделение памяти

Из книги Операционная система UNIX автора Робачевский Андрей М.

Выделение памяти      Сначала следует определить место для размещения строки при вводе. Как было отмечено раньше, это значит, выделить память, достаточную для размещения любых строк, которые мы предполагаем читать. Не следует надеяться, что компьютер подсчитает длину


Классы памяти

Из книги Яндекс Воложа [История создания компании мечты] автора Дорофеев Владислав Юрьевич

Классы памяти I.Ключевые слова: auto, external, static, registerII. Основные замечания Класс памяти переменной определяет область ее действия и продолжительность использования. Класс памяти определяется местом задания переменной и соответствующим ключевым словом. Переменные,


5.1.2. Модель памяти

Из книги Разработка ядра Linux автора Лав Роберт

5.1.2. Модель памяти При совместном использовании сегмента памяти один процесс должен сначала выделить память. Затем все остальные процессы, которые хотят получить доступ к ней, должны подключить сегмент. По окончании работы с сегментом каждый процесс отключает его.


Выделение памяти

Из книги автора

Выделение памяти При обсуждении формата исполняемых файлов и образа программы в памяти мы отметили, что сегменты данных и стека могут изменять свои размеры. Если для стека операцию выделения памяти операционная система производит автоматически, то приложение имеет


Провал в памяти

Из книги автора

Провал в памяти Сегодняшний «Яндекс» — это глобальная централизованная сеть. Это тысячи километров выделенных каналов, соединяющих воедино десятки тысяч серверов, которые обрабатывают за доли секунды ежедневно около 150 млн запросов, формулируемых около 100 млн


Уровень слябового распределителя памяти

Из книги автора

Уровень слябового распределителя памяти Выделение и освобождение структур данных — это одна из наиболее частых операций, которые выполняются в любом ядре. Для того чтобы облегчить процедуру частого выделения и освобождения данных при программировании, вводятся списки


Устройство слябового распределителя памяти

Из книги автора

Устройство слябового распределителя памяти Уровень слябового распределения памяти делит объекты на группы, которые называются кэшами (cache). Разные кэши используются для хранения объектов различных типов. Для каждого типа объектов существует свой уникальный кэш.


Пример использования слябового распределителя памяти

Из книги автора

Пример использования слябового распределителя памяти Давайте рассмотрим пример из реальной жизни, связанный с работой со структурами task_struct (дескрипторы процессов). Показанный ниже код в несколько более сложной форме приведен в файле kernel/fork.c.В ядре определена