mlock(2) System Calls Manual mlock(2) NOM mlock, mlock2, munlock, mlockall, munlockall - Verrouiller et deverrouiller la memoire BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include int mlock(const void addr[.len], size_t len); int mlock2(const void addr[.len], size_t len, unsigned int flags); int munlock(const void addr[.len], size_t len); int mlockall(int flags); int munlockall(void); DESCRIPTION mlock(), mlock2() et mlockall() verrouillent tout ou partie de l'espace d'adressage du processus appelant dans la memoire physique pour empecher cette memoire d'etre evincee dans l'espace d'echange (swap). munlock() et munlockall() ont l'effet inverse, respectivement deverrouillant une partie ou l'ensemble de l'espace d'adressage du processus appelant, afin que les pages dans la zone indiquee puissent a nouveau etre evincees dans l'espace d'echange si le gestionnaire de memoire du noyau l'exige. Le verrouillage et le deverrouillage de la memoire s'effectuent sur des unites de page entiere. mlock(), mlock2() et munlock() mlock() verrouille les pages sur len octets a partir de l'adresse addr. Toutes les pages qui contiennent une partie de la zone memoire indiquee ont la garantie de resider en memoire principale quand l'appel reussit ; elles ont la garantie de rester en memoire principale jusqu'a leur deverrouillage. mlock() verrouille aussi les pages de la plage indiquee sur len octets a partir de l'adresse addr. Neanmoins, l'etat des pages contenues dans cette plage apres un appel reussi dependra de la valeur du parametre flags. L'argument flags peut etre 0 ou la constante suivante : MLOCK_ONFAULT Verrouiller les pages actuellement residentes et marquer toute la plage pour que le reste des pages non residentes se verrouillent quand elles se remplissent d'erreurs de pagination. Si flags vaut 0, mlock2() se comporte exactement comme mlock(). munlock() deverrouille la memoire sur len octets a partir de l'adresse addr. Apres cet appel, toutes les pages contenant une partie de la zone memoire indiquee peuvent de nouveau etre evincees dans l'espace d'echange par le noyau. mlockall() et munlockall() mlockall() verrouille toutes les pages projetees dans l'espace d'adressage du processus appelant. Cela inclut les pages de code, de donnees et de pile, ainsi que les bibliotheques partagees, les donnees utilisateur dans le noyau, la memoire partagee, et les fichiers projetes en memoire. Toutes les pages projetees ont la garantie de resider en memoire principale quand l'appel reussit ; elles ont la garantie de rester en memoire principale jusqu'a leur deverrouillage. L'argument flags est compose d'un OU binaire avec les options suivantes : MCL_CURRENT Verrouiller toutes les pages actuellement projetees dans l'espace d'adressage du processus. MCL_FUTURE Verrouiller toutes les pages qui seront projetees dans l'espace d'adressage du processus dans le futur. Il peut s'agir, par exemple, de nouvelles pages necessitees par la croissance du tas et de la pile, ou de nouveaux fichiers projetes en memoire, ou des zones de memoire partagee. MCL_ONFAULT (depuis Linux 4.4) Utilise avec MCL_CURRENT, MCL_FUTURE ou les deux. Marquer toutes les projections actuelles (avec MCL_CURRENT) ou futures (avec MCL_FUTURE) pour verrouiller les pages quand elles contiennent des erreurs. Si on l'utilise avec MCL_CURRENT, toutes les pages presentes sont verrouillees mais mlockall() ne rencontrera pas d'erreur sur des pages non presentes. Quand on l'utilise avec MCL_FUTURE, toutes les projections futures seront marquees pour verrouiller les pages quand elles rencontreront une erreur, mais elles ne seront pas remplies par le verrou lors de la creation de la projection. MCL_ONFAULT doit etre utilise avec MCL_CURRENT, MCL_FUTURE ou les deux. Si MCL_FUTURE a ete utilise, un appel systeme ulterieur (p.ex. mmap(2), sbrk(2), malloc(3)) risque d'echouer s'il cause un depassement du nombre d'octets verrouilles autorise (voir ci-dessous). Dans les memes circonstances, la croissance de la pile risque egalement d'echouer : le noyau interdira l'augmentation de la pile et enverra le signal SIGSEGV au processus. munlockall() deverrouille toutes les pages projetees dans l'espace d'adressage du processus appelant. VALEUR RENVOYEE S'ils reussissent, ces appels systeme renvoient 0. En cas d'erreur, ils renvoient -1, errno est positionne pour indiquer l'erreur et les verrouillages de l'espace d'adressage du processus ne sont pas modifies. ERREURS EAGAIN (mlock(), mlock2() et munlock()) Une partie (ou l'ensemble) de l'espace d'adressage indique n'a pas pu etre verrouillee. EINVAL (mlock(), mlock2() et munlock()) La somme de addr+len etait inferieure a addr (l'addition aurait pu conduire a un depassement par exemple). EINVAL (mlock2()) Des flags inconnus etaient demandes. EINVAL (mlockall()) Des flags inconnus ont ete indiques ou MCL_ONFAULT a ete indique sans MCL_FUTURE ou MCL_CURRENT. EINVAL (Pas sous Linux) addr n'est pas un multiple de la taille de la page. ENOMEM (mlock(), mlock2() et munlock()) Une partie de la zone indiquee ne correspond pas a des pages projetees dans l'espace d'adressage du processus. ENOMEM (mlock(), mlock2() et munlock()) Le verrouillage ou le deverrouillage d'une region ferait depasser le nombre maximum de projections permises ayant des attributs distincts (comme verrouille contre deverrouille). Par exemple, le deverrouillage d'une plage situee au milieu d'une projection actuellement verrouillee donnerait trois projections : deux verrouillees de chaque cote et une deverrouillee au milieu. ENOMEM (Linux 2.6.9 et plus recents) L'appelant avait une limite souple RLIMIT_MEMLOCK non nulle, mais a tente de verrouiller plus de memoire que la quantite autorisee. Cette limite n'est pas imposee si le processus est privilegie (CAP_IPC_LOCK). ENOMEM (Linux 2.4 et precedents) Le processus appelant a essaye de verrouiller plus de la moitie de la memoire vive. EPERM L'appelant n'est pas privilegie mais a besoin de droits (CAP_IPC_LOCK) pour realiser les operations demandees. EPERM (munlockall()) (Linux 2.6.8 et precedents) L'appelant n'est pas privilegie (CAP_IPC_LOCK). VERSIONS Linux Sous Linux, mlock(), mlock2() et munlock() arrondissent automatiquement addr a la frontiere de page la plus proche. Toutefois, la specification POSIX.1 de mlock() et de munlock() permet a l'implementation d'imposer que addr soit alignee sur une frontiere de page. Les applications portables devraient s'en assurer. Le champ VmLck du fichier /proc/pid/status specifique a Linux indique le nombre de kilooctets de memoire que le processus d'identifiant PID a verrouille en utilisant mlock(), mlock2(), mlockall() et MAP_LOCKED de mmap(2). STANDARDS mlock() munlock() mlockall() munlockall() POSIX.1-2008. mlock2() Linux. Sur les systemes POSIX ou mlock() et munlock() sont disponibles, la constante symbolique _POSIX_MEMLOCK_RANGE est definie dans et le nombre d'octets par page peut etre determine grace a la constante PAGESIZE si definie dans ou en appelant sysconf(_SC_PAGESIZE). Sur les systemes POSIX sur lesquels mlockall() et munlockall() sont disponibles, la constante symbolique _POSIX_MEMLOCK est definie dans comme etant une valeur superieure a 0. (Consultez aussi sysconf(3).) HISTORIQUE mlock() munlock() mlockall() munlockall() POSIX.1-2001, POSIX.1-2008, SVr4. mlock2() Linux 4.4, glibc 2.27. NOTES Il y a deux domaines principaux d'applications du verrouillage de pages : les algorithmes en temps reel et le traitement de donnees confidentielles. Les applications temps reel reclament un comportement temporel deterministe, et la pagination est, avec l'ordonnancement, une cause majeure de delais imprevus. Ces algorithmes basculent habituellement sur un ordonnancement temps-reel avec sched_setscheduler(2). Les logiciels de cryptographie manipulent souvent quelques octets hautement confidentiels, comme des mots de passe ou des cles privees. A cause de la pagination, ces donnees secretes risquent d'etre transferees sur un support physique ou elles pourraient etre lues par un ennemi longtemps apres que le logiciel se soit termine. Soyez toutefois conscient que le mode suspendu sur les portables et certains ordinateurs de bureau sauvegardent une copie de la memoire sur le disque, quels que soient les verrouillages. Les processus temps-reel utilisant mlockall() pour eviter les delais dus a la pagination doivent reserver assez de pages verrouillees pour la pile avant d'entrer dans la section temporellement critique, afin qu'aucun defaut de page ne survienne lors d'un appel de fonction. Cela peut etre obtenu en appelant une fonction qui alloue une variable automatique suffisamment grande (comme un tableau) et ecrit dans la memoire occupee par ce tableau afin de modifier ces pages de pile. Ainsi, suffisamment de pages seront projetees pour la pile et pourront etre verrouillees. Les ecritures bidon permettent de s'assurer que meme les pages copiees a l'ecriture ne causeront pas de defaut de page dans la section critique. Les verrouillages de memoire ne sont pas recuperes par un enfant lors d'un fork(2) et sont automatiquement supprimes (deverrouilles) au cours d'un execve(2) ou lorsque le processus se termine. Les parametres MCL_FUTURE et MCL_FUTURE | MCL_ONFAULT de mlockall() ne sont pas recuperes par un enfant cree par fork(2) et sont effaces au cours d'un execve(2). Remarquez que fork(2) preparera l'espace d'adressage pour une operation copie-en-ecriture. La consequence est que tout acces en ecriture consecutif creera une erreur de pagination qui, elle-meme, peut causer des latences importantes dans un processus en temps reel. Il est donc crucial de ne pas appeler fork(2) apres des operations mlockall() ou mlock() ; meme a partir d'un thread qui tourne en priorite basse dans un processus dont un thread tourne en priorite haute. Le verrouillage de memoire sur une zone est automatiquement enleve si la zone est invalidee par munmap(2). Il n'y a pas d'empilement des verrouillages memoire, ce qui signifie qu'une page verrouillee plusieurs fois par des appels mlock(), mlock2() ou mlockall() sera liberee en un seul appel a munlock() pour la zone memoire correspondante ou par un appel a munlockall(). Les pages qui sont projetees a plusieurs endroits ou par plusieurs processus restent verrouillees en memoire vive tant qu'il y a au moins un processus ou une zone qui les verrouille. Si un appel a mlockall(), qui utilise l'attribut MCL_FUTURE, est suivi d'un autre appel qui n'indique pas cet attribut, les changements effectues par l'appel MCL_FUTURE seront perdus. L'attribut MLOCK_ONFAULT de mlock2() et celui MCL_ONFAULT de mlockall() permettent un verrouillage efficace de la memoire pour les applications qui ont a faire a de grandes projections ou seulement une (petite) partie des pages de la projection sont modifiees. Dans ce cas, le verrouillage de toutes les pages d'une projection risquerait une sanction lourde de verrouillage de memoire. Limites et permissions Sous Linux 2.6.8 et precedents, un processus doit etre privilegie (CAP_IPC_LOCK) pour verrouiller de la memoire et la limite souple RLIMIT_MEMLOCK definit le nombre maximal d'octets que le processus peut verrouiller en memoire. Depuis Linux 2.6.9, aucune limite n'est placee sur la quantite de memoire pouvant etre verrouillee par un processus privilegie, et la limite souple RLIMIT_MEMLOCK definit la quantite maximale de memoire pouvant etre verrouillee par un processus non privilegie. BOGUES Dans Linux 4.8 et anterieurs, un bogue dans le calcul par le noyau de la memoire verrouillee pour les processus non privilegies (a savoir sans CAP_IPC_LOCK) faisait que si la region indiquee par addr et len incluait un verrou existant, les octets deja verrouilles dans la region incluante etaient comptes deux fois lors de la verification de leur atteinte de limite. Un tel double comptage calculerait mal une valeur de << memoire verrouillee totale >> du processus qui a depasse la limite RLIMIT_MEMLOCK, si bien que mlock() et mlock2() echoueraient sur des requetes qui auraient du reussir. Ce bogue a ete corrige dans Linux 4.9. Dans Linux de la branche 2.4 des noyaux, jusqu'a Linux 2.4.17 inclus, le parametre MCL_FUTURE de mlockall() etait herite par l'enfant apres un fork(2) en raison d'un bogue. Cela a ete corrige dans Linux 2.4.18. Depuis Linux 2.6.9, si un processus privilegie appelle mlockall(MCL_FUTURE) et reduit ses privileges plus tard (perd la capacite CAP_IPC_LOCK, par exemple en prenant un UID effectif non nul), les allocations de memoires suivantes (p.ex. mmap(2), brk(2)) echoueront si la limite RLIMIT_MEMLOCK est depassee. VOIR AUSSI mincore(2), mmap(2), setrlimit(2), shmctl(2), sysconf(3), proc(5), capabilities(7) TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.8 2 mai 2024 mlock(2)