Робота з областями пам’яті

Ядру часто необхідно визначати, чи відповідає та чи інша область памяті в адресному просторі процесу заданому критерію, наприклад, існує заданий адресу в області памяті Ці операції є основою роботи функції mmap (), яка буде розглянута в наступному розділі, і виконувати їх доводиться часто Кілька корисних для цього функцій оголошені у файлі

&ltlinux/mmh&gt.

Функція find_vma ()

Функція f ind_vma () визначена у файлі mm / mmapс

Ця функція дозволяє знайти в заданому адресному просторі ту першу область памяті, для якої значення поля vm_end більше заданого адреси addr Іншими словами, ця функція дозволяє знайти перший область памяті, яка містить адресу addr або починається з адреси, більшого адреси addr Якщо такої області памяті не існує, то функція повертає значення NULL

В іншому випадку повертається вказівник на відповідну структуру vm_area_struct Зверніть увагу, що знайдена область VMA може починатися з адреси, більшого адреси addr, і ця адреса не обовязково належить,знайденої області памяті Результат виконання функції find_vma () кешується в поле map_cach e дескриптора памяті Оскільки дуже велика ймовірність того, що після однієї операції з областю памяті підуть ще операції з нею ж, то відсоток влучень в кеш виходить досить великим (на практиці виходять значення порядку 30-40%) Перевірка кешованих результатів виконується дуже швидко Якщо потрібну адресу в кеші не знайдений, то виконується пошук по всіх областях памяті, повязаним із заданим дескриптором Цей пошук виконується за допомогою червоно-чорного дерева таким чином

struct vm_area_struct * find_vma(struct mm_struct *mm, unsigned long addr)

{

struct vm_area_struct *vma = NULL

if (mm) {

vma = mm-&gtmmap_cache

if ( (vma &amp&amp vma-&gtvm_end &gt addr &amp&amp vma-&gtvm start &lt= addr)) {

struct rb node * rb_node

rb node = mm-&gtmm_rbrb_node

vma = NULL

while (rb_node) {

struct vm_area_struct * vma_tmp

vma_tmp = rb_entry (rb_node,

struct vm_area_struct, vm_rb)

if (vma_tmp-&gtvm_end &gt addr) {

vma = vma_tmp

if (vma_tmp-&gtvm_start &lt= addr)

break

rb_node = rb_node-&gtrb_left

} else

}

rb_node = rb_node-&gtrb_right

if (vma)

mm-&gtmmap_cache = vma

}

}

return vma

}

Спочатку виконується перевірка поля vma_cach e на предмет того, чи містить кешована область VMA необхідну адресу Зверніть увагу, що проста перевірка того, чи є значення поля vm_end великим addr, не гарантує що проверяемая область памяті є першою, в якій є адреси, великі addr Тому, для того щоб кеш в цій ситуації виявився корисним, перевірявся адреса повинна належати кешованої області памяті На щастя, це якраз і відповідає випадку виконання послідовних операцій з однією і тією ж областю VMA

Якщо кеш не містить потрібну область VMA, то функція повинна виконувати пошук по червоно-чорному дереву Це виконується шляхом перевірки вузлів дерева Якщо значення поля vma_end для області памяті поточного вузла більше addr, то поточним стає лівий дочірній вузол, в іншому випадку – правий Функція завершує свою роботу, як тільки знаходиться область памяті, яка містить адреса addr Якщо така область VMA не знайдено, то функція продовжує пошук по дереву і повертає ту область памяті, яка починається після адреси addr Якщо взагалі не знайдена жодна область памяті, то повертається значення NULL

Функція find_vma_prev ()

Функція find_vma_pre v () працює аналогічно функції fin d vma (), але додатково вона ще повертає останню область VMA, яка закінчується перед адресою addr Ця функція також визначена у файлі mma / mmapc і оголошена в файлі таким чином

struct vm_area_struct * find vma_prev(struct mm_struct *mm, unsigned long addr, struct vm_area_struct **pprev)

Параметр ppre v після повернення з функції містить покажчик на попередню область VMA

Функція find_VMA_intersection ()

Функція f ind_vma_intersectio n () повертає перший область памяті, яка перекривається з вказаним інтервалом адрес Ця функція визначена у файлі таким чином Це функція з підстановкою тіла

static inline struct vm_area_struct * find_vma_intersection(

struct mm_struct *mm, unsigned long start_addr, unsigned long end addr)

{

struct vm_area_struct *vma

vma=find_vma(mm,start_addr)

if (vma &amp&amp end_addr &lt= vma-&gtvm_start)

vma = NULL

return vma

}

Перший параметр – адресний простір, в якому виконується пошук, параметр start_add r – це перший адресу інтервалу адрес, а параметр end_add r – остання адреса інтервалу

Очевидно, що якщо функція find_vma () повертає значення NULL, то це ж значення буде повертати і функція find_vma_intersection () Якщо функція

find_vma () повертає існуючу область VMA, то функція find_vma_intersectio n () поверне ту ж область тільки тоді, коли ця областьНЕ починається після кінця даного діапазону адрес Якщо область памяті, яка повертається функцією find_vma (), починається після останнього адреси з зазначеного діапазону, то функція f ind_vma_intersectio n () повертає значення NULL

Джерело: Лав, Роберт Розробка ядра 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>

*

*