Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Описатель кеша общего назначения



Как было сказано ранее, кеши всегда хранят объекты предопределенного размера общего назначения в виде пар. Один кеш - для выделения объектов из зоны DMA, другой - для стандартного выделения из обычной памяти. Если вы вспомните, что такое зоны памяти, вы поймете, что DMA-кеши размещаются в ZONE_DMA, а стандартные - в ZONE_ NORMAL. Структура cache_sizes является удобным средством для хранения всей связанной с размерами кешей информации.

include/linux/slab.h

69 struct cache_sizes {

70 size_t cs_size;

71 kmem_cache_t *cs_cachep;

72 kmem_cache_t *cs_dmacachep;

73 };

4.4.2.1 cs_size

Поле cs_size хранит размер объекта памяти, находящегося в кеше.



Глава 4 • Управление памятью


4.4.2.2 cs_cachep

Поле cs__cachep хранит указатель на описатель кеша обычной памяти, выделяемых из

ZONE_NORMAL.

4.4.2.3 cs_dmacachep

Поле cs_dmacachep хранит указатель на описатель кеша обычной памяти, выделяемых ИЗ ZONE_NORMAL.

На ум приходит вопрос: «Где хранятся описатели кешей? » Выделитель секций обла­дает специально зарезервированным для этого кешем. Кеш cache_cache хранит объек­ты типа описателя кеша. Кеш секции инициализируется статически при загрузке системы, для того чтобы можно было быть уверенным, что место для описателей кеша есть.

Описатель секции

Каждая секция в кеше имеет описатель, хранящий связанную с этой секцией информа­цию. Необходимо заметить, что описатель кеша хранится в специальном кеше, называе­мом cache__cache. Описатель секции, в свою очередь, хранится в двух местах: внутри самой секции (точнее говоря, фрейм первой страницы) или снаружи, в первом кеше об­щего назначения, в объекте достаточного размера для хранения описателя секции. Он за­полняется при создании кеша на основе оставшегося после объекта размещения. Это про­странство определяется при создании кеша.

Давайте рассмотрим несколько полей описателя секции.

mm/slab.с

173 struct slab {

174 struct list_head list;

175 unsigned long coloroff;

176 void *s__mem; /* включает цветовой отступ */

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

178 kmem_bufctl_t free;

179 };

List

Как вы помните из обсуждения описателя кеша, секция может находиться в одном из трех состояний: free, partial или full. Описатель кеша хранит описатель секции в трех списках - по одному для каждого состояния. Все секции в определенном состоя­нии хранятся в двусвязном списке в зависимости от значения поля list.

Sjnem

Поле s_mem хранит указатель на первый объект в секции.


Выделение секций



Inuse

Значение inuse отслеживает количество занятых в секции объектов. Для полностью или частично заполненных секций это число положительное, а для свободных секций равно 0.

Free

Поле free хранит значение индекса для массива, элементы которого представляют объ­екты секции. В частности, поле free хранит значение индекса элемента массива, пред­ставляющего первый доступный объект в секции. Тип данных kmem_buf ctl_t связы­вает все объекты внутри секции. Этот тип является просто беззнаковым целым и опреде­лен в include /asm/ types.h. Этот тип данных определяет массив, всегда хранящийся сразу после описателя секции, в зависимости от того, хранится ли описатель секции внутри ее или снаружи. Все станет значительно понятней, если мы взглянем на функцию slab_buf ctl_t, возвращающую массив:

mm/slab.с

1614 static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)

1615 {

1616 return (kmem_bufctl_t *)(slabp+1);

1617 }

Функция slab_buf с tl__t () получает указатель на описатель секции и возвращает указатель на область памяти, следующую сразу за описателем секции.

При инициализации кеша поле slab_f гее устанавливается в 0 (так как все объекты свободны, будет возвращен первый) и каждое вхождение в массив kniem__buf ctl_t ус­танавливается в значение индекса следующего члена массива. Это означает, что нулевой элемент хранит значение 1, первый элемент хранит значение 2 и т. д. Последний элемент в массиве хранит значение BUFCTL_END, что означает, что он является последним эле­ментом в массиве.

Рис. 4.8 демонстрирует описатель секции, массив buf с tl и размещение объекта сек­ции, когда описатель секции хранится внутри самой секции. В табл. 4.5 показаны возмож­ные значения некоторых полей описателя секции в каждом из трех возможных состояний.



Глава 4 • Управление памятью


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    slab   slab  
  color_off     color_off  
list list
    s_mem   s_mem
free free
inuse inuse
   
< 1> < 1>
< 2> < 2>
< 3> < 3>
   
< N-1> < N-1>
< BUFCTL_END> < BUFCTL_END>
   
    obi 1 obi 1
     
obj2 obj 2
   
obj 3 obj 3
         
  objN   objN  
             

Рис. 4.8. Описатель секции и bufctl

Таблица 4.5. Состояние секции и значения полей описателя


Free


Partial


Full


 


slab_inuse slab-> free


X X


N N


