Provided by: manpages-fr_4.27.0-1_all bug

NOM

       cpuset - Confiner des processus à des sous-ensembles de processeurs et de nœuds mémoire

DESCRIPTION

       Le  système de fichiers cpuset (N.d.T. : « cpuset » signifie mot à mot « ensemble de CPU », mais comme il
       ne s'agit pas uniquement d'ensembles de CPU, le terme cpuset sera utilisé par la suite) est une interface
       sous forme d'un pseudosystème de fichiers pour le mécanisme « cpuset » du noyau, qui permet de  contrôler
       le  placement  de  processus  sur  des  processeurs  ou  en  mémoire.  Il  est  habituellement monté dans
       /dev/cpuset.

       Sur les systèmes dont le noyau a été compilé avec la prise en charge des cpusets, tous les processus sont
       attachés à un cpuset, et les cpusets sont toujours présents. Si un système prend en charge  les  cpusets,
       alors  il  aura  une  entrée  nodev  cpuset  dans  le fichier /proc/filesystems. En montant le système de
       fichiers cpuset (consultez la section EXEMPLE ci-dessous), l'administrateur peut configurer  les  cpusets
       d'un système pour contrôler le placement des processus sur les CPU et dans la mémoire sur de système. Par
       défaut,  si  la  configuration  des  cpusets d'un système n'est pas modifiée ou si le système de fichiers
       cpuset n'est même pas monté, le mécanisme des cpusets, même s'il est présent, n'a  pas  d'effets  sur  le
       comportement du système.

       Un cpuset définit une liste de CPU et de nœuds mémoire.

       Les  CPU  d'un  système  comprennent  toutes  les  unités  de  traitement logiques sur lesquelles peuvent
       s'exécuter des processus, comprenant,  s'il  y  en  a,  les  différents  cœurs  d'un  processeur  et  les
       Hyper-Threads d'un cœur de processeur. Les nœuds mémoire comprennent tous les bancs distinct de mémoire ;
       les  petits  systèmes  et  les  systèmes  SMP  ont typiquement un seul nœud mémoire qui contient toute la
       mémoire du système, alors que les systèmes NUMA (« non-uniform memory access » : accès non uniforme à  la
       mémoire) ont plusieurs nœuds mémoire.

       Les  cpusets  sont représentés par des répertoires dans un pseudosystème de fichiers hiérarchique dont le
       répertoire de plus haut niveau (/dev/cpuset) représente le système complet (tous les CPU et nœuds mémoire
       en ligne). Tout cpuset fils (le descendant) d'un autre cpuset père contient un sous-ensemble des  CPU  et
       des  nœuds  mémoire  du  père.  Les  répertoires  et  les  fichiers  qui représentent les cpusets ont les
       permissions habituelles des systèmes de fichiers.

       Chaque processus du système appartient à un unique cpuset. Un processus est obligé de s'exécuter sur  les
       CPU du cpuset auquel il appartient et est obligé d'allouer de la mémoire uniquement sur les nœuds mémoire
       de  ce  cpuset.  Quand  un  processus crée un fils avec fork(2), le processus fils est placé dans le même
       cpuset que le processus père. S'il a les privilèges suffisants, le processus fils peut se  déplacer  d'un
       cpuset à un autre et les CPU ou nœuds mémoire d'un cpuset existant peuvent être changés.

       Au  début  du démarrage du système, un seul cpuset est défini qui comprend tous les CPU et tous les nœuds
       mémoire du système et tous les processus se trouvent dans ce cpuset. Pendant le démarrage ou par la suite
       lors de l'exécution normale du système, d'autres cpusets peuvent être créés, en tant que  sous-répertoire
       de  ce  cpuset  de  plus haut niveau, sous le contrôle de l'administrateur système. Des processus peuvent
       être placés dans ces autres cpusets.

       Les  cpusets  sont  intégrés  dans  le  noyau  avec   le   mécanisme   d'affinité   d'ordonnancement   de
       sched_setaffinity(2)  et les mécanismes de placement en mémoire de mbind(2) et set_mempolicy(2). Aucun de
       ces mécanismes ne permettent à un processus d'utiliser un CPU ou un nœud mémoire qui n'est  pas  autorisé
       par le cpuset du processus. Si une modification du cpuset entre en conflit avec ces autres mécanismes, le
       placement  dans  le cpuset est forcé, même si cela signifie qu'il faut outrepasser ces autres mécanismes.
       Ceci est fait silencieusement par le noyau en restreignant les CPU et  nœuds  mémoire  demandés  par  ces
       autres  mécanismes  à  ceux  qui  sont  autorisés  par le cpuset du processus appelant. Ces autres appels
       peuvent alors renvoyer une erreur si, par exemple, ils sont amenés à demander un ensemble vide de CPU  ou
       de nœuds mémoire après que la demande est restreinte au cpuset du processus appelant.

       Typiquement,  un  cpuset  est utilisé pour gérer le confinement dans des CPU ou des nœuds mémoire pour un
       ensemble de processus qui coopèrent entre eux, comme un ordonnanceur de tâches, et ces autres  mécanismes
       permettent  de  gérer  le  placement  de  chacun des processus ou des régions mémoire pour chacune de ces
       tâches.

