jammy (2) mremap.2.gz

Provided by: manpages-fr-dev_4.13-4_all bug

NOM

       mremap - Modifier une projection de la mémoire virtuelle

SYNOPSIS

       #define _GNU_SOURCE         /* Consultez feature_test_macros(7) */
       #include <sys/mman.h>

       void *mremap(void *old_address, 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
       MAP_SHARED  de 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 contient le code d'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.

CONFORMITÉ

       Cet  appel  système  est spécifique à Linux et ne devrait pas être employé dans des programmes destinés à
       être portables.

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.

       Avant la version 2.4, la 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.

   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) (comme 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 qu'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 (MAP_PRIVATE de 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)

COLOPHON

       Cette page fait partie de la publication 5.10 du projet man-pages Linux. Une description du projet et des
       instructions  pour  signaler  des  anomalies et la dernière version de cette page peuvent être trouvées à
       l'adresse https://www.kernel.org/doc/man-pages/.

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  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  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 à
       debian-l10n-french@lists.debian.org ⟨⟩.