mbind(2)

НАИМЕНОВАНИЕ
mbind - устанавливает политику на область памяти

БИБЛИОТЕКА
NUMA (Non-Uniform Memory Access) policy library (libnuma, -lnuma)

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

long mbind(unsigned long size, unsigned long maxnode;
           void addr[size], unsigned long size, int mode,
           const unsigned long nodemask[(maxnode + ULONG_WIDTH - 1)
/ ULONG_WIDTH],
           unsigned long maxnode, unsigned int flags);

ОПИСАНИЕ
mbind() sets the NUMA memory policy, which consists of a policy mode and zero or more nodes, for the memory range starting with addr and continuing for size bytes. The memory policy defines from which node memory is allocated.

If the memory range specified by the addr and size arguments includes an "anonymous" region of memory—that is a region of memory created using the mmap(2) system call with the MAP_ANONYMOUS—or a memory-mapped file, mapped using the mmap(2) system call with the MAP_PRIVATE flag, pages will be allocated only according to the specified policy when the application writes (stores) to the page. For anonymous regions, an initial read access will use a shared page in the kernel containing all zeros. For a file mapped with MAP_PRIVATE, an initial read access will allocate pages according to the memory policy of the thread that causes the page to be allocated. This may not be the thread that called mbind().

Указанная политика в заданной области памяти будет игнорироваться для всех отображений MAP_SHARED. Скорее всего, страницы будут выделены согласно политике памяти нити, для которой происходит выделение страницы. Но опять таки, это может быть не та нить, которая вызвала mbind().

Если заданная область памяти включает общую область памяти, созданную с помощью системного вызова shmget(2) и подключённую с помощью системного вызова shmat(2), то страницы, выделяемые для анонимной или общей области памяти, будут выделены согласно указанной политике, независимо от того, какой процесс подключил сегмент общей памяти, что вызвало выделение. Однако, если общая область памяти была создана с флагом SHM_HUGETLB, то огромные страницы будут выделяться согласно указанной политике, только если выделение страницы происходит из-за процесса, который вызвал mbind() для этой области.

По умолчанию, mbind() учитывается только при новых выделениях; если страницы внутри области уже были использованы до настройки политики, то политика не применяется. Такое поведение можно изменить с помощью флагов MPOL_MF_MOVE и MPOL_MF_MOVE_ALL, описанных далее.

The mode argument must specify one of MPOL_DEFAULT, MPOL_BIND, MPOL_INTERLEAVE, MPOL_WEIGHTED_INTERLEAVE, MPOL_PREFERRED, MPOL_PREFERRED_MANY, or MPOL_LOCAL (which are described in detail below). All policy modes except MPOL_DEFAULT require the caller to specify the node or nodes to which the mode applies, via the nodemask argument.

Аргумент mode также может содержать необязательный флаг режима. Поддерживаемые флаги режима:

MPOL_F_NUMA_BALANCING (начиная с Linux 5.15)
    When mode is MPOL_BIND, enable the kernel NUMA balancing for the task if it is supported by the kernel. If the flag isn't supported by the kernel, or is used with mode other than MPOL_BIND, -1 is returned and errno is set to EINVAL.

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) и у которого имеется память.

Аргумент mode должен включать одно из следующих значений:

MPOL_DEFAULT
    Этот режим запрашивает удаление любой политики не по умолчанию и восстановление поведения по умолчанию. Если он применяется к области памяти посредством mbind(), то это означает использование политики памяти нити, которая могла быть установлена с помощью set_mempolicy(2). Если режим политики памяти нити также равен MPOL_DEFAULT, то будет задействована системная политика по умолчанию. При системной политике по умолчанию выделяются страницы на том узле ЦП, на котором было запрошено выделение. Для MPOL_DEFAULT в аргументах nodemask и maxnode должен быть указан пустой набор узлов.

MPOL_BIND
    Этот режим задаёт жёсткую политику, при которой выделение памяти ограничено узлами, заданными в nodemask. Если в nodemask указано более одного узла, то выделение страниц начнётся с узла с достаточным объёмом свободной памяти, который наиболее близок к узлу, где запрошено выделение. Страницы не выделяются на узлах, не указанных в IR nodemask(до Linux 2.6.26 выделение страниц происходило начиная с узла с меньшим номером идентификатора, и продолжится до тех пор, пока на нём не кончится свободная память. Затем выделение продолжится на узле со следующим большим номером идентификатора, указанного в nodemask, и т.д. до тех пор, пока на всех заданных узлах не закончится свободная память).

MPOL_INTERLEAVE
    Этот режим задаёт, что при выделении страниц нужно выполнять чередование узлов, которые указаны в nodemask. Это оптимизирует использование полосы пропускания, но не задержку, вовлекая при доступ к страницам и памяти множество узлов. Чтобы это дало эффект, область памяти должна быть достаточно большой, не менее 1 МБ или более, и характер доступа должен быть достаточно равномерным. Доступ к одной странице области будет по прежнему ограничен размером полосы пропускания одного узла.

MPOL_WEIGHTED_INTERLEAVE (начиная с Linux 6.9)
    This mode interleaves page allocations across the nodes specified in nodemask according to the weights in /sys/kernel/mm/mempolicy/weighted_interleave. For example, if bits 0, 2, and 5 are set in nodemask, and the contents of /sys/kernel/mm/mempolicy/weighted_interleave/node0, /sys/.../node2, and /sys/.../node5 are 4, 7, and 9, respectively, then pages in this region will be allocated on nodes 0, 2, and 5 in a 4:7:9 ratio.