FICHIERS

       Chaque répertoire de /dev/cpuset représente un cpuset et contient un ensemble définit  de  pseudofichiers
       qui décrivent l'état de ce cpuset.

       Les  nouveaux  cpusets  sont  créés avec l'appel système mkdir(2) ou la commande mkdir(1). Les propriétés
       d'un cpuset, comme ses drapeaux, les CPU et nœuds  mémoire  autorisés  et  les  processus  attachés  sont
       récupérés  ou  modifiés  en  lisant  ou  écrivant  dans le fichier approprié du répertoire du cpuset. Ces
       fichiers sont décrits ci-dessous.

       Les pseudofichiers dans chaque répertoire d'un cpuset sont créés  automatiquement  quand  le  cpuset  est
       créé,  suite  à  l'appel  à  mkdir(2).  Il  n'est  pas possible d'ajouter ou de supprimer directement ces
       pseudofichiers.

       Le répertoire d'un cpuset qui ne contient pas de répertoire pour un cpuset fils et n'a pas  de  processus
       lui  étant  attaché  peut  être  supprimé  à  l'aide de rmdir(2) ou rmdir(1). Il n'est pas nécessaire, ou
       possible, de supprimer les pseudofichiers du répertoire avant de le supprimer.

       Les pseudofichiers des répertoires d'un cpuset sont de petits fichiers textes qui  peuvent  être  lus  ou
       écrits  en utilisant les outils traditionnels comme cat(1) et echo(1) ou depuis un programme en utilisant
       des fonctions d'une bibliothèque d'entrées  sorties  ou  des  appels  système,  comme  open(2),  read(2),
       write(2) et close(2).

       Les  pseudofichiers  dans  un répertoire d'un cpuset représentent l'état interne du noyau et n'ont pas de
       représentation persistante sur le disque. Les fichiers d'un cpuset sont listés et décrits ci-dessous.

       tasks  Liste des identifiants de processus (PID) des processus dans ce  cpuset.  La  liste  contient  une
              série  de  nombres décimaux au format ASCII, chacun suivit d'une nouvelle ligne. Un processus peut
              être ajouté à un cpuset (ce qui le supprime automatiquement du cpuset qui le contenait auparavant)
              en écrivant son PID dans le fichier tasks du cpuset (avec ou sans nouvelle ligne à la fin).

              Attention : un seul PID peut être écrit à la fois dans le fichier tasks. Si une chaîne est  écrite
              et qu'elle contient plus d'un PID, seul le premier sera utilisé.

       notify_on_release
              Drapeau  (0  ou  1).  Lorsqu'il est activé (1), ce cpuset sera géré de façon particulière une fois
              qu'il sera libéré, c'est-à-dire après que tous les processus cessent de  l'utiliser  (c'est-à-dire
              se  terminent  ou  ont été déplacés dans un autre ensemble de CPU) et que tous les répertoires des
              cpusets fils ont été supprimés. Consultez la section Notification à la libération ci-dessous.

       cpuset.cpus
              Liste des numéros physiques des CPU sur lesquels les processus  de  ce  cpuset  ont  le  droit  de
              s'exécuter.  Consultez  la  section Format des listes ci-dessous pour une description du format de
              cpus.

              Les CPU autorisés pour un cpuset peuvent être changés en  écrivant  une  nouvelle  liste  dans  la
              fichier cpus.

       cpuset.cpu_exclusive
              Drapeau (0 ou 1). S'il est activé (1), le cpuset a un accès exclusif à ses CPU (des cpusets frères
              ou  cousins  ne  peuvent  pas  partager  de  CPU).  Par  défaut, il est désactivé (0). Les cpusets
              nouvellement créés ont aussi ce drapeau de désactivé (0) au début.

              Deux cpusets sont frères s'ils ont le même  cpuset  père  dans  la  hiérarchie  /dev/cpuset.  Deux
              cpusets   sont   cousins  si  aucun  n'est  l'ancêtre  de  l'autre.  Indépendamment  du  paramètre
              cpu_exclusive, si un cpuset est l'ancêtre d'un autre et si ces deux cpusets ont des listes de  CPU
              (cpus)  non  vides,  alors  leurs listes de CPU doivent se chevaucher parce que la liste cpus d'un
              cpuset est toujours un sous ensemble de la liste cpus de son cpuset père.

       cpuset.mems
              Liste des nœuds mémoire sur lesquels les processus de ce cpuset  ont  le  droit  d'allouer  de  la
              mémoire. Consultez la section Format des listes ci-dessous pour une description du format de mems.

       cpuset.mem_exclusive
              Drapeau  (0  ou 1). S'il est activé (1), le cpuset a un accès exclusif à ses nœuds mémoire (pas de
              partage entre  frères  ou  cousins).  S'il  est  activé  (1),  il  s'agit  également  d'un  cpuset
              «  Hardwall  » (voir ci-dessous). Par défaut, il est désactivé (0). Les cpusets nouvellement créés
              ont aussi ce drapeau de désactivé (0) au début.

              Indépendamment du paramètre mem_exclusive, si un cpuset est  l'ancêtre  d'un  autre,  alors  leurs
              nœuds  mémoires  doivent  se  chevaucher  parce  que  l'ensemble des nœuds mémoire d'un cpuset est
              toujours un sous ensemble des nœuds mémoire du cpuset père.

       cpuset.mem_hardwall (depuis Linux 2.6.26)
              Drapeau (0 ou 1). S'il est  activé  (1),  le  cpuset  est  de  type  Hardwall  (voir  ci-dessous).
              Contrairement  à  mem_exclusive,  des cpusets marqués avec mem_hardwall peuvent partager des nœuds
              mémoire avec des cpusets frères ou  cousins.  Par  défaut,  il  est  désactivé  (0).  Les  cpusets
              nouvellement créés ont aussi ce drapeau de désactivé (0) au début.

       cpuset.memory_migrate (depuis Linux 2.6.16)
              Drapeau  (0 ou 1). S'il est activé (1), alors la migration mémoire est activée. Par défaut, il est
              désactivé (0). Consultez la section Migration mémoire ci-dessous.

       cpuset.memory_pressure (depuis Linux 2.6.16)
              Une mesure de la pression mémoire causée par les  processus  d'un  cpuset.  Consultez  la  section
              Pression  mémoire  ci-dessous.  À  moins que memory_pressure_enabled soit activé, il vaut toujours
              zéro. Ce fichier est en lecture seule. Consultez la section AVERTISSEMENTS ci-dessous.

       cpuset.memory_pressure_enabled (depuis Linux 2.6.16)
              Drapeau (0 ou 1). Ce fichier n'est  présent  que  dans  le  cpuset  racine,  qui  est  normalement
              /dev/cpuset.  S'il  est  activé  (1),  les  calculs  de memory_pressure sont activés pour tous les
              cpusets du système. Par défaut, il est  désactivé  (0).  Consultez  la  section  Pression  mémoire
              ci-dessous.

       cpuset.memory_spread_page (depuis Linux 2.6.17)
              Drapeau  (0  ou  1).  S'il  est  activé (1), les pages du cache de pages du noyau (les tampons des
              systèmes de fichiers) sont distribuées uniformément dans les cpusets. Par défaut, il est désactivé
              (0) dans le cpuset racine et  hérité  du  cpuset  parent  pour  les  cpusets  nouvellement  créés.
              Consultez la section Répartition mémoire ci-dessous.

       cpuset.memory_spread_slab (depuis Linux 2.6.17)
              Drapeau  (0 ou 1). S'il est activé (1), les caches slab (N.d.T. : tampons préalloués par le noyau)
              pour les entrées-sorties de fichiers (des structures pour des répertoires ou inœuds) sont répartis
              uniformément dans le cpuset. Par défaut, ce drapeau est désactivé (0) dans le cpuset racine et les
              nouveaux cpusets héritent du drapeau de leur parent quand ils sont  créés.  Consultez  la  section
              Répartition mémoire ci-dessous.

       cpuset.sched_load_balance (depuis Linux 2.6.24)
              Drapeau (0 ou 1). S'il est activé (1, la valeur par défaut), le noyau répartira automatiquement la
              charge  des  processus  du  cpuset au travers les CPU autorisés pour le cpuset. S'il est désactivé
              (0), le noyau ne répartira pas la charge des processus du cpuset, à moins qu'un autre  cpuset  qui
              partage  des  CPU  avec  lui  n'ait  son  drapeau  sched_load_balance activé. Consultez la section
              Répartition de la charge par l'ordonnanceur ci-dessous pour plus de détails.

       cpuset.sched_relax_domain_level (depuis Linux 2.6.26)
              Entier, compris entre -1 et une  petite  valeur  positive.  sched_relax_domain_level  contrôle  la
              largeur  de  l'intervalle  des  CPU  pour lesquels le noyau effectue une répartition immédiate des
              tâches exécutables. Si sched_load_balance est désactivé, alors sched_relax_domain_level ne  compte
              pas, puisqu'il n'y a pas de répartition de la charge. Si sched_load_balance est activé, alors plus
              sched_relax_domain_level  est important, plus l'intervalle des CPU sur lesquels le noyau essaie de
              répartir la  charge  est  important.  Consultez  la  section  Niveau  du  domaine  de  détente  de
              l'ordonnanceur ci-dessous pour plus de détails.

       En  plus  des pseudofichiers décrits ci-dessus, dans chaque répertoire de /dev/cpuset, chaque processus a
       un pseudofichier, /proc/pid/cpuset, qui indique le chemin vers le  répertoire  du  cpuset  du  processus,
       relativement à la racine du système de fichiers cpuset.

       Quatre lignes sont également ajoutées dans le fichier /proc/pid/status, fournissant pour chaque processus
       les  champs  :  Cpus_allowed  (sur  quels  CPU  il peut être ordonnancé) et Mems_allowed (sur quels nœuds
       mémoire de la mémoire peut être allouée), avec l'Affichage sous forme de masque et l'Affichage sous forme
       de liste (voir ci-dessous). Voici un exemple :

           Cpus_allowed:   ffffffff,ffffffff,ffffffff,ffffffff
           Cpus_allowed_list:     0-127
           Mems_allowed:   ffffffff,ffffffff
           Mems_allowed_list:     0-63

       Les champs « allowed » ont été ajoutés dans Linux 2.6.24 ; les champs « allowed_list »  ont  été  ajoutés
       dans Linux 2.6.26.

