From c7a2374285bbca579d97c711f40b396f8f7d8c9e Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sat, 25 Jul 2009 20:22:10 +0000 Subject: [PATCH] Priorita' di I/O, ancora materiale. --- prochand.tex | 165 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 156 insertions(+), 9 deletions(-) diff --git a/prochand.tex b/prochand.tex index b879a1d..d649018 100644 --- a/prochand.tex +++ b/prochand.tex @@ -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 @@ -3006,14 +3006,160 @@ 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 corrisponenza ad uno scheduler diverso il loro +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}). +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. + + \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: + \begin{errlist} + \item[\errcode{ESRCH}] non esiste il processo indicato. + \item[\errcode{EINVAL}] i valori di \param{which} e \param{who} non sono + validi. + \end{errlist} } +\end{prototype} + +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 +processi di un \textit{process group} (tratteremo questo argomento in +sez.~\ref{sec:sess_proc_group}) o per 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} + +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}. + +\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 un priorità come + restituito da \func{ioprio\_get} ottiene 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 + 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} + -Lo scheduler CFQ prevede la presenza di tre diverse classi, e ricalcando i -concetti dello scheduler della CPU, %TODO trattare le priorità di I/O % vedi man ioprio_set e Documentation/block/ioprio.txt @@ -3231,9 +3377,10 @@ 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 %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: +% LocalWords: Documentation block syscall ioprio IPRIO CLASS -- 2.30.2