MPOL_PREFERRED
    В этом режиме устанавливается предпочтительный узел для выделения. Ядро сначала будет пытаться выделить страницы на этом узле и перейдёт на другие узлы, если на предпочтительном узле недостаточно свободной памяти. Если в nodemask задано более одного идентификатора узла, то в качестве предпочтительного будет выбран первый из маски. Если в аргументах nodemask и maxnode указан пустой набор, то память будет выделена на узле ЦП, на котором запросили выделение.

MPOL_PREFERRED_MANY (начиная с Linux 5.15)
    Specifies a set of nodes for allocation; see set_mempolicy(2).

MPOL_LOCAL (начиная с Linux 3.8)
    Этот режим устанавливает «локальное выделение»; памяти выделяется на узле с ЦП, на котором запросили выделение («локальный узел»). Аргументы nodemask и maxnode должны содержать пустой набор. Если на «локальном узле» не хватает свободной памяти, то ядро попытается выделить память на других узлах. Ядро выделит памяти на «локальном узле» сколько бы ни было на нём памяти. Если «локальный узел» не разрешён для нити текущим контекстом набора процессоров, то ядро попытается выделить память на других узлах. Ядро выделит памяти на «локальном узле» независимо от того, станет ли он разрешённым для нити текущим контекстом набора процессоров. В отличии от этого , MPOL_DEFAULT восстанавливает политику памяти нити (которая может быть задана с помощью set_mempolicy(2)); эта политика может быть другой, не «локальным выделением».

Если в flags указан MPOL_MF_STRICT и mode не равно MPOL_DEFAULT, то вызов завершается ошибкой EIO, если существующие страницы в области памяти не следуют политике.

If MPOL_MF_MOVE is specified in flags, then the kernel will attempt to move all the existing pages in the memory range so that they follow the policy. Pages that are shared with other processes will not be moved. If MPOL_MF_STRICT is also specified, then the call fails with the error EIO if some pages could not be moved. If the MPOL_INTERLEAVE policy was specified, pages already residing on the specified nodes will not be moved such that they are interleaved.

If MPOL_MF_MOVE_ALL is passed in flags, then the kernel will attempt to move all existing pages in the memory range regardless of whether other processes use the pages. The calling thread must be privileged (CAP_SYS_NICE) to use this flag. If MPOL_MF_STRICT is also specified, then the call fails with the error EIO if some pages could not be moved. If the MPOL_INTERLEAVE policy was specified, pages already residing on the specified nodes will not be moved such that they are interleaved.

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

ОШИБКИ

EFAULT
    Part or all of the memory range specified by nodemask and maxnode points outside your accessible address space. Or, there was an unmapped hole in the specified memory range specified by addr and size.

EINVAL
    An invalid value was specified for flags or mode; or addr + size was less than addr; or addr is not a multiple of the system page size. Or, mode is MPOL_DEFAULT and nodemask specified a nonempty set; or mode is MPOL_BIND or MPOL_INTERLEAVE and nodemask is empty. Or, maxnode exceeds a kernel-imposed limit. Or, nodemask specifies one or more node IDs that are greater than the maximum supported node ID. Or, none of the node IDs specified by nodemask are on-line and allowed by the thread's current cpuset context, or none of the specified nodes contain memory. Or, the mode argument specified both MPOL_F_STATIC_NODES and 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.

СТАНДАРТЫ
Linux.

ИСТОРИЯ
Linux 2.6.7.

Support for huge page policy was added with Linux 2.6.16. For interleave policy to be effective on huge page mappings the policied memory needs to be tens of megabytes or larger.

До Linux 5.7. MPOL_MF_STRICT игнорировался при отображении больших страниц.

Режимы MPOL_MF_MOVE и MPOL_MF_MOVE_ALL доступны только в Linux 2.6.16 и новее.

ПРИМЕЧАНИЯ
Информация о библиотеке доступна в numa(7).

Политика NUMA не поддерживается для области памяти отображения файла, который отображён с флагом MAP_SHARED.

Режим MPOL_DEFAULT может по разному влиять на mbind() и set_mempolicy(2). Когда указан MPOL_DEFAULT для set_mempolicy(2), политика памяти нити возвращается к политике по умолчанию или локальному выделению. Когда MPOL_DEFAULT указан для области памяти, используемой mbind(), все страницы, последовательно выделяемые для этой области, будут использовать политику памяти нити, которая задана с помощью set_mempolicy(2). Это эффективно удаляет явную политику из указанной области, «откатываясь» к возможной политике не по умолчанию. Для выбора явного «локального выделения» области памяти, укажите в mode значение MPOL_LOCAL или MPOL_PREFERRED с пустым набором узлов. Этот метод также сработает и в вызове set_mempolicy(2).

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

ПЕРЕВОД
Русский перевод этой страницы руководства разработал(и) aereiae <aereiae@gmail.com>, Alexey <a.chepugov@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Малянов Евгений Викторович <maljanow@outlook.com>

Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков (<debian-l10n-russian@lists.debian.org>).