Дескриптор пам’яті

Ядро являє адресний простір процесу у вигляді структури даних, яка називаєтьсядескриптором памяті Ця структура містить всю інформацію, яка відноситься до адресного простору процесу Дескриптор памяті представляється за допомогою структури struc t mm_struct, яка визначена у файлі

&lt1inux/schedh&gt 3

Розглянемо цю структуру з коментарями, що пояснюють призначення кожного поля

struct mm_struct {

struct vm_area_struct * mmap / * Список областей памяті * /

struct rb_root mm_rb / * Червоно-чорне дерево областей памяті * / struct vm_area_struct * mmap_cache / * Остання використана область памяті * / unsigned long free_area_cache / * Перший незайнятий ділянку

spinlock_t page_table_lock / * Спін-блокування таблиць сторінок * / struct list_head mmlist / * Список всіх структур mm_struct * / unsigned long start_code / * Початкова адреса сегмента коду * / Unsigned long end code / * Кінцевий адресу сегмента коду * / unsigned long start_data / * Початкова адреса сегмента даних * / unsigned long end_data / * Кінцевий адресу сегменту даних * / Unsigned long start_brk / * Початкова адреса сегмента купи * / Unsigned long brk / * Кінцевий адресу сегмента купи * / Unsigned long start_stack / * Початок стека процесу * /

unsigned long arg_start / * Початкова адреса області аргументів * / unsigned long arg_end / * Кінцевий адреса області аргументів * / unsigned long env_start / * Початкова адреса області змінних середовища * / unsigned long env_end / * Кінцевий адреса області змінних середовища * / unsigned long rss / * Кількість фізичних сторінок памяті * / unsigned long total_vm / * Загальна кількість сторінок памяті * / unsigned long locked_vm / * Кількість заблокованих сторінок

памяті * /

unsigned long def_flags / * Прапори доступу, використовувані за замовчуванням * /

unsigned long cpu_vm_mask / * MacKa відкладеного перемикання буфера TLB * / unsigned long swap_address / * Останній сканований адреса * / unsigned dumpable: l / * Чи можна створювати файл core * / Int used_hugetlb / * Чи використовуються гігантські

сторінки памяті (hugetlb) * /

3 Між дескриптором процесу, дескриптором памяті і відповідними функціями існує тісна я звязок Тому структура struc t mm_struc t і визначена в заголовному файл еschedh

mm_context_t context / * Дані, специфічні для апаратної платформи * /

int core_waiters / * Кількість потоків, які очікують на створення файлу core * /

struct completion * core_startup_donc / * Умовна змінна початку створення файлу core * /

struct completion core_done / * Умовна змінна завершення створення файлу core * /

rwlock_t ioctx_list_lock / * Блокування списку асинхронного вводу-виводу (AIO) * /

struct kioctx * ioctx_list / * Список асинхронного вводу-виводу (AIO) V

struct kioctx default kioctx / * Контекст асинхронного вводавивода, використовуваний за замовчуванням * /

}

Поле mm_users – це кількість процесів, які використовують дане адресний простір Наприклад, якщо один і той же адресний простір спільно використовується двома потоками, то значення поля mm_user s дорівнює двом Поле ram_count – це основний лічильник використання структури mm_struct Наявність користувачів структури, яким відповідає поле mm_users, призводить до збільшення лічильника mm_coun t на одиницю У попередньому прикладі значення поля mm_count дорівнює одиниці Коли значення поля mm_user s стає рівним нулю (тобто коли два потоки завершаться), тільки тоді значення поля mm_count зменшується на одиницю Коли значення поля mm_coun t стає рівним нулю, то на відповідну структуру mm_struc t більше немає посилань, і вона звільняється, Підтримка двох лічильників дозволяє ядру відрізняти головний лічильник використання (mm_count) від кількості процесів, які використовують дану структуру (mm_users)

Поля mmap і mm_r b – це два різних контейнера даних, які містять одну й ту ж інформацію: інформацію про всі області памяті у відповідному адресному просторі У першому контейнері ця інформація зберігається у вигляді повязаного списку, а в другому-у вигляді червоно-чорного бінарного дерева Оскільки червоно-чорне дерево – це різновид бінарного дерева, то, як і для всіх типів бінарного дерева, кількість операцій пошуку заданого елемента в ньому дорівнює О (lo g (n)) Більш детальний розгляд червоно-чорних дерев знайдете в розділі Списки і дерева областей памяті .

Хоча зазвичай в ядрі уникають надмірності, повязаної з введенням декількох структур для зберігання одних і тих же даних, проте в даному випадку ця надмірність дуже до речі Контейнер mmap – це звязаний список, який дозволяє дуже швидко проходити по всіх елементах З іншого боку, контейнер mm_rb – це червоно-чорне дерево, яке дуже добре підходить для пошуку заданого елемента Області памяті будуть розглянуті в цьому розділі трохи нижче, Всі структури mm_struc t обєднані в двохзвязної список за допомогою нулів mmlist Першим елементом цього списку є дескриптор памяті init_mm, який є дескриптором памяті процесу ink Цей список захищена від конкурентного доступу за допомогою блокування mmlist_lock, яка визначена у файлі kernel / forkс Загальна кількість дескрипторів памяті зберігається в глобальній

