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

       

Do_wp_page


Как было упомянуто ранее, копирование при записи фактически реализовано здесь, поэтому рассмотрим эту функцию хотя бы вкратце. В функции tsk была предпринята попытка выполнить запись по адресу, который находился в пределах указанной области vma и контролировался переданным параметром page_table.

Происходит вызов функции __get_free_page (строка , которая просто возвращается назад и вызывает функцию __get_free_pages в строке ) для предоставления процессу новой страницы — это должна быть новая копия страницы, защищенной от записи. Обратите внимание, что это позволяет обеспечить переключение заданий. Любопытно отметить, что в этом коде не предусмотрена проверка того, смогла ли функция __get_free_page успешно распределить новую страницу: для него фактически может не потребоваться новая страница, как мы вскоре увидим, поэтому проверка откладывается до того момента, когда в этом появится смысл.

Наращивается число «малых» ситуаций отсутствия страницы: ситуаций отсутствия страницы, которые были разрешены без обращения к диску.

Существуют только два пользователя данной страницы, и одним из них является кэш свопинга — временный пул страниц, выведенных на диск, но еще не возвращенных в память. Страница просто удалена из кэша свопинга (с использованием функции delete_from_swap_cache, строка ) и теперь она имеет только одного пользователя.

Либо эта страница была только что возвращена из кэша свопинга, либо она имела для начала только одного пользователя. Страница отмечается как предназначенная для записи и грязная (поскольку на ней была выполнена запись).

Если новая страница была распределена ранее, она не понадобится: копия не нужна, поскольку страница имеет только одного пользователя. Функция do_wp_page освобождает новую страницу, а затем возвращает ненулевое значение в качестве свидетельства успеха.

: Страница имеет более одного пользователя и не могла быть просто возвращена в память из кэша свопинга. Поэтому в функции do_wp_page возникает потребность в получении новой страницы для копии. Если оказалось, что предыдущая попытка распределения страницы окончилась неудачей, теперь эта информация становится важной; функция do_wp_page должна возвратить отказ.


Получение копии содержимого страницы с использованием функции copy_cow_page (строка ). Это обычно лишь вызов макрокоманды copy_page (строка ), которая представляет собой просто команду memcpy.

Выполняется синхронизация содержимого старой и новой копии страницы с оперативной памятью с использованием функции flush_page_to_ram (строка ). Как и функция update_mmu_cache, эта функция в архитектуре х86 является пустой операцией.

Как и прежде, обозначает страницу как предназначенную для записи и грязную, но оставляет нетронутыми все другие признаки защиты страницы (например, обозначение выполняемого кода) из содержащей ее области VMA.

Этот вызов функции free_page (строка , где просто происходит вызов функции free_pages, строка ) фактически не освобождает старую страницу, поскольку она имеет несколько пользователей — она только уменьшает на единицу число ссылок на старую страницу. Поскольку запрос вызвавшей программы был удовлетворен, функция do_wp_page может вернуть ненулевое значение в качестве свидетельства успеха.


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