CAPACITÉS ÉTENDUES

       En  plus  de  contrôler  quels CPU (cpus) et nœuds mémoire (mems) un processus à le droit d'utiliser, les
       cpusets fournissent les fonctionnalités étendues suivantes.

   Ensembles de CPU exclusifs
       Si un cpuset est marqué avec cpu_exclusive ou mem_exclusive, aucun autre cpuset, autre que  des  ancêtres
       ou descendants directs, peuvent partager des CPU ou des nœuds mémoire avec ce cpuset.

       Un  cpuset dont mem_exclusive est activé restreint les allocations du noyau pour les pages des tampons de
       cache et autres données internes du noyau communément  partagées  par  le  noyau  au  travers  différents
       utilisateurs.  Tous  les  cpusets,  que  mem_exclusive  soit  activé ou non, restreignent l'allocation de
       mémoire depuis l'espace utilisateur. Ceci permet de configurer un système de telle sorte que  différentes
       tâches puissent partager des données du noyau, tout en isolant toutes les allocations en mode utilisateur
       des  tâches  dans leur propre cpuset. Pour ceci, il faut créer un gros cpuset, avec mem_exclusive activé,
       pour contenir toutes les tâches, et créer des cpuset fils sans mem_exclusive  pour  chacune  des  tâches.
       Seule une petite partie de la mémoire du noyau, comme les requêtes des gestionnaires d'interruptions, est
       autorisée à être placée sur des nœuds mémoire en dehors d'un cpuset, même si mem_exclusive est activé.

   Hardwall
       Un cpuset pour lequel mem_exclusive ou mem_hardwall est activé est un cpuset hardwall. Un cpuset hardwall
       restreint  les  allocations  mémoire  du  noyau  pour les pages, tampons et toutes autre données partagés
       fréquemment par le noyau  au  travers  différents  utilisateurs.  Tous  les  cpusets,  hardwall  ou  non,
       restreignent les allocations mémoire pour l'espace utilisateur.

       Ceci  permet  de  configurer  un  système  de  telle  sorte que différentes tâches indépendantes puissent
       partager des données du noyau, comme des pages des systèmes de fichiers, tout en isolant les  allocations
       de  l'espace  utilisateur  de  chaque  tâche  dans  leur  cpuset. Pour ceci, il faut créer un gros cpuset
       hardwall qui contiendra toutes les tâches et créer des cpusets  fils  (non  hardwall)  pour  chacune  des
       tâches.

       Seule  une  petite  quantité  de mémoire noyau, comme les demandes des gestionnaires d'interruption, peut
       être utilisée à l'extérieur d'un cpuset hardwall.

   Notification à la libération
       Si le drapeau notify_on_release d'un cpuset est activé (1), alors quand le dernier  processus  quitte  le
       cpuset  (il  se  termine ou s'attache à un autre cpuset) et que le dernier cpuset fils de ce cpuset a été
       supprimé, le noyau exécutera la commande /sbin/cpuset_release_agent en lui fournissant le chemin (relatif
       au point de montage du système de  fichiers  cpuset)  du  cpuset  abandonné.  Ceci  permet  de  supprimer
       automatiquement les cpusets abandonnés.

       Le  drapeau  notify_on_release  du  cpuset racine est désactivé (0) par défaut au moment du démarrage. La
       valeur  par  défaut  pour  les  autres  cpusets  lors  de  leur  création  est  égale  à  la  valeur   de
       notify_on_release de leur cpuset parent.

       La  commande  /sbin/cpuset_release_agent  est  appelée,  avec  dans  argv[1]  le nom (un chemin relatif à
       /dev/cpuset) du cpuset à supprimer.

       Le contenu habituel de la commande /sbin/cpuset_release_agent est simplement le script shell suivant :

           #!/bin/sh
           rmdir /dev/cpuset/$1

       Comme pour les autres drapeaux ci-dessous, ce drapeau peut être modifié en écrivant un 0 ou  un  1  ASCII
       (avec ou sans fin de ligne) dans le fichier pour respectivement désactiver ou activer le drapeau.

   Pression mémoire
       Le  fichier  memory_pressure  d'un  cpuset indique la moyenne instantanée du taux auquel les processus du
       cpuset tentent de libérer de la mémoire utilisée sur les nœuds du cpuset pour  satisfaire  les  nouvelles
       demandes de mémoire.

       Ceci  permet  à un gestionnaire de tâches de superviser les tâches qui s'exécutent dans des cpuset dédiés
       et détecter efficacement la pression mémoire qu'une tâche produit.

       Ceci est utile à la fois pour les systèmes très surveillés qui exécutent diverses tâches qui  leurs  sont
       fournies et peuvent choisir de terminer ou de changer la priorité des tâches qui essaient d'utiliser plus
       de  mémoire  que  les  nœuds mémoire qui leurs ont été assignés leurs permettent, et les systèmes pour du
       calcul scientifique avec des tâches parallèles, fortement couplées, au temps d'exécution  important,  qui
       ne  pourraient  plus  fournir les performances demandées si elles se mettaient à utiliser plus de mémoire
       qu'elles n'en ont droit.

       Ce mécanisme fourni un moyen très économique pour détecter des signes de pression mémoire sur un  cpuset.
       L'action  à  effectuer  lorsqu'un  signe  de  pression mémoire est détecté est laissé au libre arbitre du
       gestionnaire des tâches ou autre code utilisateur.

       À   moins   que   le   calcul   de   la   pression   mémoire   soit   activé   par    le    pseudofichier
       /dev/cpuset/cpuset.memory_pressure_enabled,  cette  pression  mémoire n'est calculée pour aucun cpuset et
       les lectures dans les fichiers memory_pressure renvoient toujours  zéro,  c'est-à-dire  la  chaîne  ASCII
       « 0\en ». Consultez la section AVERTISSEMENTS ci-dessous.

       Une moyenne instantanée par cpuset est utilisée pour les raisons suivantes :

       -  Comme  cette  métrique  est  par  cpuset  plutôt que par processus ou par région mémoire virtuelle, la
          charge du système due à la supervision de cette métrique par un ordonnanceur de tâches  est  fortement
          réduite sur les gros systèmes, étant donné qu'il n'est pas nécessaire de parcourir la liste des tâches
          à chaque fois.

       -  Comme  cette  métrique  est  une  moyenne instantanée plutôt qu'un compteur, un ordonnanceur de tâches
          obtient la pression mémoire en une seule lecture sans avoir  à  lire  et  se  souvenir  des  résultats
          pendant un certain temps.

       -  Comme  cette  métrique  est par cpuset plutôt que par processus, l'ordonnanceur de tâches peut obtenir
          l'information importante, la pression mémoire dans un cpuset, en une  seule  lecture  sans  nécessiter
          d'obtenir  et de se souvenir des résultats pour tous les processus d'un cpuset (la liste des processus
          peut changer dynamiquement).

       La pression mémoire d'un cpuset est calculée en utilisant un simple filtre digital  par  cpuset  dans  le
       noyau.  Pour chaque cpuset, ce filtre suit le taux auquel les processus attachés à ce cpuset demandent au
       noyau de réutiliser de la mémoire.

       Ces demandes de réutilisation de mémoire se produisent quand un processus doit satisfaire une demande  de
       page  mémoire  en  trouvant  d'abord  une page à réutiliser, du fait de l'absence de page disponible déjà
       prête. Les pages sales des systèmes de fichiers sont réutilisées en les écrivant d'abord sur  le  disque.
       Les  tampons  des  systèmes de fichiers qui n'ont pas été modifiés sont réutilisés tout simplement en les
       abandonnant, mais si cette page est nécessaire de nouveau, il faudra la relire sur le disque.

       Le fichier cpuset.memory_pressure fournit un nombre entier qui représente le taux des  demandes  récentes
       (la  demi-vie  est de 10 secondes) de réutilisation de mémoire par les processus du cpuset, l'unité étant
       le nombre de demandes par seconde fois 1000.

   Répartition mémoire
       Il y a deux fichiers, par cpuset, pour des drapeaux booléens qui contrôlent où le noyau alloue les  pages
       pour  les  tampons  des  systèmes  de  fichiers et les structures de données liées internes au noyau. Ces
       fichiers sont cpuset.memory_spread_page et cpuset.memory_spread_slab.

       Si le drapeau booléen cpuset.memory_spread_page est activé, alors  le  noyau  répartit  les  tampons  des
       systèmes  de fichiers (les caches des pages) équitablement sur tous les nœuds autorisés pour le processus
       qui demande la page, au lieu de placer ces pages de préférence  sur  le  nœud  sur  lequel  s'exécute  le
       processus.

       Si  le  drapeau  booléen  cpuset.memory_spread_slab  d'un  cpuset  est  activé,  alors le noyau répartira
       uniformément les caches slab liés aux systèmes de fichiers, comme ceux pour des entrées  d'inœuds  ou  de
       répertoires,  sur  tous  les  nœuds  autorisés pour le processus qui demande de la mémoire, plutôt que de
       préférer mettre ces pages sur le nœud sur lequel s'exécute le processus.

       La configuration de ces drapeaux n'affecte pas les pages du segment de données (consultez brk(2))  ou  du
       segment de la pile d'un processus.

       Par  défaut,  les  deux types de répartition de la mémoire sont désactivés et le noyau préfère allouer la
       mémoire sur le nœud local où s'exécute le processus. Si ce nœud n'est pas autorisé par la politique  NUMA
       du  processus  ou  par  la  configuration  des  cpusets  ou s'il n'y a plus suffisamment de pages mémoire
       disponibles sur ce nœud, alors le noyau recherche  le  nœud  le  plus  proche  étant  autorisé  et  ayant
       suffisamment de pages disponibles.

       Quand un nouveau cpuset est créé, il hérite de la configuration de répartition mémoire de son père.

       Activer  la  répartition  mémoire  a pour effet d'ignorer la politique mémoire NUMA du processus pour les
       allocations de pages ou de caches slab, qui sont alors éparpillées. Cependant, les changements dus  à  la
       répartition  mémoire  demandée  par  un  cpuset  ne sont pas visibles pour les appels système mbind(2) ou
       set_mempolicy(2). Ces deux appels système liés à la politique mémoire NUMA semblent se comporter comme si
       aucune répartition mémoire n'était demandée par un cpuset, même  si  c'est  le  cas.  Si  la  répartition
       mémoire  est  par la suite désactivée pour les cpuset, la dernière politique mémoire NUMA définie par ces
       appels est automatiquement appliquée de nouveau.

       cpuset.memory_spread_page et cpuset.memory_spread_slab sont tous les  deux  des  fichiers  contenant  des
       drapeaux  booléens.  Par  défaut,  ils  contiennent  un  « 0 », ce qui signifie que la fonctionnalité est
       désactivée pour ce cpuset. Si un « 1 » est écrit dans le fichier, la  fonctionnalité  correspondante  est
       activée.

       La  répartition  mémoire  d'un  cpuset  se  comporte de façon similaire à ce qui est connu (dans d'autres
       contextes) comme le placement mémoire à tour de rôle (« round-robin ») ou entrelacé (« interleave »).

       La configuration d'une stratégie de répartition mémoire pour un cpuset peut  améliorer  significativement
       les performances pour les tâches qui :

       -  nécessitent  de  placer  les  données  locales  des threads dans des nœuds mémoire proches des CPU qui
          exécutent les threads qui accèdent le plus fréquemment à ces données ; mais aussi

       -  nécessitent d'accéder à de gros ensembles de données de systèmes de fichiers qui doivent être répartis
          sur différents nœuds du cpuset de la tâche du fait de leurs tailles.

       Sans cette politique, la répartition des allocations mémoire sur les nœuds du cpuset de la tâche peut  ne
       pas   être   équitable,   particulièrement  pour  les  tâches  qui  n'auraient  qu'un  thread  chargé  de
       l'initialisation ou de la lecture des données d'entrée.

   Migration mémoire
       Normalement, avec la configuration de cpuset.memory_migrate par défaut (désactivé), une fois qu'une  page
       est  allouée (une page physique de la mémoire lui est donnée), cette page reste sur le nœud où elle a été
       allouée, tant qu'elle reste allouée, même si la politique de placement mémoire du  cpuset  (mems)  change
       par la suite.

       Quand  la  migration  mémoire  est activée pour un cpuset, si la configuration de mems est modifiée alors
       toute page mémoire utilisée par un processus du cpuset qui se trouverait sur un nœud  mémoire  qui  n'est
       plus autorisé sera déplacée sur un nœud mémoire qui est autorisé.

       De plus, si un processus est déplacé dans un cpuset dont le drapeau memory_migrate est activé, toutes les
       pages  mémoire  qu'il  utilise  et  qui  se trouvent sur des nœuds mémoire qui étaient autorisés dans son
       cpuset précédant mais ne le sont plus dans le  nouveau  cpuset  seront  déplacées  sur  un  nœud  mémoire
       autorisé pour le nouveau cpuset.

       L'emplacement  relatif  d'un page déplacée d'un cpuset est préservé si possible lors de ces opérations de
       déplacement. Par exemple, si la page se trouvait sur le deuxième nœud valable du précédent cpuset,  alors
       la page sera placée sur le deuxième nœud valable du nouveau cpuset, si c'est possible.

   Répartition de la charge par l'ordonnanceur
       L'ordonnanceur  du noyau répartit automatiquement la charge des processus. Si un CPU est sous-utilisé, le
       noyau recherchera des processus sur d'autres CPU plus chargés et  déplacera  ces  processus  sur  le  CPU
       sous-utilisé à condition que les mécanismes comme les cpuset et sched_setaffinity(2) le permettent.

       Le coût de l'algorithme de répartition de la charge et son impact sur les structures de données partagées
       du  noyau,  comme  la  liste  des  processus,  augmente  plus  que linéairement avec le nombre de CPU qui
       interviennent pour la répartition de la charge. Par exemple le coût pour la répartition de la charge dans
       un grand ensemble de CPU sera supérieur à celui pour la répartition de  la  charge  dans  deux  ensembles
       ayant  moitié  moins  de  CPU.  (La relation entre le nombre de CPU intervenant dans la répartition de la
       charge et le coût de cette  répartition  de  charge  dépend  de  l'implémentation  de  l'ordonnanceur  de
       processus  du  noyau,  qui  change  dans  le  temps  quand de meilleurs algorithmes d'ordonnancement sont
       implémentés)

       Le drapeau sched_load_balance d'un cpuset permet de supprimer cette répartition automatique de la  charge
       dans les cas où elle n'est pas nécessaire et que sa suppression améliorerait les performances.

       Par  défaut,  la  répartition  de la charge se fait sur tous les CPU, à l'exception de ceux marqués comme
       étant isolés en utilisant au moment du démarrage le paramètre du  noyau  «  isolcpus=  ».  (Consultez  la
       section  Niveau  du  domaine  de  détente  de  l'ordonnanceur ci-dessous pour changer le comportement par
       défaut)

       Cette répartition de la charge par défaut n'est pas bien adaptée aux situations suivantes :

       -  Sur les gros systèmes, la répartition de la charge sur beaucoup  de  CPU  est  très  coûteuse.  Si  le
          système  est  géré  avec  des cpusets pour placer les tâches indépendantes sur différents ensembles de
          CPU, une répartition de la charge complète n'est pas nécessaire.

       -  Les systèmes avec une prise en charge temps-réel sur certains CPU doivent minimiser  la  surcharge  du
          système  sur  ces  CPU  et  donc  éviter  la  répartition de la charge des processus si elle n'est pas
          nécessaire.

       Quand le drapeau sched_load_balance d'un  cpuset  est  activé  (ce  qui  est  le  cas  par  défaut),  une
       répartition  de  la  charge  sur  tous  les  CPU  autorisés par le cpuset est demandé, à condition que le
       processus puisse être déplacé d'un CPU du cpuset à un autre CPU (c'est-à-dire qu'il n'ait pas été attaché
       à des CPU avec, par exemple, sched_setaffinity(2)).

       Quand le drapeau sched_load_balance d'un cpuset est désactivé, alors l'ordonnanceur évitera  de  déplacer
       des processus pour répartir la charge des CPU du cpuset, sauf si un autre cpuset partage le même CPU et a
       son drapeau sched_load_balance activé.

       Ainsi,  par  exemple,  si  le cpuset racine a son drapeau sched_load_balance activé, alors l'ordonnanceur
       répartira la charge sur tous les CPU et la configuration du drapeau sched_load_balance des autres cpusets
       n'a pas d'effet, puisqu'une répartition complète de la charge est déjà demandée.

       Dans les deux situations ci-dessus, le drapeau sched_load_balance devrait  donc  être  désactivé  sur  le
       cpuset racine et seuls les cpusets fils plus petits devraient l'activer.

       Lorsque  vous  faites ceci, vous ne devez généralement pas laisser un processus non attaché à un CPU dans
       le cpuset racine qui pourrait utiliser les CPU de façon non négligeable. De  cette  façon  les  processus
       peuvent être artificiellement contraints à un sous ensemble des CPU en fonction de la configuration de ce
       drapeau  dans  les  cpusets descendants. Même si ce processus pourrait utiliser des cycles CPU inutilisés
       par certains CPU, l'ordonnanceur du noyau ne cherchera pas à répartir la charge du processus sur  le  CPU
       sous utilisé.

       Bien  sûr,  les processus attachés à un CPU particulier peuvent être laissés dans un cpuset qui désactive
       sched_load_balance puisque ces processus ne peuvent être déplacés de toute façon.

   Niveau du domaine de détente de l'ordonnanceur
       L'ordonnanceur du noyau effectue une répartition de la charge immédiate lorsqu'un CPU devient  disponible
       ou  lorsqu'une  autre  tâche est prête. Cette répartition de la charge permet de s'assurer que le plus de
       CPU possibles sont utilisés efficacement en exécutant des tâches. Le noyau effectue aussi une répartition
       de la charge de façon plus sporadique sur la base  de  l'horloge  logicielle  décrite  dans  time(7).  La
       configuration  de  sched_relax_domain_level  ne  s'applique  qu'à  la  répartition de charge automatique.
       Indépendamment de la configuration de sched_relax_domain_level, une répartition de charge sporadique  est
       effectuée  à  travers  tous les CPU (sauf si cela a été désactivé avec sched_load_balance). Dans tous les
       cas, bien sûr, les tâches ne seront exécutées que sur les CPU autorisés par leur cpuset et par les appels
       systèmes sched_setaffinity(2).

       Sur les petits systèmes, avec peu de CPU, la répartition de charge immédiate  est  utile  pour  améliorer
       l'interactivité du système et minimiser les cycles CPU inutilisés. Mais sur les gros systèmes, essayer de
       répartir  la  charge immédiatement sur un nombre important de CPU peut être plus coûteux que ce que ça ne
       rapporte, en fonction des performances des différentes tâches et du matériel.

       La signification exacte des petites valeurs de sched_relax_domain_level dépendra de  l'implémentation  de
       l'ordonnanceur  du  noyau  et  de l'architecture non uniforme du matériel. Ces deux paramètres évolueront
       dans le temps et dépendent de l'architecture du système et de la version du noyau.

       À ce jour, quand cette capacité a  été  introduite  sous  Linux  2.6.26,  la  signification  des  valeurs
       positives  de  sched_relax_domain_level  est  la  suivante  pour  certaines  des  architectures  les plus
       courantes :

       1      Effectuer immédiatement une répartition de la charge sur les différents Hyper-Thread  frères  d'un
              même cœur.
       2      Effectuer immédiatement une répartition de la charge sur les différents cœurs d'un processeur.
       3      Effectuer  immédiatement  une  répartition  de  la charge sur les différents CPU d'un même nœud ou
              d'une même lame.
       4      Effectuer immédiatement une répartition de la charge sur les différents (détail  d'implémentation)
              nœuds [pour les systèmes NUMA].
       5      Effectuer  immédiatement  une  répartition  de  la  charge sur tous les CPU d'un système [pour les
              systèmes NUMA].

       La valeur zéro (0) pour sched_relax_domain_level signifie toujours qu'il n'y  a  pas  de  répartition  de
       charge  immédiate, et donc la répartition de la charge s'effectue périodiquement et non pas immédiatement
       quand un CPU devient disponible ou qu'une tâche peut être exécutée.

       La valeur -1 pour sched_relax_domain_level signifie toujours qu'il faut utiliser la valeur par défaut  du
       système.  La  valeur  par  défaut du système peut varier en fonction de l'architecture et du noyau. Cette
       valeur  par  défaut  du  système  peut   être   modifiée   en   fournissant   au   noyau   un   paramètre
       « relax_domain_level= » lors du démarrage.

       Si  des  cpusets partagent des CPU et ont des valeurs de sched_relax_domain_level incompatibles, alors la
       valeur la plus élevée s'applique à tous les CPU de ces cpusets. Dans ce cas, -1 est  la  valeur  la  plus
       faible, remplacée par toute autre valeur et -0 est la valeur la plus faible suivante.