цілочисельний змінної mmlist_nr, яка визначена в тому ж файлі

Виділення дескриптора памяті

Покажчик на дескриптор памяті, виділений для якої завдання, зберігається в полі mm дескриптора процесу цього завдання Отже, вираження current-> rnm дозволяє отримати дескриптор памяті поточного процесу Функція copy_mm () використовується для копіювання дескриптора батьківського процесу в дескриптор породженого процесу під час виконання виклику fоrk () Структура mm_struc t виділяється з слябової кеша mm_cachep за допомогою макросу allocate_m m () Це реалізовано у файлі kernel / forkс Зазвичай кожен процес отримує унікальний екземпляр структури mm_struc t і відповідно унікальне адресний простір

Процес може використовувати один і той же адресний простір спільно зі своїми породженими процесами, шляхом зазначення прапора CLONE_VM при виконанні виклику clon e () Такі процеси називаються потоками Згадайте з матеріалу глави 3, Управління процесами, що в операційній системі Linux в цьому і полягаєєдинеістотна відмінність між звичайними процесами і потоками Ядро Linux більше жодним іншим чином їх не розрізняє Потоки з точки зору ядра-це звичайні процеси, які просто спільно використовують деякі загальні ресурси

У разі, коли зазначений прапор CLONE_VM, макрос allocate_mm () не викликається, а в поле mm дескриптора породженого процесу записується значення покажчика на дескриптор памяті батьківського процесу Це реалізовано с допомогою наступного оператора розгалуження у функції сору_m m ()

if   (clone_flag s  &amp  CLONE_VM)   {

/*

* Curren t – це батьківський процес

* Ts k – це процес, породжений у виклику fork ()

*/

atomic_inc(&ampcurrent-&gtmm-&gtmm_users)

tsk-&gtmm = current-&gtmm

}

Видалення дескриптора памяті

Коли процес, повязаний з певним адресним простором, завершується, то викликається функція exit_mm () Ця функція виконує деякі службові дії і оновлює деяку статистичну інформацію Далі викликається функція input (), яка зменшує на одиницю значення лічильника кількості користувачів mm_user s для дескриптора памяті Коли значення лічильника кількості користувачів стає рівним нулю, то викликається функція mmdrop (), яка зменшує значення основного лічильника використання mm_count Коли і цей лічильник використання нарешті досягає нульового значення, то викликається функція free_mm (), яка повертає екземпляр структури mm_struc t в слябової кеш mm_cachep за допомогою виклику функції kmem_cache_fгее (), оскільки де- скриптор памяті більше не використовується

Структура mm_struc t і потоки простору ядра

Потоки простору ядра не мають свого адресного простору процесу і, отже, повязаного з ним дескриптора памяті Значення поля mm для потоку простору ядра одно NULL Ще одне  визначення потоку ядра – це процес, який не має користувальницького контексту

Відсутність адресного простору-гарну властивість, оскільки потоки ядра взагалі не звертаються до памяті в просторі користувача (дійсно, до якого адресного простору їм звертатися) Оскільки потоки ядра не звертаються до сторінок памяті в просторі користувача, їм взагалі не потрібен дескриптор памяті і таблиці сторінок (таблиці сторінок обговорюються далі в цьому розділі) Незважаючи на це, потокам простору ядра все ж потрібні деякі структури даних, такі як таблиці сторінок, щоб звертатися до памяті ядра Щоб забезпечити потоки ядра усіма даними без необхідності витрачати память на дескриптор памяті і таблиці сторінок, а також процесорний час на перемикання на нове адресний простір і так далі, кожен потік ядра використовує дескриптор памяті завдання, яке виконувалося перед ним

Коли процес запланований на виконання, то завантажується адресний простір, на яке вказує поле mm цього процесу Поле active_m m дескриптора процесу оновлюється таким чином, щоб вказувати на нове адресний простір Потоки ядра не мають свого адресного простору, тому значення поля mm для них одно NULL Тому, коли потік ядра планується на виконання, ядро визначає, що значення нуля mm одно NULL, і залишає завантаженим попереднє адресний простір Після цього ядро ​​оновлює поле active_m m дескриптора процесу для потоку ядра, щоб він вказував на дескриптор памяті попереднього процесу Пр і необхідності потік ядра може використовувати таблиці сторінок попереднього процесу Так як потоки ядра не звертаються до памяті в просторі користувача, то вони використовують тільки ту інформацію про адресний простір ядра, яка повязана з памяттю ядра і є загальною для всіх процесів

Джерело: Лав, Роберт Розробка ядра Linux, 2-е видання : Пер з англ – М: ТОВ «ІД Вільямс »2006 – 448 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*