mbind -
устанавливает
политику
на область
памяти
NUMA (Non-Uniform Memory Access) policy library (
libnuma,
-lnuma)
#include <numaif.h>
long mbind(void addr[.len], unsigned long len, int mode,
const unsigned long nodemask[(.maxnode + ULONG_WIDTH - 1)
/ ULONG_WIDTH],
unsigned long maxnode, unsigned int flags);
Вызов
mbind()
устанавливает
политику
памяти NUMA,
состоящую
из режима
политики и
нуля или
более
узлов, на
область
памяти,
начинающуюся
с
addr и длиной
len байт.
Политикой
памяти
задаётся
на каком
узле будет
выделяться
память.
If the memory range specified by the
addr and
len 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,
описанных
далее.
В
аргументе
mode должно
быть
указано
одно из
следующих
значений:
MPOL_DEFAULT,
MPOL_BIND,
MPOL_INTERLEAVE,
MPOL_PREFERRED или
MPOL_LOCAL
(описано
далее). Для
всех
режимов
политики,
за
исключением
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) и у
которого
имеется
память.
Аргумент
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_PREFERRED
- В этом
режиме
устанавливается
предпочтительный
узел для
выделения.
Ядро
сначала
будет
пытаться
выделить
страницы
на этом
узле и
перейдёт
на другие
узлы, если
на
предпочтительном
узле
недостаточно
свободной
памяти.
Если в nodemask
задано
более
одного
идентификатора
узла, то в
качестве
предпочтительного
будет
выбран
первый из
маски. Если
в
аргументах
nodemask и maxnode
указан
пустой
набор, то
память
будет
выделена
на узле ЦП,
на котором
запросили
выделение.
-
MPOL_LOCAL
(начиная с Linux
3.8)
- Этот
режим
устанавливает
«локальное
выделение»;
памяти
выделяется
на узле с
ЦП, на
котором
запросили
выделение
(«локальный
узел»).
Аргументы
nodemask и maxnode
должны
содержать
пустой
набор. Если
на
«локальном
узле» не
хватает
свободной
памяти, то
ядро
попытается
выделить
память на
других
узлах. Ядро
выделит
памяти на
«локальном
узле»
сколько бы
ни было на
нём памяти.
Если
«локальный
узел» не
разрешён
для нити
текущим
контекстом
набора
процессоров,
то ядро
попытается
выделить
память на
других
узлах. Ядро
выделит
памяти на
«локальном
узле»
независимо
от того,
станет ли
он
разрешённым
для нити
текущим
контекстом
набора
процессоров.
В отличии
от этого ,
MPOL_DEFAULT
восстанавливает
политику
памяти
нити
(которая
может быть
задана с
помощью
set_mempolicy(2)); эта
политика
может быть
другой, не
«локальным
выделением».
Если в
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.
The
mbind() system call was added in 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_LOCAL или
MPOL_PREFERRED с
пустым
набором
узлов. Этот
метод
также
сработает
и в вызове
set_mempolicy(2).
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.
Before Linux 5.7.
MPOL_MF_STRICT was ignored on huge page mappings.
Режимы
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)
Русский
перевод
этой
страницы
руководства
был сделан
aereiae <
[email protected]>, Alexey <
[email protected]>, Azamat
Hackimov <
[email protected]>, Dmitriy S. Seregin
<
[email protected]>, Dmitry Bolkhovskikh <
[email protected]>,
ITriskTI <
[email protected]>, Max Is <
[email protected]>, Yuri
Kozlov <
[email protected]>, Иван
Павлов <
[email protected]>
и Малянов
Евгений
Викторович
<
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]