Вход/Регистрация
Разработка ядра Linux
вернуться

Лав Роберт

Шрифт:

Рис. 11.1. Взаимоотношения между кэшами, слябами и объектами

Каждый кэш представляется структурой

kmem_cache_s
. Эта структура содержит три списка
slab_full
,
slab_partial
и
slab_empty
, которые хранятся в структуре
kmem_list3
. Эти списки содержат все слябы, связанные с данным кэшем. Каждый сляб представлен следующей структурой
struct slab
, которая является дескриптором сляба.

struct slab {

 struct list head list; /* список полных, частично заполненных

или пустых слябов */

 unsigned long colouroff; /* смещение для окрашивания слябов */

 void *s_mem; /* первый объект сляба */

 unsigned int inuse; /* количество выделенных объектов */

 kmem_bufctl_tfree; /* первый свободный объект, если есть */

};

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

Слябовый распределитель создает новые слябы, вызывая интерфейс ядра нижнего уровня для выделения памяти

__get_free_pages
следующим образом.

static void *kmem_getpages(kmem_cache_t *cachep,

 int flags, int nodeid) {

 struct page *page;

 void *addr;

 int i;

 flags |= cachep->gfpflags;

 if (likely(nodeid == -1)) {

addr = (void*)__get_free_pages(flags, cachep->gfporder);

if (!addr)

return NULL;

page = virt_to_page(addr);

 } else {

page = alloc_pages_node(nodeid, flags, cachep->gfporder);

if (!page)

return NULL;

addr = page_address(page);

 }

 i = (1 << cachep->gfporder);

 if (cachep->flags & SLAB_RECLAIM_ACCOUNT)

atomic_add(i, &slab_reclaim_pages);

 add_page_state(nr_slab, i);

 while (i-- ) {

SetPageSlab(page);

page++;

 }

 return addr;

}

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

__get_free_pages
. Следует обратить внимание на то, как значения этих флагов объединяются с другими значениями с помощью логической операции
ИЛИ
. Данная операция дополняет флаги значением флагов кэша, которые используются по умолчанию и которые обязательно должны присутствовать n значении параметра
flags
. Количество страниц памяти — целая степень двойки — хранится в поле
cachep->gfporder
. Рассмотренная функция выглядит более сложной, чем это может показаться сначала, поскольку она также рассчитана на NUMA-системы (Non-Uniform Memory Access, системы с неоднородным доступом к памяти). Если параметр
nodeid
на равен
– 1
, то предпринимается попытка выделить память с того же узла памяти, на котором выполняется запрос. Такое решение позволяет получить более высокую производительность для NUMA-систем. Для таких систем обращение к памяти других узлов приводит к снижению производительности.

Для образовательных целей можно убрать код, рассчитанный на NUMA-системы, и получить более простой вариант функции

kmem_getpages
в следующем виде.

static inline void* kmem_getpages(kmem_cache_t *cachep,

 unsigned long flags) {

 void *addr;

 flags |= cachep->gfpflags;

 addr = (void*)__get_free_pages(flags, cachep->gfporder);

 return addr;

}

Память освобождается с помощью функции

kmem_freepages
, которая вызывает функцию
free_pages
для освобождения необходимых страниц кэша. Конечно, назначение уровня слябового распределения — это воздержаться от выделения и освобождения страниц памяти. На самом деле слябовый распределитель использует функции выделения памяти только тогда, когда в данном кэше не доступен ни один частично заполненный или пустой сляб. Функция освобождения памяти вызывается только тогда, когда становится мало доступной памяти и система пытается освободить память или когда кэш полностью ликвидируется.

  • Читать дальше
  • 1
  • ...
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: