sched(7) Miscellaneous Information Manual sched(7)
NOM
sched - Apercu de l'ordonnancement de CPU
DESCRIPTION
Depuis Linux 2.6.23, l'ordonnanceur par defaut est CFS (Completely Fair
Scheduler - ordonnanceur completement equitable). Il remplace
l'ordonnanceur precedent, << O(1) >>.
Resume des API
Linux fournit les appels systeme suivants pour controler le
comportement de l'ordonnancement du CPU, la politique et la priorite
des processus (ou, plus precisement, des threads).
nice(2)
Definir une nouvelle valeur de politesse pour le thread appelant
et renvoyer cette nouvelle valeur.
getpriority(2)
Renvoyer la valeur de politesse d'un thread, d'un groupe de
processus ou de l'ensemble des threads possedes par un
utilisateur particulier.
setpriority(2)
Definir la valeur de politesse d'un thread, d'un groupe de
processus ou de l'ensemble des threads possedes par un
utilisateur particulier.
sched_setscheduler(2)
Definir la politique d'ordonnancement et les parametres du
thread indique.
sched_getscheduler(2)
Renvoyer la politique d'ordonnancement du thread indique.
sched_setparam(2)
Definir les parametres d'ordonnancement du thread indique.
sched_getparam(2)
Recuperer les parametres d'ordonnancement du thread indique.
sched_get_priority_max(2)
Renvoyer la priorite la plus haute disponible pour la politique
d'ordonnancement indiquee.
sched_get_priority_min(2)
Renvoyer la priorite la plus basse disponible pour la politique
d'ordonnancement indiquee.
sched_rr_get_interval(2)
Recuperer le quantum de temps alloue utilise pour les threads
ordonnances par une politique de type repartition par tourniquet
(round robin).
sched_yield(2)
Provoquer la liberation du CPU par l'appelant afin de permettre
l'execution d'autres threads.
sched_setaffinity(2)
Definir le masque d'affinite CPU du thread indique (propre a
Linux).
sched_getaffinity(2)
Recuperer le masque d'affinite CPU du thread indique (propre a
Linux).
sched_setattr(2)
Definir la politique d'ordonnancement et les parametres du
thread indique. Cet appel systeme (propre a Linux) fournit un
sur-ensemble de la fonctionnalite de sched_setscheduler(2) et de
sched_setparam(2).
sched_getattr(2)
Recuperer la politique d'ordonnancement et les parametres du
thread indique. Cet appel systeme (propre a Linux) fournit un
sur-ensemble de la fonctionnalite de sched_getscheduler(2) et de
sched_getparam(2).
Politiques d'ordonnancement
L'ordonnanceur est la partie du noyau qui decide quel thread pret va
etre execute ensuite. Chaque processus a une politique d'ordonnancement
associee et une priorite d'ordonnancement statique, sched_priority.
L'ordonnanceur prend ses decisions en fonction de la politique
d'ordonnancement et de la priorite statique de tous les threads du
systeme.
Pour les threads ordonnances sous l'une des politiques d'ordonnancement
normales (SCHED_OTHER, SCHED_IDLE, SCHED_BATCH), sched_priority n'est
pas utilisee dans les decisions d'ordonnancement (et doit valoir 0).
Les processus ordonnances sous l'une des politiques d'ordonnancement
temps reel (SCHED_FIFO, SCHED_RR) ont une valeur sched_priority dans
l'intervalle 1 (faible) a 99 (haute). (Comme les nombres l'impliquent,
les threads temps reel ont toujours une priorite plus haute que les
threads normaux.) Notez bien : POSIX.1 exige d'une implementation
qu'elle gere seulement un minimum de 32 niveaux de priorite distincts
pour les politiques temps reel et certains systemes n'offrent que ce
minimum. Les programmes portables doivent utiliser
sched_get_priority_min(2) et sched_get_priority_max(2) pour connaitre
l'intervalle des priorites gerees pour une politique particuliere.
Theoriquement, l'ordonnanceur entretient une liste de tous les threads
prets pour l'execution pour chaque valeur possible de sched_priority.
Afin de determiner quel processus doit s'executer ensuite,
l'ordonnanceur recherche la liste non vide de plus haute priorite
statique et choisit le thread en tete de cette liste.
La politique d'ordonnancement d'un thread determine l'emplacement ou il
sera insere dans la liste contenant les threads de meme priorite
statique et comment il se deplacera dans cette liste.
Tout ordonnancement est preemptif : si un thread avec une priorite
statique plus elevee devient pret, le thread actuellement en cours
d'execution est interrompu et retourne dans la liste d'attente avec son
niveau de priorite statique. La politique d'ordonnancement determine
l'ordre utilise seulement dans la liste de threads prets avec des
priorites statiques egales.
SCHED_FIFO : Ordonnancement premier entre, premier sorti
SCHED_FIFO ne peut etre utilisee qu'avec des priorites statiques
superieures a 0, ce qui signifie que des qu'un thread SCHED_FIFO
devient pret, il preempte n'importe quel thread SCHED_OTHER,
SCHED_BATCH ou SCHED_IDLE en cours d'execution. SCHED_FIFO est un
ordonnancement simple sans decoupage temporel. Pour les threads
ordonnances selon la politique SCHED_FIFO, les regles suivantes sont
appliquees :
- Un thread SCHED_FIFO qui a ete preempte par un autre thread de
priorite superieure restera en tete de liste pour sa priorite et
reprendra son execution des que tous les threads de priorite
superieure seront a nouveau bloques.
- Quand un thread SCHED_FIFO bloque devient pret, il est insere en fin
de liste pour sa priorite.
- Si un appel a sched_setscheduler(2), sched_setparam(2),
sched_setattr(2), pthread_setschedparam(3) ou
pthread_setschedprio(3) modifie la priorite du thread SCHED_FIFO
pret ou en cours d'execution, identifie par pid, l'effet sur la
position du thread dans la liste depend de la direction de la
modification de la priorite des threads :
(a) Si la priorite du thread est relevee, il est place en fin de
liste pour sa nouvelle priorite. Par consequent, il peut
preempter un thread en cours d'execution ayant la meme
priorite.
(b) Si la priorite du thread est inchangee, sa position dans la
liste des executions est inchangee.
(c) Si la priorite du thread est abaissee, il est place en tete de
liste pour sa nouvelle priorite.
Selon POSIX.1-2008, les modifications de priorite (ou politique) de
thread en utilisant tout autre mecanisme que pthread_setschedprio(3)
devraient aboutir a ce que le thread soit place en fin de liste pour
sa priorite.
- Un thread appelant sched_yield(2) sera place en fin liste.
Aucun autre evenement ne deplacera un thread ordonnance selon la
politique SCHED_FIFO dans la liste d'attente des threads prets de
priorite statique equivalente.
Un thread SCHED_FIFO s'execute jusqu'a ce qu'il soit bloque par une
requete d'entree-sortie, qu'il soit preempte par un thread de priorite
superieure ou qu'il appelle sched_yield(2).
SCHED_RR : ordonnancement tourniquet
SCHED_RR est une amelioration simple de SCHED_FIFO. Tout ce qui est
decrit pour SCHED_FIFO s'applique aussi a SCHED_RR, sauf que chaque
thread ne dispose que d'un quantum de temps maximal pour son execution.
Si l'execution d'un thread SCHED_RR est d'une duree superieure ou egale
au quantum de temps, il sera place en fin de liste pour sa priorite. Un
thread SCHED_RR qui a ete preempte par un thread de priorite superieure
et par consequent qui reprend l'execution en tant que thread en cours,
terminera la part non utilisee de son quantum de temps dans le
tourniquet. La valeur du quantum de temps peut etre lue avec
sched_rr_get_interval(2).
SCHED_DEADLINE: ordonnancement sur echeances selon le modele des taches
sporadiques.
Depuis Linux 3.14, Linux offre une politique d'ordonnancement sur
echeances (SCHED_DEADLINE). L'implementation actuelle de cette
politique repose sur les algorithmes GEDF (Global Earliest Deadline
First, ou << priorite globale a l'echeance proche >>) et CBS (Constant
Bandwidth Server, ou << serveur a bande passante constante >>) utilises
conjointement. Pour definir ou recuperer cette politique et ses
attributs associes, les appels systeme sched_setattr(2) et
sched_getattr(2) doivent etre utilises.
Une tache sporadique presente une sequence de sous-taches qui sont
chacune activees au moins une fois par periode. Chaque sous-tache a
egalement une echeance relative, avant laquelle elle doit achever son
execution, et un temps d'execution qui est le temps CPU necessaire pour
qu'elle s'execute. Le moment auquel une tache est activee parce qu'une
sous-tache doit etre executee est appele temps d'activation (egalement
designe temps d'appel (<< request time >>) ou temps de liberation
(<< release time >>)). Le temps de lancement est le moment auquel la
tache commence son execution. L'echeance imperative est obtenue en
additionnant l'echeance relative et le temps d'activation.
Le schema suivant illustre ces termes :
activation/reveil echeance imperative
| temps du lancement |
| | |
v v v
-----x--------xoooooooooooooooooooooooo--------x--------x---
|<- temps d'execution ->|
|<---------- echeance relative ---------->|
|<----------------- periode ---------------------->|
Lorsqu'une politique SCHED_DEADLINE est activee au moyen de
sched_setattr(2), il est possible de preciser trois parametres :
Runtime, Deadline et Period. Ces parametres ne correspondent pas
forcement aux termes decrits precedemment : il est d'usage d'affecter a
Runtime une valeur superieure au temps d'execution moyen (ou le pire
temps d'execution possible, pour les cas de temps reel extremes) ;
Deadline prend la valeur de l'echeance relative ; enfin, Period recoit
la valeur de la periode de la tache. Ainsi, pour un ordonnancement
SCHED_DEADLINE, on obtient.
activation/reveil echeance imperative
| temps du lancement |
| | |
v v v
-----x--------xoooooooooooooooooooooooo--------x--------x---
|<------- Execution ------->|
|<----------------- Echeance ------------>|
|<----------------- Periode ---------------------->|
Les trois parametres de configuration de l'ordonnancement sur echeances
correspondent aux champs sched_runtime, sched_deadline et sched_period
de la structure sched_attr (consultez sched_setattr(2)). Ces champs
sont exprimes en nanosecondes. Si la valeur 0 est affectee a
sched_period, ce parametre prend la valeur de sched_deadline.
Le noyau exige que :
sched_runtime <= sched_deadline <= sched_period
De plus, dans l'implementation actuelle, tous les parametres doivent
valoir au moins 1024 (c'est a dire a peine plus qu'une microseconde,
qui est la resolution de cette implementation) et moins de 2^63. Si la
valeur de l'un de ces parametres sort de cet intervalle,
sched_setattr(2) echoue en renvoyant l'erreur EINVAL.
Le CBS assure que les differentes taches n'interferent pas en bloquant
les threads qui tentent de depasser leur temps d'execution (Runtime).
Pour que les conditions requises par l'ordonnancement sur echeances
soient remplies, le noyau doit empecher des situations dans lesquelles
l'ensemble des threads SCHED_DEADLINE n'est pas realisable
(ordonnancement non possible) en tenant compte des contraintes donnees.
Le noyau doit donc executer un test d'approbation lorsque la politique
SCHED_DEADLINE et ses attributs sont definis ou modifies. Ce test
d'approbation valide que le changement demande est realisable ; si ce
n'est pas le cas, sched_setattr(2) echoue et renvoie l'erreur EBUSY.
Par exemple, il est necessaire (et par forcement suffisant) pour
l'utilisation totale d'etre inferieure ou egale au nombre total de CPU
disponibles, ou, puisque chaque thread peut s'executer au plus pour
Runtime par Period, l'utilisation pour ce thread vaut son Runtime
divise par sa Period.
Pour assurer les conditions qui sont requises lorsqu'un thread est
autorise a utiliser la politique SCHED_DEADLINE, les threads
SCHED_DEADLINE ont la priorite la plus elevee parmi tous les threads
(controlable par l'utilisateur) du systeme. Si un thread ordonnance
selon SCHED_DEADLINE est pret, il aura la priorite sur tout autre
thread ordonnance par une autre politique.
Un appel a fork(2) effectue par un thread ordonnance selon la politique
SCHED_DEADLINE echouera en renvoyant l'erreur EAGAIN, sauf dans le cas
ou l'attribut << reset-on-fork >> du thread est active (voir plus bas).
Un thread ordonnance selon SCHED_DEADLINE qui appelle sched_yield(2)
cedera la priorite a la sous-tache en cours et attendra une nouvelle
periode pour debuter.
SCHED_OTHER : ordonnancement temps partage par defaut
SCHED_OTHER peut etre utilise seulement pour la priorite statique 0
(c'est-a-dire que les threads sous politique temps reel ont la priorite
sur les processus SCHED_OTHER). SCHED_OTHER est l'ordonnanceur temps
partage de Linux prevu pour tous les threads n'ayant pas besoin des
mecanismes temps reel speciaux.
Le thread a executer est choisi dans la liste des threads de priorite
statique 0, en utilisant une priorite dynamique qui ne s'applique que
dans cette liste. La priorite dynamique est basee sur la valeur de
politesse (<< nice >>) du thread (voir ci-dessous) et est incrementee a
chaque quantum de temps ou le thread est pret, mais non selectionne par
l'ordonnanceur. Cela garantit une progression equitable de tous les
threads SCHED_OTHER.
Dans le code source du noyau Linux, la politique SCHED_OTHER est en
fait appelee SCHED_NORMAL.
La valeur de politesse
La valeur de politesse est un attribut pouvant etre utilise pour
influencer l'ordonnanceur en faveur ou defaveur d'un processus dans les
choix d'ordonnancement. Elle affecte l'ordonnancement des processus
SCHED_OTHER et SCHED_BATCH (voir ci-dessous). La valeur de politesse
peut etre modifiee avec nice(2), setpriority(2) ou sched_setattr(2).
Selon POSIX.1, la valeur de politesse est un attribut par processus,
c'est-a-dire que les threads dans un processus devraient partager la
valeur de politesse. Cependant, dans Linux, cette valeur est un
attribut par thread : des threads distincts dans le meme processus
peuvent avoir des valeurs de politesse differentes.
L'eventail des valeurs de politesse differe selon les systemes UNIX.
Dans un Linux moderne, il varie de -20 (priorite elevee) a +19
(priorite basse). Dans quelques autres systemes, la plage est de
-20 a 20. Les tout premiers noyaux Linux (avant Linux 2.0) avaient une
plage de -infini a 15 .
De meme, le degre auquel la valeur de politesse affecte
l'ordonnancement respectif des processus SCHED_OTHER varie selon les
systemes UNIX et selon les versions du noyau Linux.
Avec l'arrivee de l'ordonnanceur CFS dans Linux 2.6.23, Linux a adopte
un algorithme qui provoque des differences relatives aux valeurs de
politesse ayant un impact plus important. Dans l'implementation
actuelle, chaque unite de difference dans les valeurs de politesse dans
deux processus aboutit a un facteur de 1,25 dans le degre dont
l'ordonnancement favorise le processus de plus haute priorite. Cela
fait que les tres petites valeurs de priorite (+19) fournissent
vraiment peu de CPU pour un processus a chaque fois qu'il existe une
charge de plus haute priorite sur le systeme, et cela fait que les
hautes valeurs (-20) fournissent la plus grande partie du CPU aux
applications en ayant besoin (par exemple, certaines applications
audio).
Dans Linux, la limite de ressources RLIMIT_NICE peut etre utilisee pour
definir une limite jusqu'a laquelle une valeur de politesse de
processus non privilegie peut etre elevee. Consultez setrlimit(2) pour
les details.
Pour davantage d'explications a propos de la valeur de politesse,
consultez ci-dessous les sous-sections sur la fonctionnalite
d'autogroupe et sur l'ordonnancement de groupe.
SCHED_BATCH : ordonnancement de processus par lots
(Depuis Linux 2.6.16) SCHED_BATCH ne peut etre utilisee qu'avec une
priorite statique de 0. Cette politique est similaire a SCHED_OTHER en
ce qu'elle ordonnance les threads conformement a leur priorite
dynamique (basee sur la valeur de politesse). La difference est que
cette politique fera que l'ordonnanceur considerera toujours que ce
thread demande beaucoup de ressources processeur. Par consequent, il
lui appliquera une petite penalite d'ordonnancement vis-a-vis du
comportement au reveil, ainsi le thread sera legerement desavantage
dans les decisions d'ordonnancement.
Cette politique est utile pour les charges de travail non interactives,
mais qui ne souhaitent pas diminuer leur valeur de politesse, ou pour
celles qui veulent une politique d'ordonnancement deterministe sans que
l'interactivite ne cause de preemptions supplementaires (entre les
taches des charges).
SCHED_IDLE : ordonnancement de taches de tres faible priorite
(Depuis Linux 2.6.23.) SCHED_IDLE ne peut etre utilisee qu'avec une
priorite statique de 0 ; la valeur de politesse n'a pas d'influence
pour cette politique.
Cette politique est concue pour l'execution de taches de tres faible
priorite (inferieure meme a une valeur de politesse +19 avec les
politiques SCHED_OTHER ou SCHED_BATCH).
Reinitialiser la politique d'ordonnancement pour les processus enfant
Chaque thread possede un attribut d'ordonnancement reset-on-fork.
Lorsque cet attribut est defini, les enfants crees au moyen de fork(2)
n'heritent pas des politiques d'ordonnancement necessitant des droits.
L'attribut reset-on-fork peut etre defini soit :
- en appliquant un OU logique a l'attribut SCHED_RESET_ON_FORK dans
l'argument policy au moment de l'appel a sched_setscheduler(2) (a
partir de Linux 2.6.32) ;
- ou en ajoutant l'argument SCHED_FLAG_RESET_ON_FORK dans
attr.sched_flags au moment de l'appel a sched_setattr(2).
Notez que les constantes utilisees dans ces deux API ont des noms
differents. La disposition de l'attribut reset-on-fork peut, de facon
analogue, etre obtenue au moyen de sched_getscheduler(2) et de
sched_getattr(2).
La fonctionnalite reset-on-fork est prevue pour des applications de
lecture audiovisuelle et peut etre utilisee pour empecher les
applications de passer outre la limite de ressource RLIMIT_RTTIME
(consultez getrlimit(2)) en creant de nombreux processus enfant.
Plus precisement, si l'attribut reset-on-fork est utilise, les regles
suivantes seront appliquees lors de la creation ulterieure des
enfants :
- Si le thread appelant a une politique d'ordonnancement SCHED_FIFO ou
SCHED_RR, la politique pour les processus enfant est reinitialisee a
SCHED_OTHER.
- Si le processus appelant a une valeur de politesse negative, elle
est mise a zero pour les processus enfant.
Une fois que l'attribut reset-on-fork est active, il ne peut etre
desactive que si le thread possede la capacite CAP_SYS_NICE. Cet
attribut est desactive pour les processus enfant crees avec fork(2).
Privileges et limites de ressources
Avant Linux 2.6.12, seuls les threads privilegies (CAP_SYS_NICE)
pouvaient attribuer une priorite statique non nulle (c'est-a-dire
definir une politique d'ordonnancement temps reel). Le seul changement
qu'un thread non privilegie pouvait faire etait d'affecter la politique
SCHED_OTHER et cela ne pouvait etre fait que si l'UID effectif de
l'appelant etait le meme que l'UID reel ou effectif du thread cible
(c'est-a-dire le thread specifie par pid) dont la politique etait
modifiee.
Un thread doit avoir des droits specifiques (CAP_SYS_NICE) pour pouvoir
affecter ou modifier la politique SCHED_DEADLINE.
Depuis Linux 2.6.12, la limite de ressources RLIMIT_RTPRIO definit un
plafond pour la priorite statique d'un thread non privilegie pour les
politiques SCHED_RR et SCHED_FIFO. Les regles pour modifier la
politique d'ordonnancement et la priorite sont les suivantes :
- Si un thread non privilegie a une limite souple RLIMIT_RTPRIO non
nulle, il peut modifier sa politique et sa priorite
d'ordonnancement, a condition que la priorite reste inferieure au
maximum de sa priorite actuelle et a sa limite souple RLIMIT_RTPRIO.
- Si la limite souple RLIMIT_RTPRIO est nulle, les seules
modifications permises sont une diminution de la priorite ou bien un
basculement vers une politique qui n'est pas temps reel.
- Soumis aux memes regles, un autre thread non privilegie peut
egalement faire ces modifications a partir du moment ou l'UID
effectif du thread effectuant la modification correspond a l'UID
reel ou effectif du thread cible.
- Des regles particulieres s'appliquent a la politique SCHED_IDLE.
Avant Linux 2.6.39, un thread non privilegie operant sous cette
politique ne peut pas modifier sa politique, quelle que soit la
valeur de sa limite souple de ressources RLIMIT_RTPRIO. Depuis
Linux 2.6.39, un thread non privilegie peut basculer vers la
politique SCHED_BATCH ou SCHED_OTHER tant que sa valeur de politesse
tombe dans l'intervalle permis par sa limite de ressources
RLIMIT_NICE (consultez getrlimit(2)).
Les threads privilegies (CAP_SYS_NICE) ignorent la limite
RLIMIT_RTPRIO : comme avec d'anciens noyaux, ils peuvent modifier
arbitrairement la politique d'ordonnancement et la priorite. Consultez
getrlimit(2) pour plus d'informations sur RLIMIT_RTPRIO.
Limiter l'utilisation CPU des processus temps-reel et a echeances.
Une boucle sans fin non bloquante dans un thread ordonnance selon une
politique SCHED_FIFO, SCHED_RR ou SCHED_DEADLINE peut potentiellement
bloquer indefiniment l'acces au CPU de tous les threads. Avant
Linux 2.6.25, le seul moyen d'eviter qu'un processus temps reel hors de
controle ne bloque le systeme etait d'executer (sur la console) un
shell ayant un priorite statique superieure a celle de l'application
testee. Cela permettait d'executer en urgence une commande kill sur les
applications temps reel en cours de test qui ne se bloquaient pas ou ne
se terminaient pas comme prevu.
Depuis Linux 2.6.25, il existe d'autres techniques pour traiter le cas
des processus temps reel et a echeances qui sont hors de controle.
L'une de ces techniques consiste a utiliser la limite de ressources
RLIMIT_RTTIME pour definir la limite du temps CPU qu'un processus temps
reel a le droit de consommer. Consultez getrlimit(2) pour plus de
details.
Depuis, Linux 2.6.25 propose egalement deux fichiers /proc qui peuvent
etre utilises pour reserver une certaine quantite de temps CPU aux
processus non temps reel. La reservation de temps CPU par ce moyen
permet d'allouer du temps CPU, par exemple, a un shell administrateur
pour qu'il puisse executer une commande kill sur un processus hors de
controle. Ces deux fichiers definissent des valeurs exprimees en
microseconde :
/proc/sys/kernel/sched_rt_period_us
Ce fichier definit une periode d'ordonnancement correspondant a
100 % de la bande passante du CPU. La valeur contenue dans ce
fichier peut aller de 1 a INT_MAX, soit une duree allant de
1 microseconde a environ 35 minutes. La valeur par defaut
contenue dans ce fichier est 1 000 000 (1 seconde).
/proc/sys/kernel/sched_rt_runtime_us
La valeur contenue dans ce fichier definit quelle part d'une
<< periode >> peut etre utilisee par des processus temps reel et
a echeances. La valeur contenue dans ce fichier peut aller de -1
a INT_MAX -1. -1 fixe un temps d'execution egal a la periode,
c'est a dire qu'aucun temps CPU n'est reserve pour les processus
non temps reel (ce qui correspond au comportement avant
Linux 2.6.25 du noyau). La valeur par defaut contenue dans ce
fichier est 950 000 (0,95 seconde), ce qui signifie que 5 % du
temps CPU est reserve aux processus qui ne s'executent pas selon
une politique d'ordonnancement temps reel ou a echeances.
Temps de reponse
Un thread de haute priorite bloque en attente d'entrees-sorties est
affecte d'un certain temps de reponse avant d'etre selectionne a
nouveau. Le concepteur d'un gestionnaire de peripherique peut reduire
grandement ce temps de reponse en utilisant un gestionnaire
d'interruptions << lentes >>.
Divers
Les processus enfant heritent de la politique d'ordonnancement et des
parametres associes lors d'un fork(2). La politique et les parametres
d'ordonnancement sont conserves au travers d'un execve(2).
Le verrouillage de pages en memoire est generalement necessaire pour
les processus temps reel afin d'eviter les delais de pagination ; cela
peut etre effectue avec mlock(2) ou mlockall(2).
Fonctionnalite d'autogroupage
Depuis Linux 2.6.38, le noyau fournit une fonctionnalite connue comme
l'autogroupage pour ameliorer les performances des bureaux interactifs
confrontes a des charges de travail multiprocessus utilisant enormement
le CPU telles que la construction du noyau Linux avec un grand nombre
de processus de construction en parallele (c'est-a-dire l'indicateur -j
de make(1)).
Cette fonction opere en conjonction avec l'ordonnancement CFS et
necessite un noyau configure avec CONFIG_SCHED_AUTOGROUP. Sur un
systeme en cours d'execution, cette fonctionnalite est activee ou
desactivee a l'aide du fichier
/proc/sys/kernel/sched_autogroup_enabled. Une valeur 0 desactive cette
fonctionnalite tandis qu'une valeur 1 l'active. La valeur par defaut
dans ce fichier est 1 a moins que le noyau ait ete amorce avec le
parametre noautogroup.
Un nouvel autogroupe est cree quand une nouvelle session est creee a
l'aide de setsid(2). Cela se produit, par exemple, quand une nouvelle
fenetre de terminal est demarree. Un nouveau processus cree par fork(2)
herite de l'appartenance d'autogroupe de son parent. Par consequent,
tous les processus dans une session sont membres du meme autogroupe. Un
autogroupe est automatiquement detruit quand le dernier processus du
groupe se termine.
Lorsque l'autogroupage est active, tous les membres d'un autogroupe
sont places dans le meme ordonnanceur << groupe de taches >> du noyau.
L'ordonnanceur CFS emploie un algorithme qui egalise la distribution
des cycles du CPU entre les groupes de taches. Le benefice qui en
decoule pour la performance de bureau interactif peut etre decrit a
l'aide de l'exemple qui suit.
Supposons qu'il existe deux autogroupes en competition pour le meme CPU
(c'est-a-dire soit un systeme avec un seul CPU, soit l'utilisation de
taskset(1) pour confiner tous les processus sur le meme CPU sur un
systeme SMP). Le premier groupe contient dix processus lies a un CPU
d'une construction de noyau demarree avec make -j10. L'autre groupe
contient un seul processus lie a un CPU : un lecteur video. Le resultat
de l'autogroupage est que les deux groupes recevront chacun la moitie
des cycles CPU. C'est-a-dire que le lecteur video recevra 50 % des
cycles CPU, plutot que seulement 9 % des cycles, ce qui conduirait
probablement a une lecture video degradee. La situation sur le systeme
SMP est plus complexe, mais l'effet general est le meme :
l'ordonnanceur repartit les cycles CPU dans les groupes de taches de
telle facon qu'un autogroupe contenant un grand nombre de processus
lies a un CPU n'aboutisse pas a un accaparement des cycles CPU au
detriment des autres travaux dans le systeme.
L'appartenance a un autogroupe de processus (groupe de taches) peut
etre vue dans le fichier /proc/pid/autogroup :
$ cat /proc/1/autogroup
/autogroup-1 nice 0
Ce fichier peut aussi etre utilise pour modifier la bande passante de
CPU allouee a un autogroupe. Cela peut etre realise en ecrivant un
nombre dans le champ << nice >> du fichier pour definir la valeur de
politesse de l'autogroupe. L'intervalle autorise va de +19 (priorite
basse) a -20 (priorite haute). L'ecriture d'une valeur en dehors de cet
intervalle provoquera l'echec de write(2) avec l'erreur EINVAL.
Le reglage de la politesse de l'autogroupe a la meme acception que la
valeur de politesse du processus, mais s'applique a la repartition des
cycles CPU a un autogroupe dans son ensemble, basee sur les valeurs
relatives de politesse des autres autogroupes. Pour un processus dans
un autogroupe, les cycles CPU qu'il recoit sont deduits de la valeur de
politesse de l'autogroupe (comparee aux autres autogroupes) et de la
valeur de politesse du processus (comparee aux autres processus dans le
meme autogroupe).
L'utilisation du controleur de CPU cgroups(7) pour placer les processus
dans des cgroups autres que le cgroup racine du CPU contourne l'effet
de l'autogroupage.
La fonctionnalite d'autogroupage groupe seulement les processus
ordonnances selon des politiques non temps reel (SCHED_OTHER,
SCHED_BATCH et SCHED_IDLE). Elle ne groupe pas les processus
ordonnances selon les politiques temps reel et a echeances. Ceux-ci
sont ordonnances selon les regles decrites ci-dessus.
Valeur de politesse et ordonnancement de groupe
Lors de l'ordonnancement de processus non temps reel (c'est-a-dire ceux
ordonnances selon les politiques SCHED_OTHER, SCHED_BATCH et
SCHED_IDLE), L'ordonnanceur CFS emploie une technique connue comme
<< ordonnancement de groupe >> (group scheduling) si le noyau a ete
configure avec l'option CONFIG_FAIR_GROUP_SCHED (ce qui est typique).
Avec l'ordonnancement de groupe, les threads sont ordonnances dans des
<< groupes de taches >>. Celles-ci ont une relation hierarchique, avec
comme racine le groupe de taches initial du systeme connu comme
<< groupe de taches racine >> (root task group). Les groupes de taches
sont constitues dans les circonstances suivantes :
- Tous les threads dans un cgroup du CPU forment un groupe de taches.
Le parent de ce groupe de taches est le groupe de taches du cgroup
parent correspondant.
- Si l'autogroupage est active, alors tous les threads qui sont
(implicitement) places dans un autogroupe (c'est-a-dire la meme
session, telle que creee par setsid(2)) forment un groupe de taches.
Chaque nouvel autogroupe est par consequent un groupe de taches
distinct. Le groupe de taches racine est le parent de tous les
autogroupes de ce type.
- Si l'autogroupage est active, alors le groupe de taches racine se
compose de tous les processus dans le cgroup racine du CPU qui
n'etaient pas par ailleurs places implicitement dans un nouvel
autogroupe.
- Si l'autogroupage est desactive, alors le groupe de taches racine
est constitue de tous les processus dans le cgroup racine du CPU.
- Si l'ordonnancement de groupe a ete desactive (c'est-a-dire que le
noyau a ete configure sans CONFIG_FAIR_GROUP_SCHED), alors tous les
processus du systeme sont en theorie places dans un groupe de taches
unique.
Avec l'ordonnancement de groupe, une valeur de politesse de thread a un
effet sur les decisions d'ordonnancement seulement relatives aux autres
threads dans le meme groupe de taches. Cela a quelques consequences
surprenantes en terme de semantique traditionnelle de la valeur de
politesse sur les systemes UNIX. En particulier, si l'autogroupage est
active (par defaut dans diverses distributions), alors l'emploi de
setpriority(2) ou nice(1) sur un processus a un effet seulement sur
l'ordonnancement concernant les autres processus executes dans la meme
session (classiquement : la meme fenetre de terminal).
Inversement, pour deux processus qui sont (par exemple) les seuls
processus lies a un CPU dans differentes sessions (par exemple, des
fenetres distinctes de terminal, chacune des taches etant liee a un
autogroupe distinct), modifier la valeur de politesse du processus
d'une des sessions n'a pas d'effet en terme de decision
d'ordonnancement relative au processus dans l'autre session. Un
contournement utile possible consiste a utiliser une commande telle que
la suivante pour modifier la valeur de politesse de l'autogroupe pour
tous les processus dans une session de terminal :
$ echo 10 > /proc/self/autogroup
Fonctionnalites temps reel dans le noyau Linux principal
Depuis Linux 2.6.18, Linux a ete graduellement pourvu de capacites
temps reel, la plupart etant derivees de l'ancien ensemble de greffons
realtime-preempt. Jusqu'a ce que ces greffons aient ete entierement
fusionnes dans le noyau principal, ils devront etre installes pour
atteindre les meilleures performances temps reel. Ces greffons
s'appellent :
patch-version-noyau-rtversion-greffon
et peuvent etre telecharges a partir de .
Sans les greffons et avant leur complete inclusion dans le noyau
principal, la configuration du noyau n'offre que trois classes de
preemption CONFIG_PREEMPT_NONE, CONFIG_PREEMPT_VOLUNTARY et
CONFIG_PREEMPT_DESKTOP qui fournissent respectivement << aucune >>,
<< quelque >> et une << considerable >> reduction de la pire latence
d'ordonnancement.
Avec les greffons appliques ou apres leur pleine inclusion dans le
noyau principal, la configuration supplementaire CONFIG_PREEMPT_RT
devient disponible. Si elle est choisie, Linux est transforme en un
systeme d'exploitation temps reel ordinaire. Les politiques
d'ordonnancement FIFO et RR sont alors utilisees pour lancer un thread
avec une vraie priorite temps reel et une latence minimale
d'ordonnancement de pire cas.
NOTES
Le controleur cgroups(7) de CPU peut etre utilise pour limiter la
consommation de CPU par les groupes de processus.
A l'origine, le noyau Linux standard visait un systeme d'exploitation a
vocation generaliste, devant gerer des processus en arriere-plan, des
applications interactives et des applications en temps reel souples
(qui ont besoin en general de repondre a des criteres de temps
maximal). Bien que Linux 2.6 ait permis la preemption par le noyau et
que l'ordonnanceur O(1), nouvellement introduit, assure que le temps
necessaire pour planifier soit fixe et deterministe quel que soit le
nombre de taches, une vraie gestion temps reel n'etait pas possible
avant Linux 2.6.17.
VOIR AUSSI
chcpu(1), chrt(1), lscpu(1), ps(1), taskset(1), top(1), getpriority(2),
mlock(2), mlockall(2), munlock(2), munlockall(2), nice(2),
sched_get_priority_max(2), sched_get_priority_min(2),
sched_getaffinity(2), sched_getparam(2), sched_getscheduler(2),
sched_rr_get_interval(2), sched_setaffinity(2), sched_setparam(2),
sched_setscheduler(2), sched_yield(2), setpriority(2),
pthread_getaffinity_np(3), pthread_getschedparam(3),
pthread_setaffinity_np(3), sched_getcpu(3), capabilities(7), cpuset(7)
Programming for the real world - POSIX.4 de Bill O. Gallmeister,
O'Reilly & Associates, Inc., ISBN 1-56592-074-0.
Les fichiers source du noyau Linux Documentation/scheduler/
sched-deadline.txt, Documentation/scheduler/sched-rt-group.txt,
Documentation/scheduler/sched-design-CFS.txt et Documentation/
scheduler/sched-nice-design.txt
TRADUCTION
La traduction francaise de cette page de manuel a ete creee par
Christophe Blaess , Stephan Rafin
, Thierry Vignaud ,
Francois Micaux, Alain Portal , Jean-Philippe
Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas
Huriaux , Nicolas Francois
, Florentin Duneau
, Simon Paillard , Denis Barbier , David Prevot
, Cedric Boutillier ,
Frederic Hantrais et Jean-Paul Guillonneau
Cette traduction est une documentation libre ; veuillez vous reporter a
la GNU General Public License version 3
concernant les conditions
de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE.
Si vous decouvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message a .
Pages du manuel de Linux 6.9.1 2 mai 2024 sched(7)