FORMATS

       Les formats suivants sont utilisés pour représenter des ensembles de CPU et de nœuds mémoire.

   Affichage sous forme de masque
       L'Affichage  sous  forme  de  masque  est  utilisé  pour représenter les masques de bits des CPU et nœuds
       mémoire dans le fichier /proc/pid/status.

       Ce format affiche chaque mot de 32 bits au format hexadécimal (en utilisant les caractères ASCII « 0 »  -
       « 9 » et « a » - « f ») ; le début des mots est complété par des zéros si nécessaire. Pour les masques de
       plus  d'un  mot,  une  virgule  est utilisée pour séparer les mots. Les mots sont affiché au format grand
       boutiste, avec le bit le plus significatif en premier. Les chiffres hexadécimaux d'un mot  utilise  aussi
       l'ordre grand boutiste.

       Le  nombre  de  mots  de 32 bits affichés est le nombre minimal nécessaire pour afficher tous les bits du
       masque, en fonction de la taille du masque de bits.

       Exemple d'Affichage sous forme de masque :

           00000001                        # seul le bit 0
           40000000,00000000,00000000      # seul le bit 94
           00000001,00000000,00000000      # seul le bit 64
           000000ff,00000000               # seuls les bits 32-39
           00000000,000e3862               # les bits 1,5,6,11-13,17-19

       Un masque avec les bits 0, 1, 2, 4, 8, 16, 32 et 64 activés sera affiché de cette façon :

           00000001,00000001,00010117

       Le premier « 1 » correspond au bit 64, le second au bit 32, le troisième au bit 16, le quatrième  au  bit
       8, le cinquième au bit 4 et le « 7 » correspond aux bits 2, 1 et 0.

   Affichage sous forme de liste
       L'Affichage sous forme de liste pour les fichiers cpus et mems est une liste de numéros ou intervalles de
       CPU ou de nœuds mémoire séparés par des virgules, en décimal au format ASCII.

       Exemple d'Affichage sous forme de liste :

           0-4,9           # bits 0, 1, 2, 3, 4 et 9 activés
           0-2,7,12-14     # bits 0, 1, 2, 7, 12, 13 et 14 activés

