% 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
+ 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 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
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
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
+ 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
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 librerie del C per queste due funzioni occorrerà invocarle
-tramite la funzione \func{syscall} (come illustrato in
-sez.~\ref{sec:intro_syscall}). La prima delle due è \funcd{ioprio\_get}, che
-consente di leggere la priorità; il suo prototipo è:
-\begin{prototype}{linux/ioprio.h}
- {int ioprio\_get(int which, int who)}
- Legge la priorità di I/O.
+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{La funzione ritorna un valore positivo in caso di successo e $-1$
- in caso di errore, nel qual caso \var{errno} può assumere i valori:
+ \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{prototype}
+\end{functions}
-La funzione legge 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 analoghi argomenti di \func{getpriority} e \func{setpriority};
-in questo caso vengono però per \param{which} sono state definite delle
-costanti apposite, illustrate in tab.~\ref{tab:ioprio_args}. A seconda dei
-valori è così possibile leggere delle priorità per il singolo processo, per i
+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 per tutti o processi di un utente.
+sez.~\ref{sec:sess_proc_group}) o tutti o processi di un utente.
\begin{table}[htb]
\centering
\label{tab:ioprio_args}
\end{table}
-Gli stessi valori possono essere utilizzati anche quando si vuole eseguire
-l'impostazione di una priorità di I/O; in tal caso si deve usare la funzione
-\funcd{ioprio\_set}, il cui prototipo è:
-\begin{prototype}{linux/ioprio.h}
- {int ioprio\_set(int which, int who, int ioprio)}
-
- Imposta la priorità di I/O.
-
- \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
- errore, nel qual caso \var{errno} può assumere i valori:
- \begin{errlist}
- \item[\errcode{EPERM}] non si hanno i privilegi per eseguire
- l'impostazione.
- \end{errlist}
- oltre a \errcode{EINVAL} e \errcode{ESRCH} con lo stesso significato di
- \func{ioprio\_get}. }
-\end{prototype}
-
-
-La funzione in caso di successo restituisce un intero positivo che esprime il
-valore della priorità di I/O, questo è composto di due parti, una che esprime
-la cosiddetta \textsl{classe} di scheduling, l'altro che esprime la priorità
-all'interno della classe stessa. Le classi previste dallo scheduler CFQ sono
-tre, identificate da altrettanti costanti, riportate in
-tab.~\ref{tab:IOsched_class}.
-
-\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 tre classi ricalcano i concetti presenti anche nello scheduler della CPU;
-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 di priorità più alta che stanno accedendo al
-disco; in questa classe non esistono valori di priorità, tutti i processi
-hanno la stessa priorità, che è la minima possibile.
-
-La classe per le priorità ordinarie è \const{IOPRIO\_CLASS\_BE} (il nome sta
-per \textit{best-effort}) che è quella usata di default per tutti processi; in
-questo caso esistono delle priorità all'interno della classe che corrispondono
-all'assegnazione ad un processo di una maggiore banda passante nell'accesso a
-disco rispetto agli altri senza però che questo possa bloccare indefinitamente
-l'accesso agli altri; con un concetto simile a quello dei valori di
-\textit{nice} per le priorità di processore. In questo caso esistono però
-soltanto otto diverse priorità, indicate da un valore numerico fra 0 e
-7,\footnote{come per \textit{nice} anche in questo caso un valore più basso
- indica una priorità maggiore.} che sono assegnate ai singoli processi in
-maniera automatica a partire dal loro valore di \textit{nice}.\footnote{come
- riportato nella documentazione il valore della priorità viene calcolato con
- la formula: $\mathtt{prio}=(\mathtt{nice}+20)/5$.}
-
-Infine la classe di priorità \textit{real-time} \const{IOPRIO\_CLASS\_RT}
-ricalca le analoghe priorità di processore: un processo in questa classe ha
-sempre la precedenza nell'accesso a disco rispetto a tutti i processi di
-priorità inferiore, e pertanto è in grado di bloccare completamente 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 inferiori.
-
-Per manipolare il valori delle priorità di I/O sono state approntate delle
-opportune macro, in grado di estrarre i valori di priorità e la classe dai
-valori restituiti da \func{ioprio\_get} e di creare da questi un opportuno
-valore da passare a \func{ioprio\_set}, che si sono riportate in
-tab.~\ref{tab:IOsched_class_macro}.
+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
\hline
\hline
\macro{IOPRIO\_PRIO\_CLASS}\texttt{(\textit{value})}
- & dato il valore di un priorità come
- restituito da \func{ioprio\_get} ottiene il
+ & 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 un priorità come
- restituito da \func{ioprio\_get} ottiene il
+ & 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
\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
% 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 CFQ Queuing elevator dev cfq RT
+% LocalWords: Documentation block syscall ioprio IPRIO CLASS class best effort
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
-% LocalWords: Documentation block syscall ioprio IPRIO CLASS