ПРИМЕЧАНИЕ. N = количество объектов в секции; X = некоторое положительное число.


Жизненный цикл выделителя секции



Жизненный цикл выделителя секции

Теперь мы рассмотрим взаимодействие кеша и выделителя секции на протяжении жиз­ненного цикла ядра. Ядру нужно быть уверенным, что некоторые структуры находятся на своих местах для поддержки запрошенной процессом области памяти и при создании специализированного кеша в динамически загружаемом модуле.

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

Глобальные переменные выделителя секции

С выделителем секции связаны несколько глобальных переменных. Они включают:

cache_cache. Описатель кеша, содержащий все остальные описатели кешей. Читабельное для человека имя этого кеша - kmem__cache. Это единственный статически выделяемый описатель кеша.

cache__chain. Элемент списка, служащий в качестве указателя на список описа­телей кешей.

cache__chain_sem. Семафор, контролирующий доступ к cache_chain1. Каж­дый раз, когда в последовательность добавляется новый элемент (новый описатель кеша), этот семафор получается с помощью down () и освобождается с помощью up ().

malloc_sizes [ ]. Массив, хранящий описатели кеша для DMA- и неБМА-кешей, которые связаны с общим кешем.

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

mm/slab.с

486 static kmem_cache_t cache_cache = {

487.lists = LIST3_INIT(cache_cache.lists),

488.batchcount = 1,

489.limit = BOOT_CPUCACHE_ENTRIES/

490.objsize = sizeof(kmem_cache_t),

491.flags = SLAB_NO_REAP,

492.spinlock = SPIN_LOCK_UNLOCKED,

493.color_off = Ll_CACHE_BYTES,

494.name = иктет_саспеи,

495 };
496

497 /* Защищенный доступ к последовательности кеша. */

498 static struct semaphore cache_chain_sem;

1 Семафоры подробно описываются в гл. 9, «Построение ядра Linux».



Глава 4 • Управление памятью


500 struct list_head cache_chain;

Описатель кеша cache_cache обладает флагом SLAB_NO_REAP. Даже если памя­ти мало, этот кеш сохраняется на протяжении всей жизни ядра. Обратите внимание, что семафор cache_chain только определяется, но не инициализируется. Инициализация происходит во время инициализации системы в вызове kmem_cache_init (). Здесь мы рассмотрим эту функцию подробнее.

mm/slab.с

462 struct cache_sizes malloc_sizes[] = {

463 #define CACHE(x) {.cs_size = (x) },

464 #include < linux/kmalloc__sizes.h>

465 { 0, }

466 #undef CACHE

467 };

Этот фрагмент кода инициализирует массив malloc_sizes [ ] и устанавливает поле cs_size в соответствии со значением, определенным в include/linux/ kernel_sizes. h. Как было сказано ранее, размер кеша может варьироваться от 32 байт до 131072 байт в зависимости от специальных настроек ядра1.

Когда глобальные переменные заняли свои места, ядро начинает инициализацию вы­делителя секций с помощью вызова kmem_cache_init () из init/main.c2. Эта функция берет на себя заботу об инициализации последовательности кешей, его сема­фора, общего кеша, кеша kmem_cache - короче говоря, всех глобальных переменных, ис­пользуемых выделителем секций для управления секциями. В этом месте создаются специа­лизированные кеши. Для создания кешей используется функция kmem_cache_create ().

Создание кеша

Создание кеша включает три шага:

1. Выделение и инициализация описателя.

2. Расчет раскраски секции и размера объекта.

3. Добавление кеша в список cache_chain.

1 Существует несколько настроек, при которых размер общего кеша становится большим, чем 131072. Более
подробную информацию можно увидеть в include/linux/kmalloc_sizes.h.

2 Гл. 9 описывает процесс инициализации начиная с загрузки. Мы увидим, как kmem_cache_init () встраи­
вается в процесс загрузки.


Поделиться:



Популярное:

  1. Анализ общего равновесия, благосостояние
  2. В ПОИСКАХ ОБЩЕГО ЗНАМЕНАТЕЛЯ
  3. В Украине устанавливаются общегосударственные и местные налоги и сборы
  4. Глава III. Серьезные нарушения обязательств, вытекающих из императивных норм общего международного права
  5. Детали и узлы общего применения.
  6. и регистры общего назначения
  7. Измерение общего уровня цен.
  8. Имущественные отношения, возникающие в сфере деятельности государственных органов и связанные с накоплением и распределением денежных средств на общегосударственные нужды, регулируются нормами
  9. Кафедра общего земледелия и землеустройства
  10. Кому принадлежит следующее высказывание: «Сущность права состоит в равновесии двух нравственных начал: личной свободы и общего блага»?
  11. Лампы накаливания общего назначения
  12. Минимизация убытков фирмы-совершенного конкурента в краткосрочн. периоде: принцип сопоставления общего дохода с общими издержками. Условие и графическое изображение.


Последнее изменение этой страницы: 2016-03-25; Просмотров: 632; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.059 с.)
Главная | Случайная страница | Обратная связь