zone_NORMAL и ZONE_HIGHMEM на 32 и 64-разрядных ядрах

#linux-kernel #virtual-memory

#linux-ядро #виртуальная память

Вопрос:

Я пытаюсь сделать управление памятью Linux немного более понятным для целей настройки и производительности.

Читая эту очень интересную redbook «Рекомендации по производительности и настройке Linux», найденную на веб-сайте IBM, я наткнулся на то, что я не до конца понимаю.

На 32-разрядных архитектурах, таких как IA-32, ядро Linux может напрямую обращаться только к первому гигабайту физической памяти (896 МБ с учетом зарезервированного диапазона). Память выше так называемой ZONE_NORMAL должна быть отображена в нижний 1 ГБ. Это сопоставление полностью прозрачно для приложений, но выделение страницы памяти в ZONE_HIGHMEM вызывает небольшое снижение производительности.

  1. почему память выше 896 МБ должна быть отображена в меньший 1 ГБ?
  2. Почему выделение страницы памяти в ZONE_HIGHMEM влияет на производительность?
  3. для чего тогда используется ZONE_HIGHMEM ?
  4. почему ядро, способное распознавать до 4 ГБ ( CONFIG_HIGHMEM=y ), может использовать только первый гигабайт?

Заранее спасибо

Ответ №1:

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

В IA-32, который допускает линейное адресное пространство объемом 4 ГБ, обычно первые 3 ГБ линейного адресного пространства выделяются пользовательскому процессу, а последний 1 ГБ линейного адресного пространства выделяется ядру.

Ядро должно использовать свой диапазон адресов в 1 ГБ, чтобы иметь возможность обращаться к любой части физической памяти, которая ему необходима. Память выше 896 МБ не «отображается в младший 1 ГБ» — происходит то, что физической памяти ниже 896 МБ присваивается постоянный линейный адрес в части ядра линейного адресного пространства, тогда как памяти выше этого предела должно быть назначено временное отображение в оставшейся части линейного адресного пространства.

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

Комментарии:

1. «В IA-32, который допускает линейное адресное пространство объемом 4 ГБ, обычно первые 3 ГБ линейного адресного пространства выделяются пользовательскому процессу, а последний 1 ГБ линейного адресного пространства выделяется ядру». Как это обычная схема распределения? Могу ли я выделить 2 ГБ пространства пользовательскому процессу и 2 ГБ ядру? И как?

2. @yegle: Вы можете изменить разделение пользователя и ядра во время сборки ядра. Вы, должно быть, ответили Y на EXPERIMENTAL вариант, после чего вы увидите выбор разделения пользователя / ядра (по умолчанию 3 ГБ / 1 ГБ, а также 2 ГБ / 2 ГБ и 1 ГБ / 3 ГБ).

3. @caf, у меня есть два вопроса. Q1: Когда происходит сбой, таблицы страниц не изменились. Таким образом, в ядре первые 3 ГБ указывают на память пользовательских процессов, а остальные — на ядро. Если это так, нужны ли нам какие-либо дополнительные настройки? Q2: Вы говорите, что «Ядро должно использовать свой диапазон адресов в 1 ГБ, чтобы иметь возможность обращаться к любой части физической памяти, которая ему необходима». Зачем ядру напрямую обращаться к физической памяти, когда есть MMU для преобразования виртуальных адресов в физические адреса?

4. @PaulDC: В качестве примера рассмотрим ядро, выполняющее read() запрос пользовательского пространства со страницы pagecache, которая находится в ZONE_HIGHMEM . Для этого она должна быть скопирована со страницы кэша страниц в предоставленный буфер пользовательского пространства, что означает, что она должна иметь возможность обращаться к странице кэша страниц, поэтому она должна быть где-то отображена в адресное пространство ядра.