mremap
Table des matières
Retour à l'index
NOM
mremap - Modifier une projection de la mémoire virtuelle
BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)
SYNOPSIS
#define _GNU_SOURCE /* Consultez feature_test_macros(7) */
#include <sys/mman.h>
void *mremap(void old_address[.old_size], size_t old_size,
size_t new_size, int flags, ... /* void *new_address */);
DESCRIPTION
mremap() agrandit (ou diminue) une projection (Ndt : mapping) de mémoire
virtuelle en mémoire réelle, en la déplaçant éventuellement (sous contrôle
de l'argument flags et de la place disponible dans l'espace d'adressage
virtuel).
old_address est l'ancienne adresse du bloc de mémoire virtuelle à
agrandir (ou à diminuer). Veuillez noter que old_address doit être
alignée sur une frontière de page. old_size est l'ancienne taille du bloc
de mémoire virtuelle. new_size est la taille désirée pour le nouveau bloc
de mémoire. Un cinquième argument, new_address, peut éventuellement être
fourni ; voyez la description de MREMAP_FIXED ci-dessous.
Si la valeur de old_size est de zéro et si old_address renvoie à une
projection partageable (voir la description de MAP_SHARED dans
mmap(2)), mremap() créera une nouvelle projection des mêmes
pages. new_size sera la taille de la nouvelle projection et l'emplacement
de la nouvelle projection peut être indiqué avec new_address ; voir la
description de MREMAP_FIXED ci-dessous. Si une nouvelle projection est
demandée à l'aide de cette méthode, l'attribut MREMAP_MAYMOVE doit être
indiqué également.
L'argument de masquage flags est soit 0, soit un des attributs
suivants :
- MREMAP_MAYMOVE
-
Par défaut, s'il n'y a pas suffisamment d'espace pour agrandir une
projection à son emplacement actuel, mremap() échoue. Si ce drapeau est
utilisé, le noyau est autorisé à déplacer la projection à une autre adresse
virtuelle si nécessaire. Si la projection est déplacée, les pointeurs
absolus vers l'ancienne projection deviennent caduques (il faut utiliser des
décalages par rapport à l'adresse de début de la projection).
- MREMAP_FIXED (depuis Linux 2.3.31)
-
Ce drapeau a un but similaire à MAP_FIXED pour mmap(2). S'il est
utilisé, mremap() prend un cinquième argument void *new_address qui
contient une adresse alignée sur un début de page vers laquelle la
projection doit être déplacée. Toute projection existant précédemment dans
la zone entre new_address et new_size est supprimée.
-
Si MREMAP_FIXED est indiqué, MREMAP_MAYMOVE doit également être
indiqué.
- MREMAP_DONTUNMAP (depuis Linux 5.7)
-
Cet attribut, qui doit être utilisé avec MREMAP_MAYMOVE, refait une
projection vers une nouvelle adresse mais il ne supprime pas celle à
old_address.
-
L'attribut MREMAP_DONTUNMAP ne peut être utilisé qu'avec des projections
privées anonymes (voir la description de MAP_PRIVATE et de
MAP_ANONYMOUS dans mmap(2)).
-
À la fin, tous les accès à la plage indiquée par old_address et
old_size donneront une erreur de pagination. Elle sera gérée par un
gestionnaire userfaultfd(2) si l'adresse se situe dans une plage
précédemment enregistrée avec userfaultfd(2). Sinon, le noyau alloue une
page remplie de zéros pour gérer cette erreur.
-
L'attribut MREMAP_DONTUNMAP peut être utilisé pour déplacer de manière
atomique une projection tout en laissant la source associée. Voir les NOTES
pour des applications possibles de MREMAP_DONTUNMAP.
Si le segment de mémoire indiqué par old_address et old_size est
verrouillé (par mlock(2) ou similaire), ce verrou est maintenu quand le
segment est modifié et/ou déplacé. Par conséquent, la quantité de mémoire
verrouillée par le processus peut changer.
VALEUR RENVOYÉE
mremap() renvoie un pointeur sur la nouvelle zone de mémoire virtuelle
s'il réussit. En cas d'échec, la valeur MAP_FAILED (c'est-à-dire (void *) -1) est renvoyée et errno est défini pour indiquer l'erreur.
ERREURS
- EAGAIN
-
L'appelant a tenté d'agrandir un segment de mémoire verrouillé, mais c'est
impossible sans dépasser la limite RLIMIT_MEMLOCK.
- EFAULT
-
Une adresse dans l'intervalle entre old_address et
old_address+old_size n'est pas une adresse virtuelle valable pour ce
processus. On peut également obtenir EFAULT même s'il existe des
projections recouvrant la zone complète demandée, mais que ces projections
sont de types différents.
- EINVAL
-
Un paramètre non valable a été donné. Parmi les causes possibles :
-
- -
-
old_address n'était pas aligné sur une page ;
- -
-
une autre valeur que MREMAP_MAYMOVE, MREMAP_FIXED ou
MREMAP_DONTUNMAP a été indiquée dans flags ;
- -
-
new_size était zéro ;
- -
-
new_size ou new_address n'était pas valable ;
- -
-
la nouvelle plage d'adresses indiquée par new_address et new_size
chevauche l'ancienne plage d'adresses indiquée par old_address et
old_size ;
- -
-
MREMAP_FIXED ou MREMAP_DONTUNMAP était indiqué sans
MREMAP_MAYMOVE ;
- -
-
MREMAP_DONTUNMAP était indiqué mais une ou plusieurs pages de la plage
indiquée par old_address et old_size n'étaient pas privées et
anonymes ;
- -
-
MREMAP_DONTUNMAP était indiqué et old_size n'était pas égal à
new_size ;
- -
-
old_size était de zéro et old_address ne renvoie pas à une projection
partageable (mais voir BOGUES) ;
- -
-
old_size valait zéro et l'attribut MREMAP_MAYMOVE n'était pas indiqué.
- ENOMEM
-
Pas assez de mémoire disponible pour terminer l'opération. Les causes
possibles sont :
-
- -
-
La zone de mémoire ne peut pas être agrandie à l'emplacement virtuel actuel,
et l'option MREMAP_MAYMOVE n'a pas été fournie dans flags. Ou encore,
il n'y a plus assez de mémoire (virtuelle) disponible.
- -
-
MREMAP_DONTUNMAP a été utilisé, provoquant la création d'une nouvelle
projection qui dépasserait la mémoire (virtuelle) disponible. Ou alors elle
excéderait le nombre maximal de projections autorisées.
STANDARDS
Linux.
HISTORIQUE
Avant la glibc 2.4, glibc ne fournissait pas la définition de
MREMAP_FIXED et le prototype de mremap() ne permettait pas de passer
le paramètre new_address.
NOTES
mremap() modifie la correspondance entre les adresses virtuelles et les
pages de mémoire. Ce mécanisme peut être utilisé pour implémenter un
realloc(3) très efficace.
Sous Linux, la mémoire est divisée en pages. Un processus utilisateur
dispose d'un ou plusieurs segments linéaires de mémoire virtuelle. À chaque
segment correspond une ou plusieurs projections dans les pages de mémoire
réelle (dans la table des pages). Chaque segment de mémoire virtuelle
dispose de ses propres droits d'accès (sa protection), ce qui peut
déclencher des fautes de segmentation (SIGSEGV) si l'accès à la mémoire
est mal géré (par exemple, en écrivant dans un segment en lecture seule). De
même, une tentative d'accès à la mémoire en dehors des segments déclenche
une faute de segmentation.
Si mremap() est utilisé pour déplacer ou étendre une zone verrouillée
avec mlock(2) ou équivalent, l'appel mremap() fera le maximum pour
remplir la nouvelle zone mais il n'échouera pas avec ENOMEM si la zone ne
peut pas être remplie.
Cas d'utilisation de MREMAP_DONTUNMAP
Parmi les applications possibles de MREMAP_DONTUNMAP :
- -
-
userfaultfd(2) non coopératif : une application peut retirer une plage
d'adresses virtuelles en utilisant MREMAP_DONTUNMAP, puis utiliser un
gestionnaire userfaultfd(2) pour gérer les erreurs de pagination qui
arrivent ensuite lorsque d'autres threads du processus créent des pages dans
la plage retirée.
- -
-
Récupérateur de mémoire : MREMAP_DONTUNMAP peut être utilisé avec
userfaultfd(2) pour implémenter des algorithmes de ramasse-miettes
(garbage collection) (par exemple, dans une machine virtuelle Java). Une
telle implémentation peut être moins coûteuse (et plus simple) que les
techniques de collecte traditionnelles qui impliquent de marquer des pages
avec une protection PROT_NONE ainsi que l'utilisation d'un gestionnaire
SIGSEGV pour capter les accès à ces pages.
BOGUES
Avant Linux 4.14, si old_size valait zéro et si la projection à laquelle
renvoyait old_address était une projection privée (voir la description de
MAP_PRIVATE dans mmap(2)), mremap() créait une nouvelle projection
privée sans lien avec celle d'origine. Ce comportement était intentionnel et
probablement non prévu dans des applications de l'espace utilisateur
(l'intention de mremap() étant de créer une nouvelle projection à partir
de celle d'origine). Depuis Linux 4.14, mremap() échoue avec l'erreur
EINVAL dans ce scénario.
VOIR AUSSI
brk(2), getpagesize(2), getrlimit(2), mlock(2), mmap(2),
sbrk(2), malloc(3), realloc(3)
Votre manuel favori à propos de systèmes d'exploitation, pour des
informations supplémentaires sur la mémoire paginée (par exemple Modern Operating Systems de Andrew S. Tanenbaum, Inside Linux par Randolf
Bentson, The Design of the UNIX Operating System par Maurice J. Bach)
TRADUCTION
La traduction française de cette page de manuel a été créée par
Christophe Blaess <https://www.blaess.fr/christophe/>,
Stéphan Rafin <stephan.rafin@laposte.net>,
Thierry Vignaud <tvignaud@mandriva.com>,
François Micaux,
Alain Portal <aportal@univ-montp2.fr>,
Jean-Philippe Guérard <fevrier@tigreraye.org>,
Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>,
Julien Cristau <jcristau@debian.org>,
Thomas Huriaux <thomas.huriaux@gmail.com>,
Nicolas François <nicolas.francois@centraliens.net>,
Florentin Duneau <fduneau@gmail.com>,
Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,
Denis Barbier <barbier@debian.org>,
David Prévot <david@tilapin.org>
et
Jean-Philippe MENGUAL <jpmengual@debian.org>
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 à
Index
- NOM
-
- BIBLIOTHÈQUE
-
- SYNOPSIS
-
- DESCRIPTION
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- STANDARDS
-
- HISTORIQUE
-
- NOTES
-
- Cas d'utilisation de MREMAP_DONTUNMAP
-
- BOGUES
-
- VOIR AUSSI
-
- TRADUCTION
-
This document was created by
man2html,
using the manual pages.
Time: 05:06:03 GMT, September 19, 2025