MBIND(2)

ИМЯ
mbind - устанавливает политику на область памяти

ОБЗОР
#include <numaif.h>

long mbind(void *addr, unsigned long len, int mode,
           const unsigned long *nodemask, unsigned long maxnode,
           unsigned flags);

Компонуется при указании параметра -lnuma.

ОПИСАНИЕ
Вызов mbind() устанавливает политику памяти NUMA, состоящую из режима политики и нуля или более узлов, на область памяти, начинающуюся с addr и длиной len байт. Политикой памяти задаётся на каком узле будет выделяться память. Если область памяти, заданная аргументами addr и len, включает «анонимную» область памяти (область памяти, созданную с помощью системного вызова mmap(2) с аргументом MAP_ANONYMOUS) или файл, отображённый в память (с помощью вызова mmap(2) с флагом MAP_PRIVATE), то страницы будут выделены только в соответствии с указанной политикой, когда приложение выполняет запись (сохранение) страницы. Для анонимных областей при первоначальном доступе на чтение будет использоваться общая страница ядра, содержащая только нули. Для отображённого файла с флагом MAP_PRIVATE при первоначальном доступе на чтение будут выделены страницы в соответствии с политикой процесса, для которого происходит выделение страницы. Это может быть не тот же процесс, который вызвал mbind(). Указанная политика в заданной области памяти будет игнорироваться для всех отображений MAP_SHARED. Скорее всего, страницы будут выделены согласно политике процесса, для которого происходит выделение страницы. Но опять таки, это может быть не тот процесс, который вызвал mbind(). Если заданная область памяти включает общую область памяти, созданную с помощью системного вызова shmget(2) и подключённую с помощью системного вызова shmat(2), то страницы, выделяемые для анонимной или общей области памяти, будут выделены согласно указанной политике, независимо от того какой процесс подключил сегмент общей памяти, что вызвало выделение. Однако, если общая область памяти была создана с флагом SHM_HUGETLB, то огромные страницы будут выделяться согласно указанной политике, только если выделение страницы происходит из-за процесса, который вызвал mbind() для этой области. По умолчанию, mbind() учитывается только при новых выделениях; если страницы внутри области уже были использованы до настройки политики, то политика не применяется. Такое поведение можно изменить с помощью флагов MPOL_MF_MOVE и MPOL_MF_MOVE_ALL, описанных далее. В аргументе mode должно быть указано одно из следующих значений: MPOL_DEFAULT, MPOL_BIND, MPOL_INTERLEAVE или MPOL_PREFERRED. Для всех режимом политики, за исключением MPOL_DEFAULT требуется, чтобы вызывающий указывал в аргументе nodemask узел или узлы, для которых применяется режим. Аргумент mode также может содержать необязательный флаг режима. Поддерживаемые флаги режима:

MPOL_F_STATIC_NODES (начиная с Linux-2.6.26)
    В аргументе nodemask указываются идентификаторы физических узлов. Linux не пересоставляет nodemask, если процесс перемещается в другой контекст набора процессоров или когда изменяется набор узлов, который доступен процессу согласно текущему контексту набора процессоров.

MPOL_F_RELATIVE_NODES (начиная с Linux-2.6.26)
    В аргументе nodemask указываются идентификаторы узлов из набора идентификаторов узлов, разрешённых процессу текущим контекстом набора процессоров.

