Provided by: manpages-fr_3.65d1p1-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. 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).

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

       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é. 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 père
              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 père 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\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  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 :

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

       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 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,  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  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 memory_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

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

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 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),
       numa(7), migratepages(8), numactl(8)

       Documentation/cpusets.txt dans les sources du noyau Linux

COLOPHON

       Cette  page  fait partie de la publication 3.65 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

       Depuis    2010,    cette   traduction   est   maintenue   à   l'aide   de   l'outil   po4a
       <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du  projet
       perkamon <http://perkamon.alioth.debian.org/>.

       Alain Portal <http://manpagesfr.free.fr/> (2008).

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