cpuset

CPUSET(7)                 Manuel du programmeur Linux                CPUSET(7)



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

       Documentation/cpusets.txt dans les sources du noyau Linux

COLOPHON
       Cette page fait partie de la publication 3.70 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 Ã
       <perkamon-fr@traduc.org>.

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



Linux                             21 mai 2014                        CPUSET(7)