Дедупликация страницы исполняемого кода драйверов OC Windows (1187398), страница 7
Текст из файла (страница 7)
Механизм работы нитиможет быть различным, она может просыпаться раз в некоторое время, или начинатьработать по какому-то событию. Она должна проверять количество страниц в резервномбуфере, и довавлять в него новые взамен использованных.Размер буфера и частота добавления новых страниц - очень важные параметры, таккак, если буфер будет пуст в тот момент, когда потребуется страница, то зависнет поменьшей мере один экземпляр драйвера на одном из процессоров. Это не страшно, еслиподкачивающая нить на другом процессоре добавит страницу в буфер.
Однако, в худшемслучае может привести в зависанию всей системы.С другой стороны, драйверы довольно редко изменяют собственный код (а именноэто означает в одну из "объединенных" страниц), а значит, можно подобрать эти значениятакими, что с одной стороны они будут гарантировать надежность, а с другой стороны всееще будут давать значительный выигрыш по количеству страниц. Следует отметить, чтоэти параметры разные для каждого драйвера.
Однако, если встретится драйвер, которыйслишком часто изменяет собственный код, то имеет смысл не объединять его writableстраницы вовсе.В пункте 2.3. "Математическая модель" производится расчет минимальногоколичества страниц, которое должно быть в резервном буфере, и описываетсяинтесивность работы с ним. Несмотря на довольно точный расчет, этого объема может вкакой-то ситуации не хватить, и на этот случай, у пользователя есть возможностьизменять их в ручную.2.2.2.9.
Процесс "разъединения" страниц при отгрузке одного экземплярадрайвераПри разъединении страниц происходит следующее. У драйвера есть виртуальныеадреса страниц в памяти, где находится его код. Каждому виртуальные адресусоответствует определенный физические адреса той, страниц, на который хранятся этиданные. Это механизм трансляции виртуального адреса в физический. Для трансляциииспользуются PTE и PFN страницы (См. пункт 1.4. Обзор литературы).
При выгрузке 1гоэкземпляра драйвера, виртуальные страниц перестают ссылаться на физические страницы,которые принадлежат общему набору. Windows существуют секции помеченные как INIT,то есть Discardable, которые выгружаются сразу же после загрузки драйвер, тем не менее,этот диапазон адресов, остается системе, хотя физические страниц уже отгружены, PTE,33соответствующие этим виртуальным адресам зануляются, и при отгрузке драйверасистема понимает, что эти страницы уже были отгружены ранее. То есть они помечаютсятак, как будто страниц, связанные с ними уже были выгружены. Это действительно так,так как эти страниц были отгружены в систему еще на этапе загрузки драйвер. Этот жеметод мы будем использовать здесь.Таким образом, при разъединении страниц при выгрузке, не будет выделятьсяновая страница, но будут "зануляться" PTE соответствующих виртуальных страниц.Завершение работыВ случае, когда происходит выгрузка моего управляющего драйвера, он долженсначала дождаться пока завершат свою работу все работающие экземплярыдедуплицируемого драйвера, так как иначе, из-за особенностей метода отслеживаниямомента их отгрузки, они просто не смогут быть выгружены без него.342.2.3.
Имплементация механизма копирования при записи (COW)Механизм Copy On Write для неподкачиваемого (NonPaged Pool) пула памятинеобходим, когда заходит речь о максимально полном использовании ресурсов.2.2.3.1. ЦельВ данном разделе основной целью является использование механизма Copy OnWrite в страницах NonPaged Memory. Но не при копировании страниц, а для объединенияуже существующих в системе идентичных страниц в одну и экономии памяти, и далее приразъединении страниц при попытке записи.2.2.3.2. Предлагаемый метод решенияПредлагаемый метод решения состоит в том, что если в системе есть несколькоодинаковых страниц, необходимо:•Объединить страницы в одну;•Вернуть «освобожденную» страницу в систему;При записи необходимо:–Предоставить новую страницу тому потоку, который собирался выполнитьзапись;–Разъединить страницы.2.2.3.3. Трансляция виртуального адреса в физическийПро трансляцию виртуального адреса в физический см.
пункт 1.4. "Обзорлитературы".Во-первых, следует уточнить различия и связи между виртуальными ифизическими страницами в системе. Потому что в данной работе с виртуальными страницне происходит ничего, а изменяются, подгружаются и отгружаются только физические.352.2.3.4. Объединение страницРассмотрим две идентичные страницы, находящиеся в пуле неподкачиваемыхстраниц.Что было Раньше:На Рис.7 есть 2 различные, но с идентичным одержимым виртуальные страницы, сразными PTE, и которые ссылаются на две различные, хоть и с идентичным одержимым,физические страниц. То есть в PTE одной из страниц записано PFN_1, а в PTE другой PFN_2.Рис.
7. Было раньше.Объединение двух страниц, путем изменения их PTE•1-я страница из Writable становится Copy on Write;•2-я страница (так же) становится Copy on Write;(Это только для тех страниц, которые были Writable. Если же она не была Writable,то ее атрибуты не изменяются вовсе.)•PTE 2-й страницы начинает ссылаться на первую.То есть в PTE 2й страницы прописывается PFN номер 1й физической страниц.
См.Рис. 8.36Рис. 8. Объединение двух страниц, путем изменения их PTE.Возврат "освобожденной" страницы в системуПосле этого, PTE_2 будет ссылаться на новую физическую страницу. PFN 2йстраниц остается "забытым", то есть на эту физическую страницу больше никто нессылается, и ее можно вернуть в систему. См. Рис. 9.Это делается вызовом соответствующей функции (..mmdelete.. mmrelease..).Рис. 9. Возврат в систему "освобожденной" страницы.Следует отметить, что в элементе базы данных PFN есть поле, отвечающее за то,какая PTE была раньше у этой страницы, но это поле рассматривается диспетчеромпамяти, только в тот момент когда страниц была выгружена из памяти и ее пытаются37подгрузитьобратно.Посколькувданнойработерассматриваетсятольконеподкачиваемый пул, то содержимое этого поля не влияет в работу систему.2.2.3.5.
Разъединение страницТеперь система готова к работе и будет так работать до первой попытки записи наодну из страниц.В случае попытки записи на одну из страниц происходит исключение ошибкистраницы Page Fault, связанное с нарушением прав доступа. Поскольку нельзя писать встраницы помеченные как NonWritable и Copy On Write (то есть сброшен бит Writable ввзведен бит Copy On Write).Page Fault в случае запроса на записьКогда поступит запрос на запись:–Произойдет Page Fault–Вызовется обработчик этого исключения–Будет BSOD (Page Fault in NonPaged Memory) с извещением о том, чтопроизошел Page Fault in NonPaged Memory (исключение ошибки страницы внеподкачиваемом пуле памяти).=> Необходимо встроиться в обработчик Page Fault и там:–Предоставить новую страницу–Разъединить страницы, изменив их PTE так, чтобы виртуальный адрес, покоторому пытались произвести запись, ссылался теперь на выделенную физическуюстраниц.2.2.3.6.
Обработка Page FaultРассмотрим обработку исключения Page Fault для рассматриваемых страниц болееподробно.382.2.3.6.1. Предоставление новой страницыПрежде всего необходимо предоставить новую физическую страницу, копиюобщей, чтобы поток инициировавший запись, получил себе в пользование копию нужнойему страницы и мог совершить запись.
См. Рис. 10.Рис. 10. Предоставление новой страницы.2.2.3.6.2. Разъединение страниц , путем изменения их PTEИтак, когда новая страница выделена, наступает черед "разделения" страниц.Происходит "перемапирование" PTE с одной страницы на другую с изменениематрибутов. См. Рис. 11.•PTE 2-й страницы начинает ссылаться на предоставленную новую страницу•2-я страница становится Writable•1-я страница становится Writable, если на нее больше никто не ссылается.
Тоесть если объединены были всего две страницы, или не становится, если на нее ссылаетсяеще какая-нибудь страницы. Однако, что поскольку мы сами их на нее замапировали, томы знаем точное кол-во ссылающихся на нее страниц.39Рис. 11. Разъединение страниц, путем изменения их PTE.2.2.3.7. COW и высокие IRQL и связанные с ними проблемыПри предоставление новой страницы необходимо упомянуть об уровняхпрерываний. В зависимости от того, при каком IRQL работает система, изменяетсяповедение обработчика Page Fault:•Низкие IRQL – новая страница запрашивается у системы;•Высокие IRQL – новая страница берется из заранее подготовленного наборастраниц, который пополняется так часто, насколько это возможно.Размер этого заранее подготовленного набора страниц, называемого "резервнымбуфером страниц" определяется исходя из поведения драйвера и расчетов вматематической модели.
См. пункт "Математическая модель разъединения страниц".402.3. Математическая модель работы2.3.1. Основные положенияПоскольку целью работы является дедупликация исполняемого кода драйверов, тоесть уменьшение количества памяти занимаемой этими страницами, то, во-первых,необходимо подсчитать:Изменения кол-ва занимаемой памяти (минимальные, максимальные ивероятностные).2.3.1.1. Различные типы страниц памятиРассмотрим, какие типы страницбывают в драйверах, и в какие типы онипереходят потом в результате работы моей программы.Было N одинаковых драйверов с одинаковым кодом. Теперь, создается новыйнабор страниц, полностью в невыгружаемой памяти, драйверы виртуальные страницыдрайверов перемапируются на него, а их собственные страницы возвращаются в систему.Поделим все страницы на 4 типа (executable будем относить к тому же типу, что иread-only):NonPageable, read-onlyNonPageable, writeablePageable, read-only41Pageable, writableВ результате работы моей программы все страницы становятся NP, read-only неизменяются, а writeable переходят в COW.Рассмотрим, поподробнее, кол-во памяти занимаемое страницами каждого типа.Для них посчитаем минимальное, максимальное количество, а так же выведем требованияк вероятностной модели.А также, для каждого типа страниц подсчитаем изменение нагрузки на процессор,вызванной страницами этого типа, при работе моей программы.2.3.1.2.
NonPageable read-only страницыНеподкачиваемая память, только чтение. Это означает, во-первых, что не будетникаких проблем с высокими IRQL. А во-вторых, что поскольку, тут только чтение встраницах, резидентных в памяти, то их кол-во со временем не меняется. Следовательно,можно точно посчитать выгоду по памяти.Кроме того, следует отметить, что нагрузка на процессор не меняется, так какподкачки/отгрузки страниц нет.