RÈGLES

       Les règles suivantes s'appliquent à chaque cpuset :

       -  Ses  CPU  et  nœuds  mémoire  doivent  être  des  sous-ensembles  de ceux de leur parent (ou les mêmes
          ensembles).

       -  Il ne peut être marqué avec cpu_exclusive que si son parent l'est.

       -  Il ne peut être marqué avec mem_exclusive que si son parent l'est.

       -  S'il est marqué avec cpu_exclusive, ses CPU ne doivent pas être partagés avec ses frères.

       -  S'il est marqué avec mem_exclusive, ses nœuds mémoire ne doivent pas être partagés avec ses frères.

PERMISSIONS

       Les permissions d'un cpuset sont déterminées par les permissions des  répertoires  et  pseudofichiers  du
       système de fichiers cpuset, normalement monté dans /dev/cpuset.

       Par  exemple,  un processus peut se placer dans un autre cpuset s'il peut écrire dans le fichier tasks de
       ce cpuset. Ceci nécessite les permission  d'exécution  des  répertoires  à  traverser  et  la  permission
       d'écrire dans le fichier tasks.

       Une  contrainte  supplémentaire s'applique aux demandes de déplacement d'autres processus dans un cpuset.
       Un processus ne peut pas attacher un autre processus  à  un  cpuset  à  moins  qu'il  ait  la  permission
       d'envoyer un signal à ce processus (consultez kill(2)).

       Un  processus peut créer un cpuset fils s'il a accès et peut écrire dans le répertoire du cpuset père. Il
       peut modifier les CPU et nœuds mémoire d'un  cpuset  s'il  a  accès  au  répertoire  de  ce  cpuset  (les
       permissions d'exécuter tous les répertoires parents) et s'il peut écrire dans les fichiers correspondants
       cpus ou mems.

       Il  y a une petite différence entre la manière dont ces permissions sont évaluées et la manière dont sont
       évaluées les permissions pour les opérations sur des systèmes de fichiers normaux.  Le  noyau  interprète
       les  chemins relatifs en fonction du répertoire de travail actuel d'un processus. Même quand on opère sur
       un fichier d'un cpuset, les chemins relatifs sont interprétés en fonction du  répertoire  de  travail  du
       processus,  et non pas relativement au cpuset actuel du processus. Les seules façons pour que les chemins
       de cpusets soient interprétés relativement au cpuset actuel du  processus  sont  soit  que  le  processus
       utilise le répertoire du cpuset comme répertoire de travail (il a d'abord effectué un cd ou chdir(2) dans
       le répertoire de son cpuset dans /dev/cpuset, ce qui est plutôt inhabituel), soit que du code utilisateur
       convertit le chemin relatif au cpuset en un chemin absolu.

       En  théorie,  ceci signifie que le code utilisateur devrait indiquer les cpusets en utilisant des chemins
       absolus, ce qui nécessite de connaître le point de montage du système de fichier cpuset (d'habitude, mais
       sans que ce soit nécessaire,  /dev/cpuset).  En  pratique,  à  la  connaissance  de  l'auteur,  tous  les
       utilitaires  en  mode  utilisateur  supposent que si le système de fichier cpuset est monté, alors il est
       monté dans /dev/cpuset. De plus, une pratique assez courante utilisé pour  du  code  écrit  soigneusement
       consiste  à vérifier la présence du pseudofichier /dev/cpuset/tasks afin de vérifier que le pseudosystème
       de fichiers cpuset est bien monté.

AVERTISSEMENTS

   Activation de memory_pressure
       Par défaut, le fichier cpuset.memory_pressure d'un cpuset vaut zéro (0). À moins que cette fonctionnalité
       soit activée en écrivant « 1 » dans le pseudofichier /dev/cpuset/cpuset.memory_pressure_enabled, le noyau
       ne calcule pas les valeurs des fichiers memory_pressure de chaque cpuset.

   Utilisation de la commande echo
       Lorsque la commande echo est utilisée dans un interpréteur de commandes  pour  changer  les  valeurs  des
       fichiers  d'un cpuset, soyez conscient que la commande echo interne à certains interpréteurs de commandes
       n'affiche pas de message d'erreur si l'appel système write(2) échoue. Par exemple, si la commande :

           echo 19 > cpuset.mems

       échoue parce que le nœud mémoire numéro 19 n'est pas autorisé (par exemple le système  n'a  pas  de  nœud
       mémoire  numéro  19),  alors  la  commande  echo peut n'afficher aucune erreur. If faut mieux utiliser la
       commande externe /bin/echo pour changer la configuration d'un fichier d'un cpuset puisque cette  commande
       affichera les erreurs de write(2), comme par exemple :

           /bin/echo 19 > cpuset.mems
           /bin/echo : erreur d'écriture : argument invalide

