Provided by:
manpages-fr_3.27fr1.4-1_all 
NOM
cpuset - Confiner des processus a des sous-ensembles de processeurs et
de noeuds memoire
DESCRIPTION
Le systeme de fichiers cpuset (N.d.T. : << cpuset >> signifie mot a mot
<< ensemble de CPU >>, mais comme il ne s'agit pas uniquement
d'ensembles de CPU, le terme cpuset sera utilise par la suite) est une
interface sous forme d'un pseudo systeme de fichiers pour le mecanisme
<< cpuset >> du noyau, qui permet de controler le placement de
processus sur des processeurs ou en memoire. Il est habituellement
monte dans /dev/cpuset.
Sur les systemes dont le noyau a ete compile avec la prise en charge
des cpusets, tous les processus sont attaches a un cpuset, et les
cpusets sont toujours presents. Si un systeme prend en charge les
cpusets, alors il aura une entree nodev cpuset dans le fichier
/proc/filesystems. En montant le systeme de fichiers cpuset (consultez
la section EXEMPLE ci-dessous), l'administrateur peut configurer les
cpusets d'un systeme pour controler le placement des processus sur les
CPU et dans la memoire. Par defaut, si la configuration des cpusets
d'un systeme n'est pas modifiee ou si le systeme de fichiers cpuset
n'est meme pas monte, le mecanisme des cpusets, meme s'il est present,
n'a pas d'effets sur le comportement du systeme.
Un cpuset definit une liste de CPU et de noeuds memoire.
Les CPU d'un systeme comprennent toutes les unites de traitement
logiques sur lesquelles peuvent s'executer des processus, comprenant,
s'il y en a, les differents coeurs d'un processeur et les Hyper-Threads
d'un coeur de processeur. Les noeuds memoire comprennent tous les bancs
distinct de memoire ; les petits systemes et les systemes SMP ont
typiquement un seul noeud memoire qui contient toute la memoire du
systeme, alors que les systemes NUMA (<< non-uniform memory access >> :
acces non uniforme a la memoire) ont plusieurs noeuds memoire.
Les cpusets sont representes par des repertoires dans un pseudo-systeme
de fichiers hierarchique dont le repertoire de plus haut niveau
(/dev/cpuset) represente le systeme complet (tous les CPU et noeuds
memoire en ligne). Tout cpuset fils (le descendant) d'un autre cpuset
pere contient un sous-ensemble des CPU et des noeuds memoire du pere.
Les repertoires et les fichiers qui representent les cpusets ont les
permissions habituelles des systemes de fichiers.
Chaque processus du systeme appartient a un unique cpuset. Un processus
est oblige de s'executer sur les CPU du cpuset auquel il appartient et
est oblige d'allouer de la memoire uniquement sur les noeuds memoire de
ce cpuset. Quand un processus cree un fils avec fork(2), le processus
fils est place dans le meme cpuset que le processus pere. S'il a les
privileges suffisants, le processus fils peut se deplacer d'un cpuset a
un autre et les CPU ou noeuds memoire d'un cpuset existant peuvent etre
changes.
Au debut du demarrage du systeme, un seul cpuset est defini qui
comprend tous les CPU et tous les noeuds memoire du systeme et tous les
processus se trouvent dans ce cpuset. Pendant le demarrage ou par la
suite lors de l'execution normale du systeme, d'autres cpusets peuvent
etre crees, en tant que sous-repertoire de ce cpuset de plus haut
niveau, sous le controle de l'administrateur systeme. Des processus
peuvent etre places dans ces autres cpusets.
Les cpusets sont integres dans le noyau avec le mecanisme d'affinite
d'ordonnancement de sched_setaffinity(2) et les mecanismes de placement
en memoire de mbind(2) et set_mempolicy(2). Aucun de ces mecanismes ne
permettent a un processus d'utiliser un CPU ou un noeud memoire qui
n'est pas autorise par le cpuset du processus. Si une modification du
cpuset entre en conflit avec ces autres mecanismes, le placement dans
le cpuset est force, meme si cela signifie qu'il faut outrepasser ces
autres mecanismes. Ceci est fait silencieusement par le noyau en
restreignant les CPU et noeuds memoire demandes par ces autres
mecanismes a ceux qui sont autorises par le cpuset du processus
appelant. Ces autres appels peuvent alors renvoyer une erreur si, par
exemple, ils sont amenes a demander un ensemble vide de CPU ou de
noeuds memoire apres que la demande est restreinte au cpuset du
processus appelant.
Typiquement, un cpuset est utilise pour gerer le confinement dans des
CPU ou des noeuds memoire pour un ensemble de processus qui cooperent
entre eux, comme un ordonnanceur de taches, et ces autres mecanismes
permettent de gerer le placement de chacun des processus ou des regions
memoire pour chacune de ces taches.
FICHIERS
Chaque repertoire de /dev/cpuset represente un cpuset et contient un
ensemble fixe de pseudo-fichiers qui decrivent l'etat de ce cpuset.
Les nouveaux cpusets sont crees avec l'appel systeme mkdir(2) ou la
commande mkdir(1). Les proprietes d'un cpuset, comme ses drapeaux, les
CPU et noeuds memoire autorises et les processus attaches sont
recuperes ou modifies en lisant ou ecrivant dans le fichier approprie
du repertoire du cpuset. Ces fichiers sont decrits ci-dessous.
Les pseudo-fichiers dans chaque repertoire d'un cpuset sont crees
automatiquement quand le cpuset est cree, suite a l'appel a mkdir(2).
Il n'est pas possible d'ajouter ou de supprimer directement ces
pseudo-fichiers.
Le repertoire d'un cpuset qui ne contient pas de repertoire pour un
cpuset fils et n'a pas de processus lui etant attache peut etre
supprime a l'aide de rmdir(2) ou rmdir(1). Il n'est pas necessaire, ou
possible, de supprimer les pseudo-fichiers du repertoire avant de le
supprimer.
Les pseudo-fichiers des repertoires d'un cpuset sont de petits fichiers
textes qui peuvent etre lus ou ecrits en utilisant les outils
traditionnels comme cat(1) et echo(1) ou depuis un programme en
utilisant des fonctions d'une bibliotheque d'entrees sorties ou des
appels systeme, comme open(2), read(2), write(2) et close(2).
Les pseudo-fichiers dans un repertoire d'un cpuset representent l'etat
interne du noyau et n'ont pas de representation persistante sur le
disque. Les fichiers d'un cpuset sont listes et decrits ci-dessous.
tasks Liste des identifiants de processus (PID) des processus dans ce
cpuset. La liste contient une serie de nombres decimaux au
format ASCII, chacun suivit d'une nouvelle ligne. Un processus
peut etre ajoute a un cpuset (ce qui le supprime automatiquement
du cpuset qui le contenait auparavant) en ecrivant son PID dans
le fichier tasks du cpuset (avec ou sans nouvelle ligne a la
fin).
Attention : un seul PID peut etre ecrit a la fois dans le
fichier tasks. Si une chaine est ecrite et qu'elle contient plus
d'un PID, seul le premier sera utilise.
notify_on_release
Drapeau (0 ou 1). Lorsqu'il est active (1), ce cpuset sera gere
de facon particuliere une fois qu'il sera libere, c'est-a-dire
apres que tous les processus cessent de l'utiliser (c'est-a-dire
se terminent ou ont ete deplaces dans un autre ensemble de CPU)
et que tous les repertoires des cpusets fils ont ete supprimes.
Consultez la section Notification `a la lib'eration ci-dessous.
cpus Liste des numeros physiques des CPU sur lesquels les processus
de ce cpuset ont le droit de s'executer. Consultez la section
Format des listes ci-dessous pour une description du format de
cpus.
Les CPU autorises pour un cpuset peuvent etre changes en
ecrivant une nouvelle liste dans la fichier cpus.
cpu_exclusive
Drapeau (0 ou 1). S'il est active (1), le cpuset a un acces
exclusif a ses CPU (des cpusets freres ou cousins ne peuvent pas
partager de CPU). Par defaut, il est desactive (0). Les cpusets
nouvellement crees ont aussi ce drapeau de desactive (0).
Deux cpusets sont fr`eres s'ils ont le meme cpuset pere dans la
hierarchie /dev/cpuset. Deux cpusets sont cousins si aucun n'est
l'ancetre de l'autre. Independamment du parametre cpu_exclusive,
si un cpuset est l'ancetre 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 pere.
mems Liste des noeuds memoire sur lesquels les processus de ce cpuset
ont le droit d'allouer de la memoire. Consultez la section
Format des listes ci-dessous pour une description du format de
mems.
mem_exclusive
Drapeau (0 ou 1). S'il est active (1), le cpuset a un acces
exclusif a ses noeuds memoire (pas de partage entre freres ou
cousins). S'il est active, il s'agit egalement d'un cpuset
<< Hardwall >> (voir ci-dessous). Par defaut, il est desactive
(0). Les cpusets nouvellement crees ont aussi ce drapeau de
desactive (0).
Independamment du parametre mem_exclusive, si un cpuset est
l'ancetre d'un autre, alors leurs noeuds memoires doivent se
chevaucher parce que l'ensemble des noeuds memoire d'un cpuset
est toujours un sous ensemble des noeuds memoire du cpuset pere.
mem_hardwall (depuis Linux 2.6.25)
Drapeau (0 ou 1). S'il est active, le cpuset est de type
Hardwall (voir ci-dessous). Contrairement a mem_exclusive, des
cpusets marques avec mem_hardwall peuvent partager des noeuds
memoire avec des cpusets freres ou cousins. Par defaut, il est
desactive (0). Les cpusets nouvellement crees ont aussi ce
drapeau de desactive (0).
memory_migrate (depuis Linux 2.6.16)
Drapeau (0 ou 1). S'il est active (1), alors la migration
memoire est activee. Par defaut, il est desactive. Consultez la
section Migration m'emoire ci-dessous.
memory_pressure (depuis Linux 2.6.16)
Une mesure de la pression memoire causee par les processus d'un
cpuset. Consultez la section Pression m'emoire ci-dessous. A
moins que memory_pressure_enabled soit active, il vaut toujours
zero. Ce fichier est en lecture seule. Consultez la section
AVERTISSEMENTS ci-dessous.
memory_pressure_enabled (depuis Linux 2.6.16)
Drapeau (0 ou 1). Ce fichier n'est present que dans le cpuset
racine, qui est normalement /dev/cpuset. S'il est active (1),
les calculs de memory_pressure sont actives pour tous les
cpusets du systeme. Par defaut, il est desactive (0). Consultez
la section Pression m'emoire ci-dessous.
memory_spread_page (depuis Linux 2.6.17)
Drapeau (0 ou 1). S'il est active (1), les pages du cache de
pages du noyau (les tampons des systemes de fichiers) sont
distribuees uniformement dans les cpusets. Par defaut, il est
desactive (0) dans le cpuset racine et herite du cpuset pere
pour les cpusets nouvellement crees. Consultez la section
R'epartition m'emoire ci-dessous.
memory_spread_slab (depuis Linux 2.6.17)
Drapeau (0 ou 1). S'il est active (1), les caches slab (N.d.T. :
tampons pre-alloues par le noyau) pour les entrees-sorties de
fichiers (des structures pour des repertoires ou inoeuds) sont
repartis uniformement dans le cpuset. Par defaut, ce drapeau est
desactive (0) dans le cpuset racine et les nouveaux cpusets
heritent du drapeau de leur pere quand ils sont crees. Consultez
la section R'epartition m'emoire ci-dessous.
sched_load_balance (depuis Linux 2.6.24)
Drapeau (0 ou 1). S'il est active (1, la valeur par defaut), le
noyau repartira automatiquement la charge des processus du
cpuset au travers les CPU autorises pour le cpuset. S'il est
desactive (0), le noyau ne repartira pas la charge des processus
du cpuset, `a moins qu'un autre cpuset qui partage des CPU avec
lui n'ait son drapeau sched_load_balance active. Consultez la
section R'epartition de la charge par l'ordonnanceur ci-dessous
pour plus de details.
sched_relax_domain_level (depuis Linux 2.6.26)
Entier, compris entre -1 et une petite valeur positive.
sched_relax_domain_level controle la largeur de l'intervalle des
CPU pour lesquels le noyau effectue une repartition immediate
des taches executables. Si sched_load_balance est desactive,
alors sched_relax_domain_level ne compte pas, puisqu'il n'y a
pas de repartition de la charge. Si sched_load_balance est
active, alors plus sched_relax_domain_level est important, plus
l'intervalle des CPU sur lesquels le noyau essaie de repartir la
charge est important. Consultez la section Niveau du domaine de
d'etente de l'ordonnanceur ci-dessous pour plus de details.
En plus des pseudo-fichiers decrits ci-dessus, dans chaque repertoire
de /dev/cpuset, chaque processus a un pseudo-fichier,
/proc/<pid>/cpuset, qui indique le chemin vers le repertoire du cpuset
du processus, relativement a la racine du systeme de fichiers cpuset.
Quatre lignes sont egalement ajoutees dans le fichier
/proc/<pid>/status, fournissant pour chaque processus les champs :
Cpus_allowed (sur quels CPU il peut etre ordonnance) et Mems_allowed
(sur quels noeuds memoire de la memoire peut etre allouee), 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 ete ajoutes dans Linux 2.6.24 ; les champs
<< allowed_list >> ont ete ajoutes dans Linux 2.6.26.
CAPACIT'ES 'ETENDUES
En plus de controler quels CPU (cpus) et noeuds memoire (mems) un
processus a le droit d'utiliser, les cpusets fournissent les
fonctionnalites etendues suivantes.
Ensembles de CPU exclusifs
Si un cpuset est marque avec cpu_exclusive ou mem_exclusive, aucun
autre cpuset, autre que des ancetres ou descendants directs, peuvent
partager des CPU ou des noeuds memoire avec ce cpuset.
Un cpuset dont mem_exclusive est active restreint les allocations du
noyau pour les pages des tampons de cache et autres donnees internes du
noyau communement partagees par le noyau au travers differents
utilisateurs. Tous les cpusets, que mem_exclusive soit active ou non,
restreignent l'allocation de memoire depuis l'espace utilisateur. Ceci
permet de configurer un systeme de telle sorte que differentes taches
puissent partager des donnees du noyau, tout en isolant toutes les
allocations en mode utilisateur des taches dans leur propre cpuset.
Pour ceci, il faut creer un gros cpuset, avec mem_exclusive active,
pour contenir toutes les taches, et creer des cpuset fils sans
mem_exclusive pour chacune des taches. Seule une petite partie de la
memoire du noyau, comme les requetes des gestionnaires d'interruptions,
est autorisee a etre placee sur des noeuds memoire en dehors d'un
cpuset, meme si mem_exclusive est active.
Hardwall
Un cpuset pour lequel mem_exclusive ou mem_hardwall est active est un
cpuset hardwall. Un cpuset hardwall restreint les allocations memoire
du noyau pour les pages, tampons et toutes autre donnees partages
frequemment par le noyau au travers differents utilisateurs. Tous les
cpusets, hardwall ou non, restreignent les allocations memoire pour
l'espace utilisateur.
Ceci permet de configurer un systeme de telle sorte que differentes
taches independantes puissent partager des donnees du noyau, comme des
pages des systemes de fichiers, tout en isolant les allocations de
l'espace utilisateur de chaque tache dans leur cpuset. Pour ceci, il
faut creer un gros cpuset hardwall qui contiendra toutes les taches et
creer des cpusets fils (non hardwall) pour chacune des taches.
Seule une petite quantite de memoire noyau, comme les demandes des
gestionnaires d'interruption, peut etre utilisee a l'exterieur d'un
cpuset hardwall.
Notification `a la lib'eration
Si le drapeau notify_on_release d'un cpuset est active (1), alors quand
le dernier processus quitte le cpuset (il se termine ou s'attache a un
autre cpuset) et que le dernier cpuset fils de ce cpuset a ete
supprime, le noyau executera la commande /sbin/cpuset_release_agent en
lui fournissant le chemin (relatif au point de montage du systeme de
fichiers cpuset) du cpuset abandonne. Ceci permet de supprimer
automatiquement les cpusets abandonnes.
Le drapeau notify_on_release du cpuset racine est desactive (0) par
defaut au moment du demarrage. La valeur par defaut pour les autres
cpusets lors de leur creation est egale a la valeur de
notify_on_release de leur cpuset parent.
La commande /sbin/cpuset_release_agent est appelee, avec dans argv[1]
le nom (un chemin relatif a /dev/cpuset) du cpuset a 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 etre modifie
en ecrivant un 0 ou un 1 ASCII (avec ou sans fin de ligne) dans le
fichier pour respectivement desactiver ou activer le drapeau.
Pression m'emoire
Le fichier memory_pressure d'un cpuset indique la moyenne instantanee
du taux auquel les processus du cpuset tentent de liberer de la memoire
utilisee sur les noeuds du cpuset pour satisfaire les nouvelles
demandes de memoire.
Ceci permet a un gestionnaire de taches de superviser les taches qui
s'executent dans des cpuset dedies et detecter efficacement la pression
memoire qu'une tache produit.
Ceci est utile a la fois pour les systemes tres surveilles qui
executent diverses taches qui leurs sont fournies et peuvent choisir de
terminer ou de changer la priorite des taches qui essaient d'utiliser
plus de memoire que les noeuds memoire qui leurs ont ete assignes leurs
permettent, et les systemes pour du calcul scientifique avec des taches
paralleles, fortement couplees, au temps d'execution important, qui ne
pourraient plus fournir les performances demandees si elles se
mettaient a utiliser plus de memoire qu'elles n'en ont droit.
Ce mecanisme fourni un moyen tres economique pour detecter des signes
de pression memoire sur un cpuset. L'action a effectuer lorsqu'un signe
de pression memoire est detecte est laisse au libre arbitre du
gestionnaire des taches ou autre code utilisateur.
A moins que le calcul de la pression memoire soit active par le
pseudo-fichier /dev/cpuset/memory_pressure_enabled, cette pression
memoire n'est calculee pour aucun cpuset et les lectures dans les
fichiers memory_pressure renvoient toujours zero, c'est-a-dire la
chaine ASCII << 0\n >>. Consultez la section AVERTISSEMENTS ci-dessous.
Une moyenne instantanee par cpuset est utilisee pour les raisons
suivantes :
* Comme cette metrique est par cpuset plutot que par processus ou par
region memoire virtuelle, la charge du systeme due a la supervision
de cette metrique par un gestionnaire de taches est fortement
reduite sur les gros systemes, etant donne qu'il n'est pas
necessaire de parcourir la liste des taches a chaque fois.
* Comme cette metrique est une moyenne instantanee plutot qu'un
compteur, un gestionnaire de taches obtient la pression memoire en
une seule lecture sans avoir a lire et se souvenir des resultats
pendant un certain temps.
* Comme cette metrique est par cpuset plutot que par processus, le
gestionnaire de taches peut obtenir l'information importante, la
pression memoire dans un cpuset, en une seule lecture sans
necessiter d'obtenir et de se souvenir des resultats pour tous les
processus d'un cpuset (la liste des processus peut changer
dynamiquement).
La pression memoire d'un cpuset est calculee en utilisant un simple
filtre digital par cpuset dans le noyau. Pour chaque cpuset, ce filtre
suit le taux auquel les processus attaches a ce cpuset demandent au
noyau de reutiliser de la memoire.
Ces demandes de reutilisation de memoire se produisent quand un
processus doit satisfaire une demande de page memoire en trouvant
d'abord une page a reutiliser, du fait de l'absence de page disponible
deja prete. Les pages sales des systemes de fichiers sont reutilisees
en les ecrivant d'abord sur le disque. Les tampons des systemes de
fichiers qui n'ont pas ete modifies sont reutilises tout simplement en
les abandonnant, mais si cette page est necessaire de nouveau, il
faudra la relire sur le disque.
Le fichier memory_pressure fournit un nombre entier qui represente le
taux des demandes recentes (la demi-vie est de 10 secondes) de
reutilisation de memoire par les processus du cpuset, l'unite etant le
nombre de demandes par seconde fois 1000.
R'epartition m'emoire
Il y a deux fichiers, par cpuset, pour des drapeaux booleens qui
controlent ou le noyau alloue les pages pour les tampons des systemes
de fichiers et les structures de donnees liees internes au noyau. Ces
fichiers sont memory_spread_page et memory_spread_slab.
Si le drapeau booleen memory_spread_page est active, alors le noyau
repartit les tampons des systemes de fichiers (les caches des pages)
equitablement sur tous les noeuds autorises pour le processus qui
demandela page, au lieu de placer ces pages de preference sur le noeud
sur lequel s'execute le processus.
Si le drapeau booleen memory_spread_slab d'un cpuset est active, alors
le noyau repartira uniformement les caches slab lies aux systemes de
fichiers, comme ceux pour des entrees d'inoeuds ou de repertoires, sur
tous les noeuds autorises pour le processus qui demande de la memoire,
plutot que de preferer mettre ces pages sur le noeud sur lequel
s'execute le processus.
La configuration de ces drapeaux n'affecte pas les pages du segment de
donnees (consultez brk(2)) ou du segment de la pile d'un processus.
Par defaut, les deux types de repartition de la memoire sont desactive
et le noyau prefere allouer la memoire sur le noeud local ou s'execute
le processus. Si ce noeud n'est pas autorise par la politique NUMA du
processus ou par la configuration des cpusets ou s'il n'y a plus
suffisamment de pages memoire disponibles sur ce noeud, alors le noyau
recherche le noeud le plus proche etant autorise et ayant suffisamment
de pages disponibles.
Quand un nouveau cpuset est cree, il herite de la configuration de
repartition memoire de son pere.
Activer la repartition memoire a pour effet d'ignorer la politique
memoire NUMA du processus pour les allocations de pages ou de caches
slab, qui sont alors eparpillees. Cependant, les changements dus a la
repartition memoire demandee par un cpuset ne sont pas visibles pour
les appels systeme mbind(2) ou set_mempolicy(2). Ces deux appels
systeme lies a la politique memoire NUMA semble se comporter comme si
aucune repartition memoire n'etait demandee par un cpuset, meme si
c'est le cas. Si la repartition memoire est par la suite desactivee
pour les cpuset, la derniere politique memoire NUMA definie par ces
appels est automatiquement appliquee de nouveau.
memory_spread_page et memory_spread_slab sont tous les deux des
fichiers contenant des drapeaux booleens. Par defaut, ils contiennent
un << 0 >>, ce qui signifie que la fonctionnalite est desactivee pour
ce cpuset. Si un << 1 >> est ecrit dans le fichier, la fonctionnalite
correspondante est activee.
La repartition memoire d'un cpuset se comporte de facon similaire a ce
qui est connu (dans d'autres contextes) comme le placement memoire a
tour de role (<< round-robin >>) ou entrelace (<< interleave >>).
La configuration d'une strategie de repartition memoire pour un cpuset
peut ameliorer significativement les performances pour les taches qui :
a) necessitent de placer les donnees locales des threads dans des
noeuds memoire proches des CPU qui executent les threads qui
accedent le plus frequemment a ces donnees ; mais aussi
b) necessitent d'acceder a de gros ensembles de donnees de systemes de
fichiers qui doivent etre repartis sur differents noeuds du cpuset
de la tache du fait de leurs tailles.
Sans cette politique, la repartition des allocations memoire sur les
noeuds du cpuset de la tache peut ne pas etre equitable,
particulierement pour les taches qui n'auraient qu'un thread charge de
l'initialisation ou de la lecture des donnees d'entree.
Migration m'emoire
Normalement, avec la configuration de memory_migrate par defaut
(desactive), une fois qu'une page est allouee (une page physique de la
memoire lui est donne), cette page reste sur le noeud ou elle a ete
allouee, tant qu'elle reste allouee, meme si la politique de placement
memoire du cpuset (mems) change par la suite.
Quand la migration memoire est activee pour un cpuset, si la
configuration de mems est modifiee alors toute page memoire utilisee
par un processus du cpuset qui se trouverait sur un noeud memoire qui
n'est plus autorise sera deplacee sur un noeud memoire qui est
autorise.
De plus, si un processus est deplace dans un cpuset dont le drapeau
memory_migrate est active, toutes les pages memoire qu'il utilise et
qui se trouvent sur des noeuds memoire qui etaient autorises dans son
cpuset precedant mais ne le sont plus dans le nouveau cpuset seront
deplacees sur un noeud memoire autorise pour le nouveau cpuset.
L'emplacement relatif d'un page deplacee d'un cpuset est preserve si
possible lors de ces operations de deplacement. Par exemple, si la page
se trouvait sur le deuxieme noeud valable du precedent cpuset, alors la
page sera placee sur le deuxieme noeud valable du nouveau cpuset, si
c'est possible.
R'epartition de la charge par l'ordonnanceur
L'ordonnanceur du noyau repartit automatiquement la charge des
processus. Si un CPU est sous-utilise, le noyau recherchera des
processus sur d'autres CPU plus charges et deplacera ces processus sur
le CPU sous-utilise a condition que les mecanismes comme les cpuset et
sched_setaffinity(2) le permettent.
Le cout de l'algorithme de repartition de la charge et son impact sur
les structures de donnees partagees du noyau, comme la liste des
processus, augmente plus que lineairement avec le nombre de CPU qui
interviennent pour la repartition de la charge. Par exemple le cout
pour la repartition de la charge dans un grand ensemble de CPU sera
superieur a celui pour la repartition de la charge dans deux ensembles
ayant moitie moins de CPU. (La relation entre le nombre de CPU
intervenant dans la repartition de la charge et le cout de cette
repartition de charge depend de l'implementation de l'ordonnanceur de
processus du noyau, qui change dans le temps quand de meilleurs
algorithmes d'ordonnancement sont implementes)
Le drapeau sched_load_balance d'un cpuset permet de supprimer cette
repartition automatique de la charge dans les cas ou elle n'est pas
necessaire et que sa suppression ameliorerait les performances.
Par defaut, la repartition de la charge se fait sur tous les CPU, a
l'exception de ceux marques comme etant isoles en utilisant au moment
du demarrage le parametre du noyau << isolcpus= >>. (Consultez la
section Niveau du domaine de d'etente de l'ordonnanceur ci-dessous pour
changer le comportement par defaut)
Cette repartition de la charge par defaut n'est pas bien adaptee aux
situations suivantes :
* Sur les gros systemes, la repartition de la charge sur beaucoup de
CPU est tres couteuse. Si le systeme est gere avec des cpusets pour
placer les taches independantes sur differents ensembles de CPU, une
repartition de la charge complete n'est pas necessaire.
* Les systemes avec une prise en charge temps-reel sur certains CPU
doivent minimiser la surcharge du systeme sur ces CPU et donc eviter
la repartition de la charge des processus si elle n'est pas
necessaire.
Quand le drapeau sched_load_balance d'un cpuset est active (ce qui est
le cas par defaut), une repartition de la charge sur tous les CPU
autorises par le cpuset est demande, a condition que le processus
puisse etre deplace d'un CPU du cpuset a un autre CPU (c'est-a-dire
qu'il n'ait pas ete attache a des CPU avec, par exemple,
sched_setaffinity(2)).
Quand le drapeau sched_load_balance d'un cpuset est desactive, alors
l'ordonnanceur evitera de deplacer des processus pour repartir la
charge des CPU du cpuset, sauf si un autre cpuset partage le meme CPU
et a son drapeau sched_load_balance active.
Ainsi, par exemple, si le cpuset racine a son drapeau
sched_load_balance active, alors l'ordonnanceur repartira la charge sur
tous les CPU et la configuration du drapeau sched_load_balance des
autres cpusets n'a pas d'effet, puisqu'une repartition complete de la
charge est deja demandee.
Dans les deux situations ci-dessus, le drapeau sched_load_balance
devrait donc etre desactive sur le cpuset racine et seuls les cpusets
fils plus petits devraient l'activer.
Lorsque vous faites ceci, vous ne devez generalement pas laisser un
processus non attache a un CPU dans le cpuset racine qui pourrait
utiliser les CPU de facon non negligeable. De cette facon les processus
peuvent etre artificiellement contraints a un sous ensemble des CPU en
fonction de la configuration de ce drapeau dans les cpusets
descendants. Meme si ce processus pourrait utiliser des cycles CPU
inutilises par certains CPU, l'ordonnanceur du noyau ne cherchera pas a
repartir la charge du processus sur le CPU sous utilise.
Bien sur, les processus attaches a un CPU particulier peuvent etre
laisses dans un cpuset qui desactive sched_load_balance puisque ces
processus ne peuvent etre deplaces de toute facon.
Niveau du domaine de d'etente de l'ordonnanceur
L'ordonnanceur du noyau effectue une repartition de la charge immediate
lorsqu'un CPU devient disponible ou lorsqu'une autre tache est prete.
Cette repartition de la charge permet de s'assurer que le plus de CPU
possibles sont utilises efficacement en executant des taches. Le noyau
effectue aussi une repartition de la charge de facon plus sporadique
sur la base de l'horloge logicielle decrite dans time(7). La
configuration de sched_relax_domain_level ne s'applique qu'a la
repartition de charge automatique. Independamment de la configuration
de sched_relax_domain_level, une repartition de charge sporadique est
effectuee a travers tous les CPU (sauf si cela a ete desactive avec
sched_load_balance). Dans tous les cas, bien sur, les taches ne seront
executees que sur les CPU autorises par leur cpuset et par les appels
systemes sched_setaffinity(2).
Sur les petits systemes, avec peu de CPU, la repartition de charge
immediate est utile pour ameliorer l'interactivite du systeme et
minimiser les cycles CPU inutilises. Mais sur les gros systemes,
essayer de repartir la charge immediatement sur un nombre important de
CPU peut etre plus couteux que ce que ca ne rapporte, en fonction des
performances des differentes taches et du materiel.
La signification exacte des petites valeurs de sched_relax_domain_level
dependra de l'implementation de l'ordonnanceur du noyau et de
l'architecture non uniforme du materiel. Ces deux parametres evolueront
dans le temps et dependent de l'architecture du systeme et de la
version du noyau.
A ce jour, quand cette capacite a ete 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 immediatement une repartition de la charge sur les
differents Hyper-Thread freres d'un meme coeur.
(2) Effectuer immediatement une repartition de la charge sur les
differents coeurs d'un processeur.
(3) Effectuer immediatement une repartition de la charge sur les
differents CPU d'un meme noeud ou d'une meme lame.
(4) Effectuer immediatement une repartition de la charge sur les
differents (detail d'implementation) noeuds [pour les systemes
NUMA].
(5) Effectuer immediatement une repartition de la charge sur tous les
CPU d'un systeme [pour les systemes NUMA].
La valeur zero (0) pour sched_relax_domain_level signifie toujours
qu'il n'y a pas de repartition de charge immediate, et donc la
repartition de la charge s'effectue periodiquement et non pas
immediatement quand un CPU devient disponible ou qu'une tache peut etre
executee.
La valeur -1 pour sched_relax_domain_level signifie toujours qu'il faut
utiliser la valeur par defaut du systeme. La valeur par defaut du
systeme peut varier en fonction de l'architecture et du noyau. Cette
valeur par defaut du systeme peut etre modifiee en fournissant au noyau
un parametre << relax_domain_level= >> lors du demarrage.
Si des cpusets partagent des CPU et ont des valeurs de
sched_relax_domain_level incompatibles, alors la valeur la plus elevee
s'applique a tous les CPU de ces cpusets. Dans ce cas, la valeur moins
un (-1) est la valeur la plus faible, remplacee par toute autre valeur
et la valeur z'ero (0) est la valeur la plus faible suivante.
FORMATS
Les formats suivants sont utilises pour representer des ensembles de
CPU et de noeuds memoire.
Affichage sous forme de masque
L'Affichage sous forme de masque est utilise pour representer les
masques de bits des CPU et noeuds memoire dans le fichier
/proc/<pid>/status.
Ce format affiche chaque mot de 32 bits au format hexadecimal (en
utilisant les caracteres ASCII << 0 >> - << 9 >> et << a >> -
<< f >>) ; le debut des mots est complete par des zeros si necessaire.
Pour les masques de plus d'un mot, une virgule est utilisee pour
separer les mots. Les mots sont affiche au format grand boutiste, avec
le bit le plus significatif en premier. Les chiffres hexadecimaux d'un
mot utilise aussi l'ordre grand boutiste.
Le nombre de mots de 32 bits affiches est le nombre minimal necessaire
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 actives sera
affiche de cette facon :
00000001,00000001,00010117
Le premier << 1 >> correspond au bit 64, le second au bit 32, le
troisieme au bit 16, le quatrieme au bit 8, le cinquieme 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 numeros ou intervalles de CPU ou de noeuds memoire separes par
des virgules, en decimal au format ASCII.
Exemple d'Affichage sous forme de liste :
0-4,9 # bits 0, 1, 2, 3, 4 et 9 actives
0-2,7,12-14 # bits 0, 1, 2, 7, 12, 13 et 14 actives
R`EGLES
Les regles suivantes s'appliquent a chaque cpuset :
* Ses CPU et noeuds memoire doivent etre des sous-ensembles de ceux de
leur parent (ou les memes ensembles).
* Il ne peut etre marque avec cpu_exclusive que si son parent l'est.
* Il ne peut etre marque avec mem_exclusive que si son parent l'est.
* S'il est marque avec cpu_exclusive, ses CPU ne doivent pas etre
partages avec ses freres.
* S'il est marque avec memory_exclusive, ses noeuds memoire ne doivent
pas etre partages avec ses freres.
PERMISSIONS
Les permissions d'un cpuset sont determinees par les permissions des
repertoires et pseudo-fichiers du systeme de fichiers cpuset,
normalement monte dans /dev/cpuset.
Par exemple, un processus peut se placer dans un autre cpuset s'il peut
ecrire dans le fichier tasks de ce cpuset. Ceci necessite les
permission d'execution des repertoires a traverser et la permission
d'ecrire dans le fichier tasks.
Une contrainte supplementaire s'applique aux demandes de deplacement
d'autres processus dans un cpuset. Un processus ne peut pas attacher un
autre processus a un cpuset a moins qu'il ait la permission d'envoyer
un signal a ce processus (consultez kill(2)).
Un processus peut creer un cpuset fils s'il a acces et peut ecrire dans
le repertoire du cpuset pere. Il peut modifier les CPU et noeuds
memoire d'un cpuset s'il a acces au repertoire de ce cpuset (les
permissions d'executer tous les repertoires parents) et s'il peut
ecrire dans les fichiers correspondants cpus ou mems.
Il y a une petite difference entre la maniere dont ces permissions sont
evaluees et la maniere dont sont evaluees les permissions pour les
operations sur des systemes de fichiers normaux. Le noyau interprete
les chemins relatifs en fonction du repertoire de travail actuel d'un
processus. Meme quand on opere sur un fichier d'un cpuset, les chemins
relatifs sont interpretes en fonction du repertoire de travail du
processus, et non pas relativement au cpuset actuel du processus. Les
seules facons pour que les chemins de cpusets soient interpretes
relativement au cpuset actuel du processus sont soit que le processus
utilise le repertoire du cpuset comme repertoire de travail (il a
d'abord effectue un cd ou chdir(2) dans le repertoire de son cpuset
dans /dev/cpuset, ce qui est plutot inhabituel), soit que du code
utilisateur convertit le chemin relatif au cpuset en un chemin absolu.
En theorie, ceci signifie que le code utilisateur devrait indiquer les
cpusets en utilisant des chemins absolus, ce qui necessite de connaitre
le point de montage du systeme de fichier cpuset (d'habitude, mais sans
que ce soit necessaire, /dev/cpuset). En pratique, a la connaissance de
l'auteur, tous les utilitaires en mode utilisateur supposent que si le
systeme de fichier cpuset est monte, alors il est monte dans
/dev/cpuset. De plus, une pratique assez courante utilise pour du code
ecrit soigneusement consiste a verifier la presence du pseudo-fichier
/dev/cpuset/tasks afin de verifier que le pseudo-systeme de fichiers
cpuset est bien monte.
AVERTISSEMENTS
Activation de memory_pressure
Par defaut, le fichier memory_pressure d'un cpuset vaut zero (0). A
moins que cette fonctionnalite soit activee en ecrivant << 1 >> dans le
pseudo-fichier /dev/cpuset/memory_pressure_enabled, le noyau ne calcule
pas les valeurs des fichiers memory_pressure des cpusets individuels.
Utilisation de la commande echo
Lorsque la commande echo est utilisee dans un interpreteur de commandes
pour changer les valeurs des fichiers d'un cpuset, soyez conscient que
la commande echo interne a certains interpreteurs de commandes
n'affiche pas de message d'erreur si l'appel systeme write(2) echoue.
Par exemple, si la commande :
echo 19 > mems
echoue parce que le noeud memoire numero 19 n'est pas autorise (par
exemple le systeme n'a pas de noeud memoire numero 19), alors la
commande echo peut n'afficher aucune erreur. If faut mieux utiliser la
commande externe /bin/echo pour changer la configuration d'un fichier
d'un cpuset puisque cette commande affichera les erreurs de write(2),
comme par exemple :
/bin/echo 19 > mems
/bin/echo : erreur d'ecriture : Le resultat numerique est en dehors de l'intervalle
EXCEPTIONS
Placement m'emoire
Les contraintes des cpusets ne s'appliquent pas a toutes les
allocations de memoire systeme pour les raisons suivantes :
Si la fonctionnalite de connexion a chaud est utilisee pour supprimer
tous les CPU d'un cpuset, alors le noyau mettra a jour automatiquement
la liste de CPU autorises (cpus_allowed) de tous les processus attaches
aux CPU du cpuset et autorisera tous les CPU. Le comportement est
similaire lorsque la fonctionnalite de connexion a chaud est utilisee
pour la memoire. En general, le noyau prefere ne pas tenir compte du
placement sur les CPU ou les noeuds memoire plutot que d'abandonner un
processus dont tous les CPU ou noeuds memoire autorises sont
deconnectes. Le code utilisateur devrait reconfigurer les cpusets pour
ne mentionner que les CPU et les noeuds memoire en ligne lorsque la
fonctionnalite de connexion a chaud est utilisee pour ajouter ou
retirer ces ressources.
Quelques demandes d'allocation memoire critiques et internes au noyau,
marquees GFP_ATOMIC, doivent etre satisfaites immediatement. Le noyau
peut rater des demandes ou ne pas fonctionner correctement si certaines
de ces allocations echouent. Si une de ces demandes ne peut etre
satisfaite par le cpuset du processus en cours, alors les contraintes
du cpuset sont relachees et le noyau recherche de la memoire la ou il
peut en trouver. Il est preferable de ne pas respecter un cpuset plutot
que de stresser le noyau.
Les allocations de memoire demandees 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 systeme rename(2) pour renommer des
cpusets. Seuls des renommages simples sont pris en charge ;
c'est-a-dire que changer le nom du repertoire d'un cpuset est autorise,
mais deplacer le repertoire d'un cpuset dans un autre repertoire n'est
pas autorise.
ERREURS
L'implementation des cpusets du noyau Linux positionne errno pour
indiquer la raison de l'echec d'un appel systeme lie a un cpuset.
Les valeurs possible pour errno et leurs significations, lors d'un
echec d'un appel systeme lie a un cpuset sont listees ci-dessous :
E2BIG Tentative d'ecriture (write(2)) dans un fichier special d'un
cpuset avec une longueur superieure a la longueur autorisee par
le noyau pour ces ecritures.
EACCES Tentative d'ecriture (write(2)) d'un identifiant de processus
(PID) dans le fichier tasks d'un cpuset alors que l'appelant
n'est pas autorise a deplacer le processus.
EACCES Tentative d'ajout, avec write(2), d'un CPU ou d'un noeud memoire
dans un cpuset alors que ce CPU ou ce noeud memoire ne se trouve
pas dans le cpuset parent.
EACCES Tentative d'activation, avec write(2), de cpu_exclusive ou de
mem_exclusive sur un cpuset dont le parent n'a pas ces
proprietes.
EACCES Tentative d'ecriture (write(2)) dans un fichier memory_pressure.
EACCES Tentative de creation d'un fichier dans le repertoire d'un
cpuset.
EBUSY Tentative de suppression, avec rmdir(2), d'un cpuset auquel sont
attaches des processus.
EBUSY Tentative de suppression, avec rmdir(2), d'un cpuset ayant des
ensembles de CPU fils.
EBUSY Tentative de suppression d'un CPU ou d'un noeud memoire d'un
cpuset alors que le CPU ou le noeud memoire se trouve egalement
dans un des fils du cpuset.
EEXIST Tentative de creation, avec mkdir(2), d'un cpuset qui existe
deja.
EEXIST Tentative de renommage (rename(2)) d'un cpuset avec un nom deja
utilise.
EFAULT Tentative de lecture (read(2)) ou d'ecriture (write(2)) dans un
fichier d'un cpuset en utilisant un tampon en dehors de l'espace
memoire 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 respectes pour ce cpuset ou ses freres.
EINVAL Tentative d'ecriture (avec write(2)) d'une liste vide dans cpus
ou mems pour un cpuset auquel sont deja attaches des processus
ou des cpuset fils.
EINVAL Tentative d'ecriture (avec write(2)) dans cpus ou mems d'une
liste qui comprend un intervalle dont la borne superieure est
inferieure a la borne inferieure.
EINVAL Tentative d'ecriture (avec write(2)) dans cpus ou mems d'une
liste dont la chaine comprend un caractere non valable.
EINVAL Tentative d'ecriture (avec write(2)) dans le fichier cpus d'une
liste qui ne comprend aucun CPU en ligne.
EINVAL Tentative d'ecriture (avec write(2)) dans le fichier mems d'une
liste qui ne comprend aucun noeud memoire en ligne.
EINVAL Tentative d'ecriture (avec write(2)) dans le fichier mems d'une
liste qui comprend un noeud qui ne contient pas de memoire.
EIO Tentative d'ecriture (avec write(2)) dans le fichier tasks d'un
cpuset d'une chaine qui ne commence pas par un entier decimal au
format ASCII.
EIO Tentative de renommage (avec rename(2)) d'un cpuset dans un
autre repertoire.
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 creation, avec mkdir(2), d'un cpuset dont le nom du
repertoire de base fait plus de 255 caracteres.
ENAMETOOLONG
Tentative de creation, avec mkdir(2), d'un cpuset dont le chemin
complet, prefixe du point de montage compris (typiquement
<< /dev/cpuset/ >>), fait plus de 4095 caracteres.
ENODEV Le cpuset a ete supprime par un autre processus en meme temps
qu'une tentative d'ecriture (avec write(2)) sur un des
pseudo-fichiers du repertoire du cpuset.
ENOENT Tentative de creation, avec mkdir(2), d'un cpuset dans un cpuset
parent qui n'existe pas.
ENOENT Tentative d'acceder a (avec access(2)) ou d'ouvrir (avec
open(2)) un fichier inexistant du repertoire d'un cpuset.
ENOMEM Pas assez de memoire disponible pour le noyau ; ceci peut se
produire pour differents appels systeme lies aux cpusets, mais
seulement si le systeme manque beaucoup de memoire.
ENOSPC Tentative d'ecriture (avec write(2)) de l'identifiant d'un
processus dans le fichier tasks d'un cpuset alors que les
fichiers cpus ou mems sont vides.
ENOSPC Tentative d'ecriture (avec write(2)) d'un fichier cpus ou mems
vide dans un cpuset auquel sont attachees des taches.
ENOTDIR
Tentative de renommage (avec rename(2)) d'un cpuset qui n'existe
pas.
EPERM Tentative de suppression d'un fichier dans le repertoire d'un
cpuset.
ERANGE Une liste pour cpus ou mems a ete fournie au noyau mais comprend
un nombre trop grand pour que le noyau l'ajoute a son champ de
bits.
ESRCH Tentative d'ecriture (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 a ce que son nom indique, le parametre pid est en fait un
identifiant de thread. Chaque thread d'un groupe de threads peut etre
attache un cpuset different. La valeur renvoyee par un appel a
gettid(2) peut etre fournie comme parametre pid.
BOGUES
Les fichiers memory_pressure peuvent etre ouverts en ecriture en
demandant une creation ou troncature, mais dans ce cas write(2)
echouera en positionnant errno a EACCES, et les options de creation 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 a l'aide d'un interpreteur de commandes.
Cr'eer et s'attacher `a un cpuset.
Voici les etapes pour creer un nouveau cpuset et lui attacher
l'interpreteur de commandes en cours :
1) mkdir /dev/cpuset (si ce n'est deja fait)
2) mount -t cpuset none /dev/cpuset (si ce n'est deja fait)
3) Creer un nouveau cpuset avec mkdir(1).
4) Assigner des CPU et noeuds memoire au nouveau cpuset.
5) Attacher l'interpreteur de commandes au nouveau cpuset.
Par exemple, la sequence de commandes suivante definira un cpuset
appele << Charlie >>, ne contenant que les CPU 2 et 3 et le noeud
memoire 1, et attachera l'interpreteur de commandes en cours a ce
cpuset.
$ mkdir /dev/cpuset
$ mount -t cpuset cpuset /dev/cpuset
$ cd /dev/cpuset
$ mkdir Charlie
$ cd Charlie
$ /bin/echo 2-3 > cpus
$ /bin/echo 1 > mems
$ /bin/echo $$ > tasks
# Le shell en cours s'execute desormais dans le cpuset Charlie
# La ligne suivante devrait afficher << /Charlie >>
$ cat /proc/self/cpuset
D'eplacer des t^aches sur d'autres noeuds m'emoire.
Pour deplacer les taches attachees a un cpuset sur d'autres CPU et
d'autres noeuds memoire du systeme et deplacer les pages memoires
actuellement allouees par ces processus, effectuez les etapes
suivantes :
1) Supposons qu'il faille deplacer les taches du cpuset alpha (les CPU
4-7 et noeuds memoire 2-3) vers un autre cpuset beta (CPU 16-19 et
noeuds memoire 8-9).
2) Creer d'abord le nouveau cpuset beta.
3) Autoriser les CPU 16-19 et les noeuds memoire 8-9 pour beta.
4) Activer memory_migration dans beta.
5) Deplacer chaque tache d'alpha vers beta.
La sequence de commandes suivante effectue cela.
$ cd /dev/cpuset
$ mkdir beta
$ cd beta
$ /bin/echo 16-19 > cpus
$ /bin/echo 8-9 > mems
$ /bin/echo 1 > memory_migrate
$ while read i; do /bin/echo $i; done < ../alpha/tasks > tasks
La sequence ci-dessus deplace tous les processus de alpha vers beta et
deplace toute memoire utilisee par ces processus sur les noeuds memoire
2-3 vers les noeuds memoire 8-9.
Notez que la derniere etape de la sequence ci-dessus n'etait pas :
$ cp ../alpha/tasks tasks
La boucle while, plutot que l'utilisation de la commande cp(1), est
necessaire par ce qu'un seul identifiant de processus a la fois peut
etre ecrit dans le fichier tasks.
La meme chose (l'ecriture d'un PID a la fois) peut se faire plus
efficacement qu'avec la boucle while, en moins de caractere et dans une
syntaxe qui fonctionne avec tous les interpreteurs de commandes mais
malheureusement de facon moins intelligible, en utilisant l'option -u
(sans tampon) de sed(1) :
$ sed -un p < ../alpha/tasks > tasks
VOIR AUSSI
taskset(1), get_mempolicy(2), getcpu(2), mbind(2),
sched_getaffinity(2), sched_setaffinity(2), sched_setscheduler(2),
set_mempolicy(2), CPU_SET(3), proc(5), numa(7), migratepages(8),
numactl(8)
Le fichier Documentation/cpusets.txt des sources du noyau.
COLOPHON
Cette page fait partie de la publication 3.27 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent etre trouvees a l'adresse
<URL:http://www.kernel.org/doc/man-pages/>.
TRADUCTION
Depuis 2010, cette traduction est maintenue a l'aide de l'outil po4a
<URL:http://po4a.alioth.debian.org/> par l'equipe de traduction
francophone au sein du projet perkamon
<URL:http://perkamon.alioth.debian.org/>.
Alain Portal <URL:http://manpagesfr.free.fr/> (2008).
Veuillez signaler toute erreur de traduction en ecrivant a
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir acces a la version anglaise de ce document
en utilisant la commande << man -L C <section> <page_de_man> >>.