Linux Kernel (Ядро линукса) (часть 1)


Функция do_munmap

Выполнение этой функции происходит в два этапа. На первом этапе (шаги 1—6) она перебирает список областей памяти, принадлежащих процессу, и отсоединяет все области, попадающие в интервал линейных адресов, от адресного пространства процесса. На втором этапе (шаги 7—12) функция обновляет Таблицы Страниц процесса и удаляет области, определенные на первом этапе. Функция пользуется функциями split_vma И unmap region , описанными далее. Функция do munmap выполняет следующие действия:
1. Производит некоторые предварительные проверки значений параметров. Если интервал линейных адресов включает в себя адреса, превышающие task size, если значение start не кратно 4096, или если интервал имеет нулевую длину, функция возвращает код ошибки -einval.
2. Находит первую область памяти mpnt, которая заканчивается после удаляемого интерфейса линейных адресов (mpnt->end > start), если таковая существует:
mpnt = find_vma_prev(mm, start, &prev);
3. Если такой области нет, или найденная область не пересекается с интервалом линейных адресов, ничего предпринимать не нужно, поскольку интервал не содержит ни одной области:
end = start + len; if (!mpnt || mpnt->vm_start >= end) return 0;
4. Если интервал линейных адресов начинается внутри области памяти mpnt, функция вызывает функцию spiit vmao (описанную далее), чтобы разбить область на две меньшие: одну вне интервала, а другую— внутри него:
if (start > mpnt->vm_start) {
if (split_vma(mm, mpnt, start, 0)) return -ENOMEM; prev = mpnt;}
Локальная переменная prev, которая до этого содержала указатель на область памяти, предшествующую области mpnt, обновляется и теперь указывает на mpnt, т. е. на новую область памяти, лежащую вне интервала линейных адресов. Таким образом, переменная prev все равно указывает на область памяти, предшествующую первой области, подлежащей удалению.
5. Если интервал линейных адресов заканчивается в пределах какой-либо области памяти, функция вызывает функцию split vma () еще раз, чтобы разбить последнюю пересекающуюся с интервалом область на две меньшие: одну вне интервала, а другую — внутри него6:
last = f ind_vma (mm, end) ;
if (last && end > last->vm_start)){
if (split_vma(mm, last, start, end, 1)) return -ENOMEM;}
6. Обновляет значение локальной переменной mpnt так, чтобы она указывала на первую область памяти в интервале линейных адресов. Если переменная prev содержит null, т. е. предшествующих областей нет, адрес первой Области паМЯТИ береТСЯ ИЗ ПОЛЯ mm->mmap:
mpnt = prev ? prev->vm_next : mm->mmap;
7. Вызывает функцию detach_vmas_to_be_unmapped, Чтобы удалить области памяти, попадающие в интервал линейных адресов, из адресного пространства процесса. Эта функция, в сущности, выполняет следующий код:vma = mpnt;
insertion_point = (prev ? &prev->vm_next : &mm->mmap); do {
rb_e r a s e (& vma - > vm_rb, &mm- >mm_rb) ; mm- >map_c oun t— ; tail_vma = vma; vma = vma->next;
} while (vma && vma->start vm_next = NULL; mm->map_cache = NULL;
Дескрипторы областей, подлежащих удалению, хранятся в упорядоченном списке, на голову которого указывает локальная переменная mpnt (этот список фактически является фрагментом оригинального списка областей памяти, принадлежащих процессу).
8. Получает спин-блокировку mm->page_table_lock.
9. Вызывает функцию unmap region (описанную далее) для очистки записей Таблицы Страниц, относящихся к интервалу линейных адресов, и освобождения соответствующих страничных кадров:
unmap_region(mm, mpnt, prev, start, end);
1 0. Освобождает спин-блокировку mm->page_table_lock.
11. Освобождает дескрипторы областей памяти, собранные в список на шаге 7:do {
struct vm_area_struct next = mpnt->vm_next; unmap_vma (mm, mpnt); mpnt = next;
} while (mpnt != NULL);
Функция unmap_vma вызывается для каждой области памяти в списке. Она выполняет следующие действия:
• обновляет ПОЛЯ mm->total_vm И mm->locked_vm;
• выполняет метод mm->unmap_area дескриптора памяти. Этот метод реализован ОДНОЙ ИЗ функций, arch unmap area ИЛИ arch_unmap_area_ topdown , в зависимости от схемы расположения областей памяти процесса. В любом случае обновляется поле mm->free_area_cache, если это необходимо;
• вызывает метод close области памяти, если он определен;
• если область памяти анонимна, функция удаляет ее из списка анонимных областей, голова которого находится в поле mm->anon_vma;
• вызывает функцию kmem_cache_f гее , чтобы освободить Дескриптор области памяти.
12. Возвращает 0 (успешное завершение).

Заметка: Современные свадебные приглашения бывают разнообразными, а главное обладают всевозможными стилистическими решениями. Такие решения могут полностью отражать атмосферу свадьбы. Большое внимание стоит уделять их грамотному выбору и покупке.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть...

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...