EXCEPTIONS

   Placement mémoire
       Les  contraintes  des  cpusets  ne  s'appliquent pas à toutes les allocations de mémoire système pour les
       raisons suivantes :

       Si la fonctionnalité de connexion à chaud est utilisée pour supprimer tous les CPU d'un cpuset, alors  le
       noyau  mettra  à  jour  automatiquement  la  liste  de CPU autorisés (cpus_allowed) de tous les processus
       attachés aux CPU du cpuset et  autorisera  tous  les  CPU.  Le  comportement  est  similaire  lorsque  la
       fonctionnalité  de  connexion  à  chaud est utilisée pour la mémoire. En général, le noyau préfère ne pas
       tenir compte du placement sur les CPU ou les nœuds mémoire plutôt que d'abandonner un processus dont tous
       les CPU ou nœuds mémoire autorisés sont déconnectés. Le code utilisateur devrait reconfigurer les cpusets
       pour ne mentionner que les CPU et les nœuds mémoire en ligne lorsque la  fonctionnalité  de  connexion  à
       chaud est utilisée pour ajouter ou retirer ces ressources.

       Quelques  demandes d'allocation mémoire critiques et internes au noyau, marquées GFP_ATOMIC, doivent être
       satisfaites immédiatement. Le noyau peut rater  des  demandes  ou  ne  pas  fonctionner  correctement  si
       certaines  de  ces  allocations échouent. Si une de ces demandes ne peut être satisfaite par le cpuset du
       processus en cours, alors les contraintes du cpuset sont relâchées et le noyau recherche de la mémoire là
       où il peut en trouver. Il est préférable de ne pas respecter un cpuset plutôt que de stresser le noyau.

       Les allocations de mémoire demandées par des pilotes du noyau lors du traitement d'une interruption ne se
       trouvent dans le contexte d'aucun processus et ne sont donc pas contraintes par les cpusets.

   Renommer des cpusets
       Vous pouvez utiliser l'appel système rename(2) pour renommer des cpusets. Seuls  des  renommages  simples
       sont  pris  en  charge  ;  c'est-à-dire  que  changer le nom du répertoire d'un cpuset est autorisé, mais
       déplacer le répertoire d'un cpuset dans un autre répertoire n'est pas autorisé.

