Комментарии 17
Если операционная система изменила PID процесса — потому что и ASID станет другим
Смена PID процесса — это что-то из области фантастики. Линуксные порты на архитектуры с ASID обычно назначают ASID динамически, например так: существует глобальный счётчик, разрядностью больше, чем аппаратный ASID. Когда нужен новый ASID счётчик увеличивается на 1, переполнение разрядов аппаратного ASID вызывает сброс TLB. Каждое адресное пространство (может быть одно у нескольких задач, например если это потоки одного приложения или ядра) описывается структурой, содержащей текущий назначенный ему ASID. Всякий раз, когда нужно активировать адресное пространство, старшие биты его ASID сравниваются с глобальным счётчиком. Если совпадают — ничего делать не надо, если нет — значит было переполнение, TLB был сброшен и адресному пространству нужен новый ASID.
Если нужной записи в TLB нет, то приходится искать ее в таблицах страниц, которые операционная система размещает в нетранслируемой области ОЗУ
В некоторых архитектурах (например xtensa) при наличии MMU трансляция выполняется всегда, но TLB состоит из двух частей: часть строк обновляется и программно и аппаратно, другая только программно. ОС должна поместить в правильное место TLB запись для каталога таблиц страниц.
Третий способ — избегать синонимов программно. Например, не использовать общие страницы. Или снова начать линковать программы в общее адресное пространство.
Или выделять регионы виртуальной памяти для общих страниц по адресам, кратным размеру канала кэша (так, что одинаковые смещения в регионе попадут в одинаковые строки кэша, даже для разных процессов). А при необходимости отобразить физическую страницу в пространство ядра, отображать её с учётом её кэш-цвета, т.е. по виртуальному адресу, младшие биты которого, в пределах размера канала кэша совпадают с физическим адресом страницы.
Хорошо пишите, интересно!
НЛО прилетело и опубликовало эту надпись здесь
Спасибо, интересно. А какие архитектуры кроме ARM используют VIVT кэш?
достаточно знать, что ее загружает операционная система. Она же добавляет запись в таблицу страниц (но не в TLB),Уже в который раз натыкаюсь на такое объяснение, но не пойму, что это еще за одна таблица и что именно в ней хранится.
Грубо говоря, таблица страниц — это структура данных, в которой содержатся сведения о том, по каким физическим адресам в памяти расположены виртуальные страницы (и расположены ли они вообще — они могут быть не в оперативке, а на диске), права доступа к ним и т.д.
Только операционная система может добавлять или удалять записи из этой таблицы. Каждая запись соответствует одной странице, поэтому записей очень много и таблица занимает много места. Кроме как в оперативную память поместить ее некуда, т.к. ее размер может быть несколько мегабайт. TLB — это как кэш-память для этой огромной таблицы, TLB хранит несколько наиболее часто используемых записей.
Только операционная система может добавлять или удалять записи из этой таблицы. Каждая запись соответствует одной странице, поэтому записей очень много и таблица занимает много места. Кроме как в оперативную память поместить ее некуда, т.к. ее размер может быть несколько мегабайт. TLB — это как кэш-память для этой огромной таблицы, TLB хранит несколько наиболее часто используемых записей.
Промахнулся :)
У меня есть вопрос по поводу того, «что именно делает MMU».
Вы пишете:
Я спрашиваю, потому что этот момент — момент того, что именно делает MMU для меня до сих пор остается загадкой. В приведенной цитате либо Вы ошибаетесь, либо я чего-то недопонимаю. Объясняю: page_fault это прерывание, которое возникает, если MMU лезет в таблицы (которые в ОЗУ) и не находит нужный PTE и физический адрес, вместо этого адреса там будет стоять флаг, что страница засвапирована, и её положение на диске. После этого возникает page fault и программный обработчик вытаскивает страницу с диска в память, физический адрес заносится в ту PTE и попытка трансляции повторяется. Так, что как я понимаю к TLB это вообще отношение имеет довольно косвенное…
Что я до конца не понимаю: когда виртуальный адрес приходит к MMU, MMU нужно его преобразовать в физический. Это делается, как Вы уже говорили, через те самые таблицы (PGD->PMD->PTE в Linux). При смене контекста в регистр CR3 (x86) кладется адрес таблиц для конкретного процесса (у каждого процесса свои таблицы преобразования виртуальных адресов в физические), отсюда MMU знает адрес таблиц в ОЗУ. Дальше MMU должна по идее сделать несколько обращений к памяти, чтобы пройти по иерархии PGD->PMD->PTE и вытащить физический адрес. Как выполняются эти обращения? В MMU есть какая-то аппаратная часть которая на вход контроллера памяти выдает запрос на чтение, или это как — то делается через процессор? Помогите мне понять. Спасибо.
Вы пишете:
Если нужной записи в TLB нет, то приходится искать ее в таблицах страниц, которые операционная система размещает в нетранслируемой области ОЗУ (чтобы не было промаха TLB при обработке предыдущего промаха). Поиск может быть реализован как аппаратно, так и программно — через обработчик исключения, называемого страничной ошибкой (page fault). Найденная запись добавляется в TLB, после чего команда, вызвавшая промах TLB, выполняется снова.
Я спрашиваю, потому что этот момент — момент того, что именно делает MMU для меня до сих пор остается загадкой. В приведенной цитате либо Вы ошибаетесь, либо я чего-то недопонимаю. Объясняю: page_fault это прерывание, которое возникает, если MMU лезет в таблицы (которые в ОЗУ) и не находит нужный PTE и физический адрес, вместо этого адреса там будет стоять флаг, что страница засвапирована, и её положение на диске. После этого возникает page fault и программный обработчик вытаскивает страницу с диска в память, физический адрес заносится в ту PTE и попытка трансляции повторяется. Так, что как я понимаю к TLB это вообще отношение имеет довольно косвенное…
Что я до конца не понимаю: когда виртуальный адрес приходит к MMU, MMU нужно его преобразовать в физический. Это делается, как Вы уже говорили, через те самые таблицы (PGD->PMD->PTE в Linux). При смене контекста в регистр CR3 (x86) кладется адрес таблиц для конкретного процесса (у каждого процесса свои таблицы преобразования виртуальных адресов в физические), отсюда MMU знает адрес таблиц в ОЗУ. Дальше MMU должна по идее сделать несколько обращений к памяти, чтобы пройти по иерархии PGD->PMD->PTE и вытащить физический адрес. Как выполняются эти обращения? В MMU есть какая-то аппаратная часть которая на вход контроллера памяти выдает запрос на чтение, или это как — то делается через процессор? Помогите мне понять. Спасибо.
Да, закралась неточность. Вместо «Поиск может быть реализован как аппаратно, так и программно — через обработчик исключения, называемого страничной ошибкой (page fault)» следует читать «Поиск может быть реализован как аппаратно, так и программно — через обработчик исключения, называемого промахом TLB (TLB miss)».
Соответственно, в случае программно реализованного поиска проход по иерархии таблиц (PGD->PMD->PTE в вашем случае) осуществляет обработчик промаха TLB (и уже из него можно прыгнуть в обработчик page fault-а). В случае аппаратно реализованного поиска в MMU добавляется специальная логика, которая делает то же самое, но быстрее. Но такое железо гораздо сложнее и вдобавок жестко завязано на конкретную структуру таблиц, то есть могут возникнуть проблемы с поддержкой операционок с нестандартной иерархией таблиц.
Соответственно, в случае программно реализованного поиска проход по иерархии таблиц (PGD->PMD->PTE в вашем случае) осуществляет обработчик промаха TLB (и уже из него можно прыгнуть в обработчик page fault-а). В случае аппаратно реализованного поиска в MMU добавляется специальная логика, которая делает то же самое, но быстрее. Но такое железо гораздо сложнее и вдобавок жестко завязано на конкретную структуру таблиц, то есть могут возникнуть проблемы с поддержкой операционок с нестандартной иерархией таблиц.
Спасибо! Читая книгу Таненбаума, у меня возник резонный вопрос: "А как быть, если в ОС крутятся несколько процессов и все они захотят обратиться к определенному месту в памяти?" Судя по изложенному там материалу, при обращении к одному адресу они должны были бы обратиться к одному адресу в физической памяти. "Но это полный бред" - подумал я и пошел гуглить. Благо наткнулся на вашу статью, где вы разъяснили по ASID. Жаль в книге об этом ни слова.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
MMU в картинках (часть 1)