mbind - Définir la politique mémoire pour une zone de
mémoire
Bibliothèque de règles NUMA (Non-Uniform Memory Access) (
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() configure la politique mémoire NUMA, qui consiste en un
mode de politique et zéro ou plusieurs nœuds, pour l'intervalle
mémoire démarrant à
addr et s'étalant sur
len octets. La politique mémoire définit à partir
de quel nœud la mémoire sera allouée.
Si la plage mémoire spécifiée par les paramètres
addr et
len inclut une région
« anonyme » de mémoire (c'est-à-dire
une région de mémoire créée avec l'appel
système
mmap(2) et l'attribut
MAP_ANONYMOUS) ou un
fichier de mémoire projetée, projection créée en
utilisant l'appel système
mmap(2) et l'attribut
MAP_PRIVATE, les pages seront seulement allouées
conformément à la politique spécifiée lorsque
l'application écrit (enregistre) dans la page. Pour les régions
anonymes, un accès initial en lecture utilisera une page
partagée du noyau contenant des zéros. Pour un fichier
projeté avec
MAP_PRIVATE, un accès initial en lecture
allouera des pages conformément à la politique du thread qui a
fait que cette page a été allouée. Cela peut ne pas
être le thread qui a appelé
mbind().
La politique spécifiée sera ignorée pour toute projection
MAP_SHARED dans la plage mémoire spécifiée. Les
pages seront plutôt allouées conformément à la
politique de mémoire du thread qui a fait que la page a
été allouée. Cela peut ne pas être le thread qui a
appelé
mbind().
Si la plage de mémoire spécifiée inclut une région
de mémoire partagée créée avec l'appel
système
shmget(2) et attachée avec l'appel système
shmat(2), les pages allouées pour la région de
mémoire anonyme ou partagée seront allouées
conformément à la politique spécifiée, sans se
soucier du processus attaché au segment de mémoire
partagé qui a provoqué l'allocation. Si toutefois la
région de mémoire partagée a été
créée avec l'attribut
SHM_HUGETLB, les grosses pages
seront allouées conformément à la politique
spécifiée seulement si l'allocation de pages est
provoquée par le processus qui a appelé
mbind() pour
cette région.
Par défaut,
mbind() n'a d'effet que sur les nouvelles
allocations ; s'il y a déjà eu un accès aux pages
dans la plage avant de configurer la politique, alors la politique n'a pas
d'effet. Ce comportement par défaut peut être
écrasé par les attributs
MPOL_MF_MOVE et
MPOL_MF_MOVE_ALL décrits plus loin.
Le paramètre
mode doit spécifier l'un des attributs parmi
MPOL_DEFAULT,
MPOL_BIND,
MPOL_INTERLEAVE,
MPOL_PREFERRED ou
MPOL_LOCAL (qui sont décrits en
détails ci-dessous). Tous les modes de politique excepté
MPOL_DEFAULT nécessitent que l'appelant spécifie, dans le
paramètre
nodemask, le ou les nœuds auxquels s'appliquent
le mode.
L'argument
mode peut aussi contenir des attributs optionnels. Les valeurs
possibles sont :
-
MPOL_F_STATIC_NODES (depuis Linux 2.6.26)
- Un paramètre nodemask non vide indique des
identifiants de nœuds physiques. Linux ne réassocie pas
nodemask quand le thread change de contexte de cpuset ou
après une modification de l'ensemble de nœuds
autorisés par le contexte de cpuset en cours du thread.
-
MPOL_F_RELATIVE_NODES (depuis Linux 2.6.26)
- Un paramètre nodemask non vide indique des
identifiants de nœuds relatifs à l'ensemble des identifiants
de nœuds autorisés par le cpuset en cours du thread.
nodemask pointe sur un masque de bits qui contient jusqu'à
maxnode bits. La taille du masque de bits est arrondie au multiple
supérieur de
sizeof(unsigned long), mais le noyau n'utilisera
que jusqu'à
maxnode bits. Une valeur NULL pour
nodemask
ou une valeur
maxnode de zéro indique un ensemble vide de
nœuds. Si la valeur de
maxnode est zéro, l'argument
nodemask est ignoré. Quand un
nodemask est exigé,
il doit contenir au moins un nœud de connecté, autorisé
dans le contexte de cpuset en cours du thread appelant (à moins que le
drapeau
MPOL_F_STATIC_NODES ne soit fourni) et doit contenir de la
mémoire.
Le paramètre
mode doit contenir une des valeurs suivantes :
- MPOL_DEFAULT
- Ce mode demande à ce que toute politique
n'étant pas une politique par défaut soit retirée, ce
qui restaure le comportement par défaut. Lorsqu'il est
appliqué à une plage mémoire à l’aide
de mbind(), cela signifie d'utiliser la politique mémoire du
thread qui peut être définie avec set_mempolicy(2).
Si le mode de la politique de mémoire du thread est
également MPOL_DEFAULT, la politique par défaut du
système sera utilisée. La politique par défaut du
système alloue des pages sur le nœud du processeur qui a
déclenché l'allocation. Pour MPOL_DEFAULT, les
paramètres nodemask et maxnode doivent
spécifier l'ensemble vide de nœuds.
- MPOL_BIND
- Ce mode spécifie une politique stricte qui restreint
l'allocation mémoire aux nœuds indiqués dans
nodemask. Si nodemask indique plus d'un nœud, les
allocations de pages se feront à partir du nœud ayant assez
d'espace libre et étant le plus proche de celui où elles ont
lieu. Il n'y aura pas d'allocation de pages à partir de
nœuds non indiqués dans nodemask (avant Linux 2.6.26,
les allocations de pages se faisaient d'abord à partir du
nœud dont l'identifiant numérique était le plus petit
jusqu'à ce que ce nœud ne contienne plus de mémoire
libre. Les allocations se faisaient ensuite à partir du nœud
dont l'identifiant était le prochain plus grand
spécifié dans nodemask et ainsi de suite
jusqu'à ce que plus un seul nœud indiqué ne contienne
de mémoire libre).
- MPOL_INTERLEAVE
- Ce mode spécifie que les allocations de pages sont
entrelacées à travers l'ensemble de nœuds
spécifiés dans nodemask. Cela optimise la bande
passante au lieu de la latence en étalant les pages et
l'accès mémoire à ces pages à travers
plusieurs nœuds. Pour être efficace, la zone mémoire
doit être relativement grande, au moins 1 Mo ou plus avec un
modèle d'accès assez uniforme. Les accès à une
unique page de la zone seront toujours limités à la
capacité mémoire d'un seul nœud.
- MPOL_PREFERRED
- Ce mode définit le nœud
préféré pour les allocations. Le noyau essaiera
d'abord d'allouer sur ce nœud, avant de ce rabattre sur d'autres
nœuds si celui-ci n'a plus assez de mémoire libre. Si
nodemask précise plus d'un identifiant de nœud, le
premier nœud du masque sera choisi comme le nœud
préféré. Si les paramètres nodemask et
maxnode indiquent un ensemble vide, la mémoire est
allouée sur le nœud du processeur qui a
déclenché l'allocation.
-
MPOL_LOCAL (depuis Linux 3.8)
- Ce mode indique « allocation
locale » ; la mémoire est allouée sur
le nœud du processeur qui a déclenché l'allocation
(le « nœud local »). Les
paramètres nodemask et maxnode doivent indiquer un
ensemble vide. Si le « nœud local »
possède peu de mémoire libre, le noyau essaiera d'allouer de
la mémoire à partir d'autres nœuds. Le noyau allouera
de la mémoire du « nœud local »
à chaque fois qu'il y en aura de disponible. Si le
« nœud local » n'est pas
autorisé par le contexte de cpuset actuel du thread, le noyau
essaiera d'allouer de la mémoire à partir d'autres
nœuds. Le noyau allouera de la mémoire à partir du
« nœud local » à chaque fois
qu'il y sera autorisé par le contexte de cpuset actuel du thread.
Au contraire, MPOL_DEFAULT ramène à la politique
mémoire du thread (qui peut être définie par
set_mempolicy(2)) ; il peut s'agir d'une autre politique que
l'« allocation locale ».
Si l'option
MPOL_MF_STRICT est passée dans
flags et si
mode n'est pas
MPOL_DEFAULT, l'appel échoue avec l'erreur
EIO si les pages de la plage mémoire ne suivent pas la
politique.
Si
MPOL_MF_MOVE est passé dans
flags, le noyau essaiera de
déplacer toutes les pages existantes dans la plage de mémoire
pour qu'elles suivent la politique. Les pages partagées avec d'autres
processus ne sont pas déplacées. Si
MPOL_MF_STRICT est
également indiqué, l'appel échouera avec l'erreur
EIO si certaines pages ne peuvent pas être
déplacées.
Si
MPOL_MF_MOVE_ALL est indiqué dans
flags, alors le noyau
essaiera de déplacer toutes les pages existantes dans la plage
mémoire, même si d'autres processus les utilisent. Le thread
appelant doit être privilégié (avoir la capacité
CAP_SYS_NICE) pour utiliser cette option. Si
MPOL_MF_STRICT est
également utilisé, l'appel renverra l'erreur
EIO si
certaines pages ne peuvent pas être déplacées.
S'il réussit,
mbind() renvoie
0. En cas d'erreur, il
renvoie
-1 et remplit
errno avec la valeur d'erreur.
- EFAULT
- Une partie ou toute la plage mémoire
spécifiée par nodemask et maxnode pointe en
dehors de votre espace d'adressage accessible. Ou il y a eu un trou non
projeté dans la plage de mémoire spécifiée
avec addr et len.
- EINVAL
- Une valeur non valable a été
spécifiée pour flags ou mode ; ou
addr + len est plus petite que addr ; ou addr
n'est pas un multiple de la taille de page système. Ou, mode
est MPOL_DEFAULT et nodemask spécifiait un ensemble
non vide ; ou mode est MPOL_BIND ou
MPOL_INTERLEAVE et nodemask est vide. Ou, maxnode
dépasse une limite imposée par le noyau. Ou, nodemask
spécifie un ou plusieurs identifiants de nœud qui sont plus
grands que l'identifiant maximal de nœud pris en charge. Ou aucun
des identifiants de nœuds spécifiés par
nodemask ne sont disponibles et autorisés dans le contexte
de cpuset du thread en cours, ou aucun des nœuds
spécifiés ne contient de mémoire. Ou le
paramètre mode indiquait à la fois
MPOL_F_STATIC_NODES et MPOL_F_RELATIVE_NODES.
- EIO
-
MPOL_MF_STRICT a été utilisé et
une page existante était déjà sur un nœud ne
suivant pas la politique ; ou soit MPOL_MF_MOVE soit
MPOL_MF_MOVE_ALL a été spécifié et le
noyau n'a pas été capable de déplacer toutes les
pages existantes dans la plage.
- ENOMEM
- La mémoire disponible du noyau n'était pas
suffisante.
- EPERM
- Le paramètre flags incluait l'attribut
MPOL_MF_MOVE_ALL et l'appelant n'avait pas le privilège
CAP_SYS_NICE.
L'appel système
mbind() a été ajouté dans
Linux 2.6.7.
Cet appel système est spécifique à Linux.
Pour des informations sur la prise en charge des bibliothèques, consultez
numa(7).
La politique NUMA n'est pas gérée sur les plages de fichiers
projetés en mémoire qui ont été projetées
avec l'attribut
MAP_SHARED.
Le mode
MPOL_DEFAULT peut avoir des effets différents sur
mbind() et sur
set_mempolicy(2). Lorsque
MPOL_DEFAULT est
spécifié pour
set_mempolicy(2), la politique
mémoire du thread est remise à la politique par défaut du
système ou l'allocation locale. Lorsque
MPOL_DEFAULT est
spécifié pour une plage de mémoire utilisant
mbind(), toutes les pages allouées par la suite pour cette plage
utiliseront la politique du thread telle qu'elle a été
définie par
set_mempolicy(2). Cela supprime de manière
effective la politique explicite de la plage spécifiée, ce qui
peut éventuellement remettre une politique autre que celle par
défaut. Pour choisir explicitement une « allocation
locale » pour une plage mémoire, spécifiez
mode de
MPOL_LOCAL ou
MPOL_PREFERRED avec un ensemble
vide de nœuds. Cette méthode fonctionnera aussi avec
set_mempolicy(2).
La gestion de politique pour les pages immenses a été
ajoutée dans Linux 2.6.16. Pour que la politique d'entrelacement
soit efficace sur les projections de pages immenses, la taille de la zone
mémoire doit être au moins de dizaines de mégaoctets.
Avant Linux 5.7.
MPOL_MF_STRICT était ignoré sur les
projections de pages immenses.
MPOL_MF_MOVE et
MPOL_MF_MOVE_ALL ne sont disponibles qu'à
partir de 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)
La traduction française de cette page de manuel a été
créée par Christophe Blaess
<
https://www.blaess.fr/christophe/>, Stéphan Rafin
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]> et
Jean-Philippe MENGUAL <
[email protected]>
Cette traduction est une documentation libre ; veuillez vous reporter
à la
GNU
General Public License version 3 concernant les conditions de copie
et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message à
[email protected]