ERREURS

       L'implémentation des cpusets du noyau Linux positionne errno pour indiquer  la  raison  de  l'échec  d'un
       appel système lié à un cpuset.

       Les  valeurs  possible  pour  errno  et leurs significations, lors d'un échec d'un appel système lié à un
       cpuset sont listées ci-dessous :

       E2BIG  Tentative d'écriture (write(2)) dans un fichier spécial d'un cpuset avec une longueur supérieure à
              la longueur autorisée par le noyau pour ces écritures.

       EACCES Tentative d'écriture (write(2)) d'un identifiant de processus (PID) dans  le  fichier  tasks  d'un
              cpuset alors que l'appelant n'est pas autorisé à déplacer le processus.

       EACCES Tentative d'ajout, avec write(2), d'un CPU ou d'un nœud mémoire dans un cpuset alors que ce CPU ou
              ce nœud mémoire ne se trouve pas dans le cpuset parent.

       EACCES Tentative  d'activation,  avec write(2), de cpuset.cpu_exclusive ou de cpuset.mem_exclusive sur un
              cpuset dont le parent n'a pas ces propriétés.

       EACCES Tentative d'écriture (write(2)) dans un fichier cpuset.memory_pressure.

       EACCES Tentative de création d'un fichier dans le répertoire d'un cpuset.

       EBUSY  Tentative de suppression, avec rmdir(2), d'un cpuset auquel sont attachés des processus.

       EBUSY  Tentative de suppression, avec rmdir(2), d'un cpuset ayant des ensembles de CPU fils.

       EBUSY  Tentative de suppression d'un CPU ou d'un nœud mémoire d'un cpuset alors que le  CPU  ou  le  nœud
              mémoire se trouve également dans un des fils du cpuset.

       EEXIST Tentative de création, avec mkdir(2), d'un cpuset qui existe déjà.

       EEXIST Tentative de renommage (rename(2)) d'un cpuset avec un nom déjà utilisé.

       EFAULT Tentative  de  lecture (read(2)) ou d'écriture (write(2)) dans un fichier d'un cpuset en utilisant
              un tampon en dehors de l'espace mémoire accessible par le processus appelant.

       EINVAL Tentative de modification d'un cpuset, en utilisant write(2), de telle  sorte  que  les  attributs
              cpu_exclusive ou mem_exclusive ne soient plus respectés pour ce cpuset ou ses frères.

       EINVAL Tentative  d'écriture  (avec  write(2))  d'une  liste vide dans cpuset.cpus ou cpuset.mems pour un
              cpuset auquel sont déjà attachés des processus ou des cpuset fils.

       EINVAL Tentative d'écriture (avec write(2)) dans cpuset.cpus ou cpuset.mems d'une liste qui  comprend  un
              intervalle dont la borne supérieure est inférieure à la borne inférieure.

       EINVAL Tentative  d'écriture  (avec  write(2)) dans cpuset.cpus ou cpuset.mems d'une liste dont la chaîne
              comprend un caractère non valable.

       EINVAL Tentative d'écriture (avec write(2)) dans le fichier cpuset.cpus d'une liste qui ne comprend aucun
              CPU en ligne.

       EINVAL Tentative d'écriture (avec write(2)) dans le fichier cpuset.mems d'une liste qui ne comprend aucun
              nœud mémoire en ligne.

       EINVAL Tentative d'écriture (avec write(2)) dans le fichier cpuset.mems d'une liste qui comprend un  nœud
              qui ne contient pas de mémoire.

       EIO    Tentative  d'écriture  (avec  write(2))  dans  le  fichier  tasks  d'un cpuset d'une chaîne qui ne
              commence pas par un entier décimal au format ASCII.

       EIO    Tentative de renommage (avec rename(2)) d'un cpuset dans un autre répertoire.

       ENAMETOOLONG
              Tentative de lecture (avec read(2)) du fichier /proc/pid/cpuset d'un cpuset, pour lequel le chemin
              est plus long que la taille des pages du noyau.

       ENAMETOOLONG
              Tentative de création, avec mkdir(2), d'un cpuset dont le nom du répertoire de base fait  plus  de
              255 caractères.

       ENAMETOOLONG
              Tentative  de  création,  avec  mkdir(2),  d'un cpuset dont le chemin complet, préfixe du point de
              montage compris (typiquement « /dev/cpuset/ »), fait plus de 4095 caractères.

       ENODEV Le cpuset a été supprimé par un autre processus en même temps qu'une  tentative  d'écriture  (avec
              write(2)) sur un des pseudofichiers du répertoire du cpuset.

       ENOENT Tentative de création, avec mkdir(2), d'un cpuset dans un cpuset parent qui n'existe pas.

       ENOENT Tentative  d'accéder  à  (avec  access(2))  ou  d'ouvrir  (avec  open(2)) un fichier inexistant du
              répertoire d'un cpuset.

       ENOMEM Pas assez de mémoire disponible pour le noyau ; ceci  peut  se  produire  pour  différents  appels
              système liés aux cpusets, mais seulement si le système manque beaucoup de mémoire.

       ENOSPC Tentative  d'écriture  (avec  write(2)) de l'identifiant d'un processus dans le fichier tasks d'un
              cpuset alors que les fichiers cpuset.cpus ou cpuset.mems sont vides.

       ENOSPC Tentative d'écriture (avec write(2)) d'un fichier cpuset.cpus ou cpuset.mems vide dans  un  cpuset
              auquel sont attachées des tâches.

       ENOTDIR
              Tentative de renommage (avec rename(2)) d'un cpuset qui n'existe pas.

       EPERM  Tentative de suppression d'un fichier dans le répertoire d'un cpuset.

       ERANGE Une  liste  pour  cpuset.cpus  ou  cpuset.mems a été fournie au noyau mais comprend un nombre trop
              grand pour que le noyau l'ajoute à son champ de bits.

       ESRCH  Tentative d'écriture (avec write(2)) de l'identifiant d'un processus inexistant  dans  le  fichier
              tasks d'un cpuset.

