X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=prochand.tex;h=f3329a855b5c0c9ccbbaee18210dc83584b5a6c1;hb=56f70e18112dfe513b3caa926cdcd90004dcbd69;hp=da1d5020ba81e2a5101fa70697eca06797bb5a5f;hpb=2dad1f27ee9d112d0711d71117c1d38d42a1a1c3;p=gapil.git diff --git a/prochand.tex b/prochand.tex index da1d502..f3329a8 100644 --- a/prochand.tex +++ b/prochand.tex @@ -146,20 +146,21 @@ fig.~\ref{fig:proc_task_struct}. % TODO la task_struct è cambiata per qualche dettaglio vedi anche % http://www.ibm.com/developerworks/linux/library/l-linux-process-management/ +% TODO completare la parte su quando viene chiamato lo scheduler. Come accennato in sez.~\ref{sec:intro_unix_struct} è lo \itindex{scheduler} \textit{scheduler} che decide quale processo mettere in esecuzione; esso viene eseguito ad ogni system call ed ad ogni interrupt,\footnote{più in una serie - di altre occasioni.} -% TODO completare questa parte su quando viene chiamato lo scheduler. -(ma può essere anche attivato esplicitamente). Il timer di sistema provvede -comunque a che esso sia invocato periodicamente; generando un interrupt -periodico secondo la frequenza specificata dalla costante -\const{HZ},\footnote{fino al kernel 2.4 il valore usuale di questa costante - era 100, per tutte le architetture eccetto l'alpha, per la quale era 1000, - nel 2.6 è stato portato a 1000 su tutte le architetture; occorre fare - attenzione a non confondere questo valore con quello dei - \itindex{clock~tick} \textit{clock tick} (vedi + di altre occasioni.} ma può essere anche attivato esplicitamente. Il timer +di sistema provvede comunque a che esso sia invocato periodicamente; generando +un interrupt periodico secondo la frequenza specificata dalla costante +\const{HZ},\footnote{fino al kernel 2.4 il valore di \const{HZ} era 100 su + tutte le architetture tranne l'alpha, per cui era 1000, nel 2.6 è stato + portato a 1000 su tutte; dal 2.6.13 lo si può impostare in fase di + compilazione del kernel, con un default di 250 e valori possibili di 100, + 250, 1000 e dal 2.6.20 anche 300 (che è divisibile per le frequenze di + refresh della televisione); occorre fare attenzione a non confondere questo + valore con quello dei \itindex{clock~tick} \textit{clock tick} (vedi sez.~\ref{sec:sys_unix_time}).} definita in \file{asm/param.h}, ed il cui valore è espresso in Hertz.\footnote{a partire dal kernel 2.6.21 è stato introdotto (a cura di Ingo Molnar) un meccanismo completamente diverso, @@ -171,7 +172,6 @@ valore da parte del processore che può essere messo in stato di sospensione anche per lunghi periodi di tempo.} - Ogni volta che viene eseguito, lo \itindex{scheduler} \textit{scheduler} effettua il calcolo delle priorità dei vari processi attivi (torneremo su questo in sez.~\ref{sec:proc_priority}) e stabilisce quale di essi debba @@ -2146,21 +2146,21 @@ fintanto che esso si trova in uno qualunque degli altri stati. \begin{table}[htb] \footnotesize \centering - \begin{tabular}[c]{|p{2.8cm}|c|p{10cm}|} + \begin{tabular}[c]{|p{2.4cm}|c|p{9cm}|} \hline \textbf{Stato} & \texttt{STAT} & \textbf{Descrizione} \\ \hline \hline \textbf{Runnable}& \texttt{R} & Il processo è in esecuzione o è pronto ad essere eseguito (cioè è in attesa che gli - venga assegnata la CPU). \\ + venga assegnata la CPU).\\ \textbf{Sleep} & \texttt{S} & Il processo è in attesa di un risposta dal sistema, ma può essere - interrotto da un segnale. \\ + interrotto da un segnale.\\ \textbf{Uninterrutible Sleep}& \texttt{D} & Il processo è in attesa di un risposta dal sistema (in genere per I/O), e non può essere - interrotto in nessuna circostanza. \\ + interrotto in nessuna circostanza.\\ \textbf{Stopped} & \texttt{T} & Il processo è stato fermato con un \const{SIGSTOP}, o è tracciato.\\ \textbf{Zombie}\index{zombie} & \texttt{Z} & Il processo è terminato ma il @@ -2982,12 +2982,196 @@ risorsa che i processi devono contendersi, un'altra, altrettanto importante per le prestazioni, è quella dell'accesso a disco. Per questo motivo sono stati introdotti diversi \textit{I/O scheduler} in grado di distribuire in maniera opportuna questa risorsa ai vari processi. Fino al kernel 2.6.17 era -possibile soltanto decidere le politiche di gestione scegliendo un diverso -\textit{I/O scheduler} +possibile soltanto differenziare le politiche generali di gestione, scegliendo +di usare un diverso \textit{I/O scheduler}; a partire da questa versione, con +l'introduzione dello scheduler CFQ (\textit{Completely Fair Queuing}) è +divenuto possibile, qualora si usi questo scheduler, impostare anche delle +diverse priorità di accesso per i singoli processi.\footnote{al momento + (kernel 2.6.31), le priorità di I/O sono disponibili soltanto per questo + scheduler.} + +La scelta dello scheduler di I/O si può fare in maniera generica a livello di +avvio del kernel assegnando il nome dello stesso al parametro +\texttt{elevator}, mentre se ne può indicare uno per l'accesso al singolo +disco scrivendo nel file \texttt{/sys/block/\textit{dev}/queue/scheduler} +(dove \texttt{\textit{dev}} è il nome del dispositivo associato al disco); gli +scheduler disponibili sono mostrati dal contenuto dello stesso file che +riporta fra parentesi quadre quello attivo, il default in tutti i kernel +recenti è proprio il \texttt{cfq},\footnote{nome con cui si indica appunto lo + scheduler \textit{Completely Fair Queuing}.} che supporta le priorità. Per i +dettagli sulle caratteristiche specifiche degli altri scheduler, la cui +discussione attiene a problematiche di ambito sistemistico, si consulti la +documentazione nella directory \texttt{Documentation/block/} dei sorgenti del +kernel. + +Una volta che si sia impostato lo scheduler CFQ ci sono due specifiche system +call, specifiche di Linux, che consentono di leggere ed impostare le priorità +di I/O.\footnote{se usate in corrispondenza ad uno scheduler diverso il loro + utilizzo non avrà alcun effetto.} Dato che non esiste una interfaccia +diretta nelle \acr{glibc} per queste due funzioni occorrerà invocarle tramite +la funzione \func{syscall} (come illustrato in +sez.~\ref{sec:intro_syscall}). Le due funzioni sono \funcd{ioprio\_get} ed +\funcd{ioprio\_set}; i rispettivi prototipi sono: +\begin{functions} + \headdecl{linux/ioprio.h} + \funcdecl{int ioprio\_get(int which, int who)} + \funcdecl{int ioprio\_set(int which, int who, int ioprio)} + + Rileva o imposta la priorità di I/O di un processo. + + \bodydesc{Le funzioni ritornano rispettivamente un intero positivo + (indicante la priorità) o 0 in caso di successo e $-1$ in caso di errore, + nel qual caso \var{errno} può assumere i valori: + \begin{errlist} + \item[\errcode{ESRCH}] non esiste il processo indicato. + \item[\errcode{EINVAL}] i valori di \param{which} e \param{who} non sono + validi. + \item[\errcode{EPERM}] non si hanno i privilegi per eseguire + l'impostazione (solo per \func{ioprio\_set}). + \end{errlist} } +\end{functions} + +Le funzioni leggono o impostano la priorità di I/O sulla base dell'indicazione +dei due argomenti \param{which} e \param{who} che hanno lo stesso significato +già visto per gli omonimi argomenti di \func{getpriority} e +\func{setpriority}. Anche in questo caso si deve specificare il valore +di \param{which} tramite le opportune costanti riportate in +tab.~\ref{tab:ioprio_args} che consentono di indicare un singolo processo, i +processi di un \textit{process group} (tratteremo questo argomento in +sez.~\ref{sec:sess_proc_group}) o tutti o processi di un utente. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|c|c|l|} + \hline + \param{which} & \param{who} & \textbf{Significato} \\ + \hline + \hline + \const{IPRIO\_WHO\_PROCESS} & \type{pid\_t} & processo\\ + \const{IPRIO\_WHO\_PRGR} & \type{pid\_t} & \itindex{process~group} + \textit{process group}\\ + \const{IPRIO\_WHO\_USER} & \type{uid\_t} & utente\\ + \hline + \end{tabular} + \caption{Legenda del valore dell'argomento \param{which} e del tipo + dell'argomento \param{who} delle funzioni \func{ioprio\_get} e + \func{ioprio\_set} per le tre possibili scelte.} + \label{tab:ioprio_args} +\end{table} + +In caso di successo \func{ioprio\_get} restituisce un intero positivo che +esprime il valore della priorità di I/O, questo valore è una maschera binaria +composta da due parti, una che esprime la \textsl{classe} di scheduling di I/O +del processo, l'altra che esprime, quando la classe di scheduling lo prevede, +la priorità del processo all'interno della classe stessa. Questo stesso +formato viene utilizzato per indicare il valore della priorità da impostare +con l'argomento \param{ioprio} di \func{ioprio\_set}. + +Per la gestione dei valori che esprimono le priorità di I/O sono state +definite delle opportune macro di preprocessore, riportate in +tab.~\ref{tab:IOsched_class_macro}. I valori delle priorità si ottengono o si +impostano usando queste macro. Le prime due si usano con il valore restituito +da \func{ioprio\_get} e per ottenere rispettivamente la classe di +scheduling\footnote{restituita dalla macro con i valori di + tab.~\ref{tab:IOsched_class}.} e l'eventuale valore della priorità. La terza +macro viene invece usata per creare un valore di priorità da usare come +argomento di \func{ioprio\_set} per eseguire una impostazione. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Macro} & \textbf{Significato}\\ + \hline + \hline + \macro{IOPRIO\_PRIO\_CLASS}\texttt{(\textit{value})} + & dato il valore di una priorità come + restituito da \func{ioprio\_get} estrae il + valore della classe.\\ + \macro{IOPRIO\_PRIO\_DATA}\texttt{(\textit{value})} + & dato il valore di una priorità come + restituito da \func{ioprio\_get} estrae il + valore della priorità.\\ + \macro{IOPRIO\_PRIO\_VALUE}\texttt{(\textit{class},\textit{prio})} + & dato un valore di priorità ed una classe + ottiene il valore numerico da passare a + \func{ioprio\_set}.\\ + \hline + \end{tabular} + \caption{Le macro per la gestione dei valori numerici .} + \label{tab:IOsched_class_macro} +\end{table} + +Le classi di scheduling previste dallo scheduler CFQ sono tre, e ricalcano tre +diverse modalità di distribuzione delle risorse analoghe a quelle già adottate +anche nel funzionamento dello scheduler del processore. Ciascuna di esse è +identificata tramite una opportuna costante, secondo quanto riportato in +tab.~\ref{tab:IOsched_class}. + +La classe di priorità più bassa è \const{IOPRIO\_CLASS\_IDLE}; i processi in +questa classe riescono ad accedere a disco soltanto quando nessun altro +processo richiede l'accesso. Occorre pertanto usarla con molta attenzione, +perché un processo in questa classe può venire completamente bloccato quando +ci sono altri processi in una qualunque delle altre due classi che stanno +accedendo al disco. Quando si usa questa classe non ha senso indicare un +valore di priorità, dato che in questo caso non esiste nessuna gerarchia e la +priorità è identica, la minima possibile, per tutti i processi. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Classe} & \textbf{Significato} \\ + \hline + \hline + \const{IOPRIO\_CLASS\_RT} & Scheduling di I/O \textit{real time}.\\ + \const{IOPRIO\_CLASS\_BE} & Scheduling di I/O ordinario.\\ + \const{IOPRIO\_CLASS\_IDLE}& Scheduling di I/O di priorità minima.\\ + \hline + \end{tabular} + \caption{Costanti che identificano le classi di scheduling di I/O.} + \label{tab:IOsched_class} +\end{table} +La seconda classe di priorità di I/O è \const{IOPRIO\_CLASS\_BE} (il nome sta +per \textit{best-effort}) che è quella usata ordinariamente da tutti +processi. In questo caso esistono priorità diverse che consentono di +assegnazione di una maggiore banda passante nell'accesso a disco ad un +processo rispetto agli altri, con meccanismo simile a quello dei valori di +\textit{nice} in cui si evita che un processo a priorità più alta possa +bloccare indefinitamente quelli a priorità più bassa. In questo caso però le +diverse priorità sono soltanto otto, indicate da un valore numerico fra 0 e 7 +e come per \textit{nice} anche in questo caso un valore più basso indica una +priorità maggiore. + + +Infine la classe di priorità di I/O \textit{real-time} +\const{IOPRIO\_CLASS\_RT} ricalca le omonime priorità di processore: un +processo in questa classe ha sempre la precedenza nell'accesso a disco +rispetto a tutti i processi delle altre classi e di un processo nella stessa +classe ma con priorità inferiore, ed è pertanto in grado di bloccare +completamente tutti gli altri. Anche in questo caso ci sono 8 priorità diverse +con un valore numerico fra 0 e 7, con una priorità più elevata per valori più +bassi. + +In generale nel funzionamento ordinario la priorità di I/O di un processo +viene impostata in maniera automatica nella classe \const{IOPRIO\_CLASS\_BE} +con un valore ottenuto a partire dal corrispondente valore di \textit{nice} +tramite la formula: $\mathtt{\mathit{prio}}=(\mathtt{\mathit{nice}}+20)/5$. Un +utente ordinario può modificare con \func{ioprio\_set} soltanto le priorità +dei processi che gli appartengono,\footnote{per la modifica delle priorità di + altri processi occorrono privilegi amministrativi, ed in particolare la + capacità \const{CAP\_SYS\_NICE} (vedi sez.~\ref{sec:proc_capabilities}).} +cioè quelli il cui user-ID reale corrisponde all'user-ID reale o effettivo del +chiamante. Data la possibilità di ottenere un blocco totale dello stesso, solo +l'amministratore\footnote{o un processo con la capacità + \const{CAP\_SYS\_ADMIN} (vedi sez.~\ref{sec:proc_capabilities}).} può +impostare un processo ad una priorità di I/O nella classe +\const{IOPRIO\_CLASS\_RT} o \const{IOPRIO\_CLASS\_IDLE}. -%TODO trattare le priorità di I/O -% vedi man ioprio_set e Documentation/block/ioprio.txt %TODO trattare le funzionalità per il NUMA % vedi man numa e le pagine di manuale relative @@ -3202,7 +3386,8 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso % LocalWords: CONTINUED sources forking Spawned successfully executing exiting % LocalWords: next cat for COMMAND pts bash defunct TRAPPED DUMPED Killable PR % LocalWords: SIGKILL static RLIMIT preemption PREEMPT VOLUNTARY IDLE RTPRIO -% LocalWords: Completely Fair compat Uniform +% LocalWords: Completely Fair compat Uniform CFQ Queuing elevator dev cfq RT +% LocalWords: Documentation block syscall ioprio IPRIO CLASS class best effort %%% Local Variables: %%% mode: latex