В nodemask содержится битовая маска узлов, в которой содержится до maxnode бит. Размер битовой маски округляется до следующего кратного значения sizeof(unsigned long), но ядром будет использовано только до maxnode бит. Значением NULL в nodemask или значением maxnode равным 0 задаётся пустой набор узлов. Если значение maxnode равно 0, то аргумент nodemask игнорируется. Там, где требуется nodemask, его значение должно содержать, как минимум, один работающий узел, который разрешён процессу текущим контекстом набора процессоров (если не указан флаг MPOL_F_STATIC_NODES) и у которого имеется память. В режиме MPOL_DEFAULT любая политика не по умолчанию удаляется и восстанавливается поведение по умолчанию. Если он применяется к области памяти посредством mbind(), то это означает использование политики процесса, которая могла быть установлена с помощью set_mempolicy(2). Если режим политики процесса также равен MPOL_DEFAULT, то будет задействована системная политика по умолчанию. При системной политике по умолчанию выделяются страницы на том узле ЦП, на котором было запрошено выделение. Для MPOL_DEFAULT в аргументах nodemask и maxnode должен быть указан пустой набор узлов. В режиме MPOL_BIND выделение памяти ограничено узлами, заданными в nodemask. Если в nodemask указано более одного узла, то выделение страниц начнётся с узла с меньшим номером идентификатора, и продолжится до тех пор, пока на нём не кончится свободная память. Затем выделение продолжится на узле со следующим большим номером идентификатора, указанного в nodemask, и т.д. до тех пор, пока на всех заданных узлах не закончится свободная память. Страницы не будут выделяться на узлах, не указанных в nodemask. В режиме MPOL_INTERLEAVE при выделении страниц выполняется чередование узлов, которые указаны в nodemask. Это оптимизирует использование полосы пропускания, но не задержку, вовлекая при доступ к страницам и памяти множество узлов. Чтобы это дало эффект, область памяти должна быть достаточно большой, не менее 1МБ или более, и характер доступа должен быть достаточно равномерным. Доступ к одной странице области будет по прежнему ограничен размером полосы пропускания одного узла. В режиме MPOL_PREFERRED устанавливается предпочтительный узел для выделения. Ядро сначала будет пытаться выделить страницы на этом узле и перейдёт на другие узлы, если на предпочтительном узле недостаточно свободной памяти. Если в nodemask задано более одного идентификатора узла, то в качестве предпочтительного будет выбран первый из маски. Если в аргументах nodemask и maxnode указан пустой набор, то память будет выделена на узле ЦП, на котором запросили выделение. Это единственный способ задать «локальное выделение» области памяти через mbind(). Если в flags указан MPOL_MF_STRICT и mode не равно MPOL_DEFAULT, то вызов завершится с ошибкой EIO, если существующие страницы в области памяти не следуют политике. Если в flags указан MPOL_MF_MOVE, то ядро будет пытаться переместить все существующие страницы в области памяти так, чтобы они следовали политике. Страницы, используемые совместно с другими процессами, перемещаться не будут. Если также указан MPOL_MF_STRICT, что вызов завершится с ошибкой EIO, если страницы не могут быть перемещены. Если в flags указан MPOL_MF_MOVE_ALL, то ядро будет пытаться переместить все существующие страницы в области памяти независимо от того, используются ли они другими процессами. Для использования данного флага вызывающий процесс должен иметь привилегированным (CAP_SYS_NICE). Если также указан MPOL_MF_STRICT, то вызов завершится с ошибкой EIO, если некоторые страницы нельзя переместить.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении mbind() возвращается 0. При ошибке возвращается -1, а в errno содержится код ошибки.

ОШИБКИ

EFAULT
    Часть или вся область памяти, заданная в nodemask и maxnode, указывает за пределы доступного адресного пространства. Или в области памяти, задаваемой addr и len, есть неотображаемая дыра (hole).

EINVAL
    В flags или mode указано неправильное значение; или addr + len меньше чем addr; или addr не кратен системному размеру страницы. Или mode равен MPOL_DEFAULT и в nodemask задан непустой набор; или mode равен MPOL_BIND или MPOL_INTERLEAVE и значение nodemask пусто. Или значение maxnode превышает устанавливаемый ядром предел. Или в nodemask задан один или более идентификаторов узлов, номер которого больше чем максимально поддерживаемый. Или в nodemask не задано ни одного идентификатора узла, разрешённого процессу текущим контекстом набора процессоров, или ни один из указанных узлов не содержит память. Или в аргументе mode указаны сразу MPOL_F_STATIC_NODES и MPOL_F_RELATIVE_NODES.

EIO Был указан MPOL_MF_STRICT и существующая страница была уже на узле, что не следует политике; или был указан MPOL_MF_MOVE или MPOL_MF_MOVE_ALL и ядро не смогло переместить все существующие страницы области.

ENOMEM
    Недостаточное количество памяти ядра.

EPERM
    Аргумент flags содержит флаг MPOL_MF_MOVE_ALL и вызывающий не имеет мандата CAP_SYS_NICE.

ВЕРСИИ
Системный вызов mbind() был добавлен в ядро Linux версии 2.6.7.

СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов есть только в Linux.

ЗАМЕЧАНИЯ
Информация о библиотеке доступна в numa(7). Политика NUMA не поддерживается для области памяти отображения файла, который отображён с флагом MAP_SHARED. Режим MPOL_DEFAULT может иметь различные эффекты для mbind() и set_mempolicy(2). Когда указан MPOL_DEFAULT для set_mempolicy(2), политика процесса возвращается к политике по умолчанию или локальному выделению. Когда MPOL_DEFAULT указан для области памяти, используемой mbind(), все страницы, последовательно выделяемые для этой области, будут использовать политику процесса, которая задана с помощью set_mempolicy(2). Это эффективно удаляет явную политику из указанной области, «откатываясь» к возможной политике не по умолчанию. Для выбора явного «локального выделения» области памяти, укажите в mode значение MPOL_PREFERRED с пустым набором узлов. Этот метод также сработает и в вызове set_mempolicy(2). Поддержка политики для огромных страниц была добавлена в версию 2.6.16. Для эффективной работы политики чередования на огромных страничных отображениях, контролируемая память должна измеряться десятками мегабайт или больше. Режим MPOL_MF_STRICT игнорируется для огромных страничных отображений. Режимы MPOL_MF_MOVE и MPOL_MF_MOVE_ALL доступны только в Linux 2.6.16 и новее.

СМОТРИТЕ ТАКЖЕ
get_mempolicy(2), getcpu(2), mmap(2), set_mempolicy(2), shmat(2), shmget(2), numa(3), cpuset(7), numa(7), numactl(8)