VERSIONS

       Cpusets est apparu pour la première fois dans Linux 2.6.12.

NOTES

       Contrairement  à  ce  que  son nom indique, le paramètre pid est en fait un identifiant de thread. Chaque
       thread d'un groupe de threads peut être attaché un cpuset différent. La valeur renvoyée par  un  appel  à
       gettid(2) peut être fournie comme paramètre pid.

BOGUES

       Les  fichiers  cpuset.memory_pressure  peuvent  être  ouverts  en  écriture  en demandant une création ou
       troncature, mais dans ce cas write(2) échouera en positionnant errno à EACCES, et les options de création
       ou de troncature de open(2) n'ont aucun effet.

EXEMPLES

       Voici des exemples pour l'affichage et la modification d'options d'un cpuset à l'aide  d'un  interpréteur
       de commandes.

   Créer et s'attacher à un cpuset.
       Voici les étapes pour créer un nouveau cpuset et lui attacher l'interpréteur de commandes en cours :

       (1)  mkdir /dev/cpuset (si ce n'est déjà fait)
       (2)  mount -t cpuset none /dev/cpuset (si ce n'est déjà fait)
       (3)  Créer un nouveau cpuset avec mkdir(1).
       (4)  Assigner des CPU et nœuds mémoire au nouveau cpuset.
       (5)  Attacher l'interpréteur de commandes au nouveau cpuset.

       Par  exemple,  la  séquence de commandes suivante définira un cpuset appelé « Charlie », ne contenant que
       les CPU 2 et 3 et le nœud mémoire 1, et attachera l'interpréteur de commandes en cours à ce cpuset.

           $ mkdir /dev/cpuset
           $ mount -t cpuset cpuset /dev/cpuset
           $ cd /dev/cpuset
           $ mkdir Charlie
           $ cd Charlie
           $ /bin/echo 2-3 > cpuset.cpus
           $ /bin/echo 1 > cpuset.mems
           $ /bin/echo $$ > tasks
           # Le shell en cours s'exécute désormais dans le cpuset Charlie
           # La ligne suivante devrait afficher « /Charlie »
           $ cat /proc/self/cpuset

   Déplacer des tâches sur d'autres nœuds mémoire.
       Pour déplacer les tâches attachées à un cpuset sur d'autres CPU et d'autres nœuds mémoire du  système  et
       déplacer les pages mémoires actuellement allouées par ces processus, effectuez les étapes suivantes :

       (1)  Supposons  qu'il  faille déplacer les tâches du cpuset alpha (les CPU 4–7 et nœuds mémoire 2–3) vers
            un autre cpuset beta (CPU 16–19 et nœuds mémoire 8–9).
       (2)  Créer d'abord le nouveau cpuset beta.
       (3)  Autoriser les CPU 16–19 et les nœuds mémoire 8–9 pour beta.
       (4)  Activer memory_migration dans beta.
       (5)  Déplacer chaque tâche d'alpha vers beta.

       La séquence de commandes suivante effectue cela.

           $ cd /dev/cpuset
           $ mkdir beta
           $ cd beta
           $ /bin/echo 16-19 > cpuset.cpus
           $ /bin/echo 8-9 > cpuset.mems
           $ /bin/echo 1 > cpuset.memory_migrate
           $ while read i; do /bin/echo $i; done < ../alpha/tasks > tasks

       La séquence ci-dessus déplace tous les processus de alpha vers beta et déplace toute mémoire utilisée par
       ces processus sur les nœuds mémoire 2–3 vers les nœuds mémoire 8–9.

       Notez que la dernière étape de la séquence ci-dessus n'était pas :

           $ cp ../alpha/tasks tasks

       La boucle while, plutôt que l'utilisation de  la  commande  cp(1),  est  nécessaire  par  ce  qu'un  seul
       identifiant de processus à la fois peut être écrit dans le fichier tasks.

       La même chose (l'écriture d'un PID à la fois) peut se faire plus efficacement qu'avec la boucle while, en
       moins  de  caractère  et  dans  une  syntaxe qui fonctionne avec tous les interpréteurs de commandes mais
       malheureusement de façon moins intelligible, en utilisant l'option -u (sans tampon) de sed(1) :

           $ sed -un p < ../alpha/tasks > tasks

VOIR AUSSI

       taskset(1),   get_mempolicy(2),   getcpu(2),   mbind(2),   sched_getaffinity(2),    sched_setaffinity(2),
       sched_setscheduler(2),    set_mempolicy(2),   CPU_SET(3),   proc(5),   cgroups(7),   numa(7),   sched(7),
       migratepages(8), numactl(8)

       Documentation/admin-guide/cgroup-v1/cpusets.rst dans  l'arborescence  des  sources  du  noyau  Linux  (ou
       Documentation/cgroup-v1/cpusets.txt avant Linux 4.18 et Documentation/cpusets.txt avant Linux 2.6.29)

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>,    Cédric    Boutillier     <cedric.boutillier@gmail.com>,     Frédéric     Hantrais
       <fhantrais@gmail.com> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>

       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  à
       debian-l10n-french@lists.debian.org.

Pages du manuel de Linux 6.9.1                    15 juin 2024                                         cpuset(7)