Ядро Linux в комментариях

       

Do_munmap


Очевидно, что функция do_munmap противоположна do_mmap; она удаляет отображения виртуальной памяти из пространства памяти процесса.

Если адрес, который должен быть изъят из отображения с помощью функции do_munmap, не выровнен по границе страницы или соответствующая ему область памяти лежит вне пространства памяти процесса, ясно, что он недействителен, поэтому такая попытка будет здесь отвергнута.

Если не была освобождена, по крайней мере, одна страница, попытка отвергается.

Поиск области VMA, которая включает указанный адрес. Любопытно, что функция do_munmap возвращает 0 — признак отсутствия ошибки — если адрес не находился ни в одной области VMA. В определенном смысле, это правильно; функция do_rnunmap получила запрос проверить то, что процесс больше не имеет отображения для данной области памяти и это легко сделать, если такого отображения не было с самого начала. Но это все равно вызывает удивление; может оказаться, что со стороны вызывающей функции допущена ошибка и что функция do_munmap должна поэтому как-то об этом сообщить. Однако некоторые вызывающие функции основаны на том, что так и должно быть на самом деле, например, см. строку .

Если указанный диапазон памяти лежит полностью внутри отдельной области VMA, но не соприкасается ни с одним концом содержащей его области VMA, то удаление этого участка привело бы к возникновению отверстия во включающей его области VMA. Ядро не может допустить возникновения отверстия, поскольку области VMA по определению представляют собой непрерывные области памяти. Поэтому в таком случае функция do_munmap должна создать другие области VMA, по одной с каждой стороны отверстия. Однако, если ядро уже создало такое количество областей VMA, какое разрешено для данного процесса, оно не может это выполнить, поэтому функция do_munmap не в состоянии удовлетворить запрос.

Поиск всех областей VMA, перекрывающих или лежащих внутри участка, предназначенного для освобождения, и размещение каждой из этих областей в локальном стеке областей VMA, предназначенных для освобождения. В этом процессе функция do_munmap удаляет области VMA из содержащего их дерева AVL, если оно имеется.


Функция do_munmap построила стек областей VMA, предназначенных для освобождения; теперь она может их освободить.

Вычисление точного размера диапазона адресов, предназначенного для освобождения, с учетом того, что он может не охватывать всю эту область VMA. Предусмотрев подходящие определения для min и max, эти три строки можно записать следующим образом:

st = max(mpnt->vm_start, addr); end = min(mpnt->vm_end, addr + len);

Поэтому st — это начало области, с которого функция do_munmap фактически начнет освобождение, а end — конец этой области.

Если эта область VMA составляла часть разделяемого отображения, функция do_munmap удаляет mpnt из списка разделяемых областей VMA с помощью вызова функции remove_shared_vm_struct (строка ).

Обновляет структуры данных MMU, соответствующие текущей подобласти, которая была освобождена внутри данной области VMA.

Исправляет отображение с помощью вызова функции unmap_fixup, которая будет рассмотрена ниже.

Функция do_munmap освободила все отображения, представленные областями VMA в этом диапазоне; последний важный шаг состоит в освобождении таблиц страниц одного и того же диапазона, что было выполнено с помощью вызова функции free_pgtables (строка ).


Содержание раздела