Loading

NOM

       cpuset  - Confiner des processus à des sous-ensembles de processeurs et
       de noeuds mémoire

       Le système de fichiers cpuset [ NdT : « 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 pseudo systè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. 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 noeuds 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 coeurs d’un processeur et les Hyper-Threads
       d’un coeur de processeur. Les noeuds mémoire comprennent tous les bancs
       distinct de mémoire ; les petits  systèmes  et  les  systèmes  SMP  ont
       typiquement  un  seul  noeud  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 noeuds mémoire.

       Les cpusets sont représentés par des répertoires dans un pseudo systè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 noeuds
       mémoire en ligne). Tout cpuset fils (le descendant) d’un  autre  cpuset
       père  contient  un sous-ensemble des CPU et des noeuds 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 noeuds 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 noeuds 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 noeuds 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 noeud 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  noeuds  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
       noeuds mémoire après que  la  demande  soit  restreinte  au  cpuset  du
       processus appelant.

       Typiquement,  un  cpuset est utilisé pour gérer le confinement dans des
       CPU ou des noeuds 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 fixé de pseudo fichiers 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  noeuds  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 pseudo fichiers 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  pseudo
       fichiers.

       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 pseudo fichiers du répertoire  avant  de  le
       supprimer.

       Les pseudo fichiers des répertoires d’un cpuset sont de petits fichiers
       texte  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  pseudo fichiers 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.

       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.

       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).

              Deux  cpusets  sont frres 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.

       mems   Liste des noeuds 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.

       mem_exclusive
              Drapeau (0 ou 1). S’il est activé (1),  le  cpuset  a  un  accès
              exclusif  à  ses  noeuds mémoire (pas de partage entre frères ou
              cousins). S’il est  activé,  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).

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

       mem_hardwall (depuis Linux 2.6.25)
              Drapeau  (0  ou  1).  S’il  est  activé,  le  cpuset est de type
              Hardwall (voir ci-dessous). Contrairement à  mem_exclusive,  des
              cpusets  marqués  avec  mem_hardwall peuvent partager des noeuds
              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).

       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é. Consultez la
              section Migration mémoire ci-dessous.

       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.

       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.

       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 père
              pour  les  cpusets  nouvellement  créés.  Consultez  la  section
              Répartition mémoire ci-dessous.

       memory_spread_slab (depuis Linux 2.6.17)
              Drapeau  (0  ou 1). S’il est activé (1), les caches slab [ NdT :
              tampons pré-alloués par le noyau ] pour les  entrées-sorties  de
              fichiers  (des  structures pour des répertoires ou inoeuds) 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 père quand ils sont créés. Consultez
              la section Répartition mémoire ci-dessous.

       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 lordonnanceur ci-dessous
              pour plus de détails.

       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 lordonnanceur ci-dessous pour plus de détails.

       En  plus  des pseudo fichiers décrits ci-dessus, dans chaque répertoire
       de   /dev/cpuset,   chaque   processus    a    un    pseudo    fichier,
       /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  noeuds  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  noeuds  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 noeuds 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  noeuds  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  noeuds  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 noeuds 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 pseudo
       fichier  /dev/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\n ». 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  gestionnaire  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  gestionnaire 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, le
          gestionnaire 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 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 memory_spread_page et memory_spread_slab.

       Si le drapeau booléen 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  noeuds  autorisés  pour  le  processus  qui
       demandela  page, au lieu de placer ces pages de préférence sur le noeud
       sur lequel s’exécute le processus.

       Si le drapeau booléen 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’inoeuds ou de répertoires,  sur
       tous  les noeuds autorisés pour le processus qui demande de la mémoire,
       plutôt que de préférer  mettre  ces  pages  sur  le  noeud  sur  lequel
       s’exécute le processus.

       La  configuration de ces drapeaux n’affecte pas les pages du segment de
       données (voir 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é
       et  le noyau préfère allouer la mémoire sur le noeud local où s’exécute
       le processus. Si ce noeud 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 noeud, alors le  noyau
       recherche  le noeud 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 semble 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.

       memory_spread_page  et  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 :

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

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

       Sans cette politique, la répartition des allocations  mémoire  sur  les
       noeuds   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  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é),  cette page reste sur le noeud 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 noeud mémoire qui
       n’est plus  autorisé  sera  déplacée  sur  un  noeud  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 noeuds 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 noeud 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 noeud valable du précédent cpuset, alors la
       page sera placée sur le deuxième noeud valable du  nouveau  cpuset,  si
       c’est possible.

   Répartition de la charge par lordonnanceur
       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 lordonnanceur 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 lordonnanceur
       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 coeur.
       (2) Effectuer  immédiatement  une  répartition  de  la  charge  sur les
           différents coeurs d’un processeur.
       (3) Effectuer immédiatement  une  répartition  de  la  charge  sur  les
           différents CPU d’un même noeud 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)  noeuds  [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, la valeur  moins
       un  (-1) est la valeur la plus faible, remplacée par toute autre valeur
       et la valeur zéro (0) est la valeur la plus faible suivante.

FORMATS

       Les formats suivants sont utilisés pour représenter  des  ensembles  de
       CPU et de noeuds 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  noeuds   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 noeuds 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 noeuds 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 memory_exclusive, ses noeuds 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  pseudo  fichiers  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 (voir 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  noeuds
       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 pseudo fichier
       /dev/cpuset/tasks afin de vérifier que le pseudo  système  de  fichiers
       cpuset est bien monté.

AVERTISSEMENTS

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

   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 > mems

       échoue parce que le noeud mémoire 19 n’est pas autorisé (par exemple le
       système  n’a  pas  de  noeud 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 > mems
           /bin/echo : erreur d’écriture : Le résultat numérique est en dehors de l’intervalle

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 noeuds mémoire plutôt que d’abandonner  un
       processus   dont   tous  les  CPU  ou  noeuds  mémoire  autorisés  sont
       déconnectés. Le code utilisateur devrait reconfigurer les cpusets  pour
       ne  mentionner  que  les  CPU et les noeuds 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 noeud mémoire
              dans un cpuset alors que ce CPU ou ce noeud mémoire ne se trouve
              pas dans le cpuset parent.

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

       EACCES Tentative d’écriture (write(2)) dans un fichier 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  noeud  mémoire  d’un
              cpuset  alors que le CPU ou le noeud 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  cpus
              ou  mems  pour un cpuset auquel sont déjà attachés des processus
              ou des cpuset fils.

       EINVAL Tentative d’écriture (avec write(2)) dans  cpus  ou  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  cpus  ou  mems  d’une
              liste dont la chaîne comprend un caractère non valable.

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

       EINVAL Tentative d’écriture (avec write(2)) dans le fichier mems  d’une
              liste qui ne comprend aucun noeud mémoire en ligne.

       EINVAL Tentative  d’écriture (avec write(2)) dans le fichier mems d’une
              liste qui comprend un noeud 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 pseudo
              fichiers 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
              fichier cpus ou mems sont vides.

       ENOSPC Tentative d’écriture (avec write(2)) d’un fichier cpus  ou  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 cpus ou 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

       Les cpusets sont apparus dans la version 2.6.12 du noyau Linux.

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  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.

EXEMPLE

       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 sattacher à 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 noeuds 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 noeud 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 > cpus
           $ /bin/echo 1 > 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 dautres noeuds mémoire.
       Pour déplacer les tâches attachées à un  cpuset  sur  d’autres  CPU  et
       d’autres  noeuds  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 noeuds mémoire 2-3) vers un autre cpuset beta (CPU 16-19  et
           noeuds mémoire 8-9).
       2)  Créer d’abord le nouveau cpuset beta.
       3)  Autoriser les CPU 16-19 et les noeuds 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 > cpus
           $ /bin/echo 8-9 > mems
           $ /bin/echo 1 > 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 noeuds mémoire
       2-3 vers les noeuds 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),   numa(7),  migratepages(8),
       numactl(8)

       Le fichier Documentation/cpusets.txt des sources du noyau.

COLOPHON

       Cette page fait partie de  la  publication  3.23  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      être       trouvées       à       l’adresse
       http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Cette  page  de  manuel  a  été  traduite  par Alain Portal <aportal AT
       univ-montp2  DOT   fr>   en   2008,   et   mise   à   disposition   sur
       http://manpagesfr.free.fr/.

       Veuillez   signaler   toute   erreur   de   traduction  en  écrivant  à
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous  pouvez  toujours avoir accès à la version anglaise de ce document
       en utilisant la commande « man -L C <section> <page_de_man> ».