freebsd shpgperproc за что отвечает?

Я много гуглил о том, за что отвечает «коэффициент общего доступа к странице для каждого процесса», и ничего не нашел. Мне это просто интересно, у меня пока нет проблем с этим, просто любопытно (хочу узнать больше). В sysctl это:

vm.pmap.shpgperproc

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


person milo    schedule 05.05.2012    source источник
comment
Я понял, что этот параметр влияет (возможно, я не уверен на 100%) на количество записей в pv... но как? Исходники ядра freebsd grep ничего не нашел. или я искал не так трудно.   -  person milo    schedule 05.05.2012


Ответы (2)


Первое, что нужно отметить, это то, что shpgperproc является настраиваемым загрузчиком, поэтому его можно установить только во время загрузки с помощью соответствующей директивы в loader.conf, и после этого он доступен только для чтения.

Второе, что следует отметить, это то, что он определен в <arch>/<arch>/pmap.c, который обрабатывает зависящие от архитектуры части подсистемы vm. В частности, его фактически нет в amd64 pmap.c — его убрали сравнительно недавно, и я расскажу об этом чуть ниже. Однако он присутствует для других архитектур (i386, arm, ...) и используется одинаково на каждой архитектуре; а именно, это выглядит следующим образом:

    void
    pmap_init(void)
    {
            ...
            TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
            pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;

и больше нигде не используется. pmap_init() вызывается только один раз: во время загрузки как часть инициализации подсистемы vm. maxproc — это просто максимальное количество процессов, которые могут существовать (т. е. kern.maxproc), а cnt.v_page_count — это просто количество доступных физических страниц памяти (т. е. vm.stats.v_page_count).

pv_entry — это в основном просто виртуальное отображение физической страницы (или, точнее, struct vm_page, поэтому, если два процесса совместно используют страницу и оба сопоставляют их, для каждого сопоставления будет отдельная структура pv_entry. Таким образом, заданная страница (struct vm_page) которые необходимо очистить или выгрузить, или что-то, требующее обновления таблицы страниц hw, список соответствующих отображаемых виртуальных страниц можно легко найти, просмотрев соответствующий список pv_entrys (в качестве примера взгляните на i386/i386/pmap.c:pmap_remove_all()).

Использование pv_entrys делает некоторые операции VM более эффективными, но текущая реализация (по крайней мере, для i386), по-видимому, выделяет статический объем пространства (см. pv_maxchunks, который устанавливается на основе pv_entry_max) для pv_chunks, которые используются для управления pv_entrys. Если ядро ​​не может выделить pv_entry после освобождения неактивных, оно паникует.

Таким образом, мы хотим установить pv_entry_max в зависимости от того, сколько pv_entry нам нужно для места; ясно, что нам нужно как минимум столько, сколько есть страниц ОЗУ (отсюда и cnt.v_page_count). Затем мы хотим учесть тот факт, что многие страницы будут многократно виртуально отображаться разными процессами, поскольку для каждого такого сопоставления необходимо выделить pv_entry. Таким образом, shpgperproc, значение которого по умолчанию равно 200 для всех арок, — это просто способ масштабирования. В системе, где многие страницы будут совместно использоваться процессами (скажем, на сильно загруженном веб-сервере с запущенным apache), вполне возможно исчерпать pv_entrys, поэтому нужно увеличить его.

person mark.johnston    schedule 06.05.2012
comment
еще один вопрос: может ли использование фрагментированной памяти увеличить потребление pv_entrys? - person milo; 11.05.2012
comment
Что ж, pv_entry выделяется для каждой отображаемой страницы, поэтому, если память фрагментирована с точностью меньше, чем размер страницы, то, по-видимому, да. - person mark.johnston; 16.05.2012

У меня сейчас нет поблизости компьютера с FreeBSD, но кажется, что этот параметр определен и используется в pmap.c, http://fxr.watson.org/fxr/ident?v=FREEBSD7&im=bigexcerpts&i=shpgperproc

person dmityugov    schedule 05.05.2012
comment
Итак, я обнаружил, что pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;, но sysctl FreeBSD имеет параметр vm.pmap.pv_entry_max. какая разница? - person milo; 05.05.2012
comment
может быть, shpgperproc влияет на начальное значение pv_entry_max, которое я смогу настроить позже? - person milo; 05.05.2012