You are on page 1of 10

Planificador del kernel Linux.

Gabriel Nez Nez-Lagos - Juan Antonio Rodrguez Vela

1 Introduccin.
Linux es un ncleo (kernel) de sistema operativo. Habitualmente se distribuye junto con una serie de aplicaciones desarrolladas por el proyecto GNU para formar un sistema operativo completo llamado GNU/Linux. Es software libre, lo que quiere decir, fundamentalmente, que se puede leer o modificar el cdigo, distribuir (original o modificado), copiar y utilizar libremente. No se permite plagiarlo, ni distribuirlo sin dar acceso al cdigo fuente, ni cambiarle la licencia. Linux debe su nombre a su desarrollador original, Linus Torvalds, que era estudiante de Informtica en una universidad de Helsinki (Finlandia) cuando en 1991 se decidi a hacer un ncleo de sistema operativo que funcionara como MINIX (un derivado de UNIX). Es muy compatible con UNIX, pero no es un UNIX en el sentido de que por dentro funciona como han querido Linus y los cientos de desarrolladores que trabajan en l por Internet desde su creacin. Desde hace unos meses se encuentra en su versin 2.6 (la 2.6.5 era la ltima el 20 de Abril de 2004). La versin de produccin anterior, la 2.4 (2.4.26 era la ltima el 23 de Abril de 2004), se sigue utilizando mucho. Las versiones con segunda cifra por la izquierda impar son de desarrollo. El planificador (scheduler) es la parte del sistema operativo que permite la multiprogramacin y el multiproceso mediante la asignacin de procesos a las CPUs del sistema y el intercambio de procesos en ejecucin. Ha cambiado completamente de una versin a otra, se mantienen las principales estructuras de datos, pero se ha cambiado el algoritmo para hacerlo O(1) y con ello, ms escalable1. La versin ms documentada es la 2.4, as que hablaremos fundamentalmente de ella.

2 Caractersticas generales.
y

Linux es un kernel monoltico, como la mayora de *NIX. Eso quiere decir que el ncleo hace todo (proporciona todos los servicios del sistema operativo) y todas las capas del ncleo tienen acceso a todas las estructuras de datos, rutinas y componentes del sistema.

y y y

Es capaz de linkar mdulos en tiempo de ejecucin. Los mdulos contienen funcionalidades particulares que son cargadas dentro del Kernel cada vez que se requiere y no estn permanentemente alojados dentro del Kernel en s, ni dentro de la memoria. Adems de la reduccin en el uso de memoria, los mdulos tienen la ventaja de ser actualizables. Al compilar el ncleo se da con cada mdulo la opcin de incorporarlo estticamente al binario del kernel o bien compilarlo aparte para que luego se pueda cargar segn demanda. No est diseado a partir de hilos de ncleo. El kernel no est implementado como un conjunto de hilos, al contrario que otros *NIX modernos. Aunque realmente los admite: utiliza unos pocos para realizar tareas repetitivas2 y no tienen permitido ejecutar programas de usuario. Tiene un diseo reentrante de modo que pueden existir varios procesos en modo ncleo 'ejecutndose' a la vez (en monoprocesadores, todos menos uno estaran en la cola de listos). Tiene soporte para aplicaciones de usuario multihilo. Antes del kernel 2.0 los hilos en aplicaciones de ususario se gestionaban desde libreras en modo usuario. Compatible con estndares: POSIX, las APIs del UNIX SysV y los sockets BSD, sistemas de archivos para todos los gustos, ... Admite multiproceso simtrico (SMP). No expropiativo (Non-preemptiveness). Quiere decir que un proceso en modo ncleo no puede ser arbitrariamente interrumpido. Realmente slo tiene inters3 en monoprocesadores, porque si tenemos ms de una CPU, un nuevo proceso en modo ncleo podr ejecutarse, en principio, en una CPU que est libre sin estorbar a los procesos en modo ncleo que se estn ejecutando en otras CPUs. Era una caracterstica del ncleo 2.4 que ha cambiado en el 2.6: en este ltimo el kernel puede interrumpirse a s mismo para atender a ciertas interrupciones.

3 Gestin de procesos en linux.


En todo sistema operativo un proceso est representado por una estructura de datos donde se guarda toda la informacin relevante de ste, el PCB (Process Control Block), bloque de control del proceso o descriptor del proceso.En Linux, el PCB es la estructura struct task_struct. En esta estructura aparece todo tipo de informacin sobre un proceso.Cada proceso del sistema tiene una estructura del tipo struct task_struct asociada. Dicha estructura forma parte de una estructura del tipo union task_union que contiene el PCB (struct task_struct) y la pila del ncleo de dicho proceso (para cuando el proceso se ejecuta en modo ncleo). Esta estructura, en la que la pila y el PCB comparten la memoria ocupa

8KB.Con esta estructura, el ncleo es capaz de determinar el puntero al PCB de un proceso a partir de su puntero de la pila de ncleo (se hace con la macro current que ejecuta tres instrucciones de ensamblador).
union task_union struct task_struct task; unsignedlong stack[INIT_TASK_SIZE/sizeof(long)];

El conjunto de procesos en el sistema Linux est representado como una coleccin de estructuras struct task_struct, las cuales estn enlazadas de dos formas principalmente: Como una tabla hash, ordenados por el pid y como una lista circular doblemente enlazada usando los punteros p-next_task y pprev_task. y y

La tabla hash es usada para encontrar rpidamente una tarea por su pid usando find_task_pid(). La lista circular doblemente enlazada que usa p-next_task/ prev_task es mantenida para poder ir fcilmente a travs de todas las tareas del sistema.

static inline struct task_struct *find_task_by_pid(int pid)

struct task_struct *p, **htable = pidhash[pid_hashfn(pid)]; /* Se recorren los elementos cuyo valor dado por la funcin hash es el mismo. Son las llamadas colisiones */ for(p = *htable; p p-pid != pid; p = p-pidhash_next); return p;

En caso de colisin en la tabla hash, se usa encadenamiento. Las tareas en cada lista ordenada (esto es, ordenadas por el mismo valor dado por la funcin hash) son enlazadas por p->pidhash_next/pidhash_pprev el cual es usado por hash_pid() y unhash_pid() para insertar y quitar un proceso dado en la tabla hash. Esto es realizado bajo la proteccin de un spinlock 4 read/write ya que un acceso no controlado a la tabla hash podra traer consecuencias desatrosas.Ntese que el uso de semforos no sera suficiente para proporcionar proteccin en caso de mltiples cpus.

3.1 Anlisis del descriptor de proceso (struct task_struct)


El principal tipo de dato que se utiliza para gestionar los procesos en el ncleo es task_struct, el descriptor de proceso. Una instancia de este tipo de dato puede

ocupar normalmente hasta cerca de 1000 bytes. Est muy bien aprovechada: todas las estructuras y tablas que trabajan con procesos estn implementadas de tal forma que una misma de estas task_struct puede formar parte de muchas tablas o listas a la vez. EL truco? Lo que solemos usar como nodo en una lista enlazada (los punteros anterior y siguiente), por ejemplo, no es ms que una subestructura incrustada dentro del descriptor del proceso, as es: un puntero al anterior y al siguiente estn incrustados dentro de nuestra task_struct. Muchas partes del S.O. hacen uso de esta estructura de datos, por lo que es necesario conocer los campos ms importantes de task_struct. Algunos de estos campos son:
y volatile long state:

contiene el estado del proceso. Que la variable est declarada como volatile le indica al compilador que su valor puede cambiarse de forma asncrona (Por ejemplo desde una rutina de tratamiento de interrupcin).
volatile long state;/*-1 no ejecutable, 0 ejecutable, 0 parado*/ volatile long state; /* -1 no ejecutable, 0 ejecutable, 0 parado */ #define TASK_RUNNING 0 /* Listo, ejecucin */ #define TASK_INTERRUPTIBLE 1 /* Dormido (bloqueado). Admite seales */ #define TASK_UNINTERRUPTIBLE 2 /* Bloqueado pero slo responde a la seal o interrupcin que espera. */ #define TASK_ZOMBIE 4 /* Esperando un wait() */ #define TASK_STOPPED 8 /* SIGSTOP, SIGTSMP, SIGTTIN, SIGTTOU. Depuracin*/ #define TASK_EXCLUSIVE 32

un valor distinto de cero (tpicamente 1) indica si el proceso tiene seales pendientes. Se reacciona a estas seales al volver de una llamada al sistema, o de un bloqueo o suspensin. mm_segment_taddr_limit: indica el tamao mximo del espacio de direcciones de dicho proceso. El valor tpico es de 3GB para procesos de usuario y 4GB para los hilos de ejecucin del ncleo. volatile long need_resched: con su valor a 1 indica que este proceso, posiblemente, debe abandonar la CPU y por lo tanto se deber invocar al planificador en el momento adecuado (en vez de llamar a schedule() directamente).

int sigpending:

Otros campos que contienen informacin general del proceso son:

int exit_code, exit_signal:

contiene el valor de terminacin de un proceso, en caso de que haya finalizado mediante la llamada al sistema exit(2). Si termina por una seal, contendr el nmero de seal que lo mat.
struct task_struct*p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr:

y y y y y

Punteros para acceder a toda la familia de procesos: op(Original Parent),p(Parent),c(Youngest Child),ys (Younger Sibling, tu hermano inmediatamente ms joven), os (Older Sibling, hermano directamente ms viejo). long start_time: Indica el instante de creacin de este proceso. uid_tuid, euid, suid, fsuid; Usuario propietario de este proceso, tanto real (uid), como efectivo (euid), y atributos ms especficos. gid_tgid, egid, sgid, fsgid: Grupo propietario de este proceso, tanto real (gid), como efectivo (egid), y atributos ms especficos. unsigned long blocked: Contiene un mapa de bits con las seales que estn temporalmente bloqueadas. struct sigpending pending: Contiene la informacin sobre las seales que este proceso tiene pendientes.

Aunque la mayor parte del estado de un proceso se ha salvado en la pila del ncleo con la macro SAVE_ALL, existen algunos registros adicionales que se almacenan en la estructura task_struct y que son utilizados sobre todo en el cambio de contexto. El campo que contiene esta informacin es struct Algunos de sus campos son:
y y y unsigned long esp0; thread_struct thread.

Puntero de pila del ncleo. unsigned long eip, esp, fs, gs; Puntero de instruccin y de pila del proceso y otros registros de segmento del i386. unsigned long debugreg [ 8 ] ; Registros de depuracin.

4 Descripcin del algoritmo de planificacin de procesos.


Los tipos de algoritmos de planificacin usados en este ncleo estn definidos en las extensiones de tiempo real del estndar POSIX (POSIX.1b, antes llamado POSIX.4). El algoritmo de planificacin es bastante parecido a un Round Robin con prioridades. Puede haber a la vez en el sistema procesos con distinta poltica de planificacin establecida. En realidad cada proceso se puede planificar de

varias maneras, las polticas de planificacin de un proceso se pueden cambiar en tiempo de ejecucin y son:
y

: Es la planificacin clsica de UNIX. No es aplicable a tiempo real. Examina las prioridades dinmicas (calculadas como combinacin de las especificadas por el usuario y las calculadas por el sistema). Los procesos que llevan ms tiempo en el sistema van perdiendo prioridad. SCHED_FIFO : El sistema FIFO o FCFS (First to Come is First Served). Los procesos esperan en cola y se ejecutan secuencialmente. Se sigue calculando un cuanto de tiempo para el proceso, aunque normalmente no se use porque con esta planificacin no se fuerza al proceso a abandonar la CPU. Se usa en procesos de tiempo real. SCHED_RR : Round Robin o turno rotatorio. Funciona como el FIFO pero ahora cuando un proceso acaba su cuanto de tiempo (time slice) se le desaloja. El siguiente proceso se escoge de la lista de procesos con SCHED_RR o de la lista SCHED_FIFO. Son procesos en tiempo real. SCHED_YIELD : No es una poltica de planificacin, sino un modificador que afecta a las tres polticas anteriores. El proceso cede la CPU a cualquier otro que est listo. Se activa con una llamada al sistema (sched_yield()) slo para el siguiente ciclo de planificacin.
SCHED_OTHER

4.1 El algoritmo del kernel 2.4.


La prioridad de un proceso se calcula sumando. Por una parte se usa una funcin goodness que mide lo deseable (entre -1000, nada deseable y +1000, tiempo real, ejecutar ya) de ejecutar un proceso evaluando la prioridad. Si el proceso no es de tiempo real, se parte del tiempo restante de CPU (prioridad dinmica guardada en counter) de forma que tienen ms prioridad aquellos a los que les quede ms tiempo de CPU, se aumenta ligeramente la prioridad de los hilos del mismo proceso, se favorece a los procesos que se hayan estado ejecutando en la misma CPU (si se usa SMP) y se aade el valor de nice que especific el usuario. Si no, los procesos en tiempo real tienen un campo extra de prioridad que se suma a 1000 para el clculo de goodness. Por otra parte, existe una funcin sys_nice o sys_setpriority que se usa para aumentar la prioridad esttica del proceso. La prioridad esttica se guarda en un campopriority del descriptor de proceso y se usa para inicializar el valor de nice adems de marcar el valor inicial del cuanto de tiempo. La funcin schedule realiza el ciclo de planificacin. Se la puede llamar explcitamente o la puede llamar el sistema operativo: a la vuelta de una llamada

al sistema, despus de poner el proceso actual en la cola de espera o por temporizador. En primer lugar se definen los punteros a la tabla de procesos prev y next, que apuntarn al proceso que estaba en ejecucin y al proceso que se va a pasar a ejecutar, luego si la poltica del proceso ya ejecutado es RR se comprueba su cuanto de tiempo y si ha acabado,el proceso es enviado al final de la cola de listos. Si el proceso actual no est en TASK_RUNNING se quita de la cola de preparados,y si est en estado TASK_INTERRUPTIBLE se le enia una seal si hay que despertarlo, en caso contrario se eleimina de la cola. Ms tarde se elimina la marca que indica la necesidad de planificacin. Existe una nica cola de procesos que empieza en INIT, y que se va recorriendo en busca del mayor valor devuelto por goodness. Si no encuentra ningn proceso con cuanto por ejecutar se restablece el cuanto de cada de las tareas. Se divide por dos el tiempo de CPU (valor de counter que marca el tiempo restante) y se le suma la prioridad esttica para obtener el nuevo valor del contador. Lo normal es que el valor del contador anterior sea 0 por lo tanto estariamos inicializando el contador a la prioridad esttica. Podra no ser 0 si se hubiera llamado a goodness() con el bit SCHED_YIELD activo. Estos clculos se hacen con la funcin recalculate que en este kernel resultaba poco eficiente.

4.2 Diferencias en el kernel 2.6.


El nuevo planificador ejecuta un hilo de ncleo en cada CPU. Este hilo se encarga de planificar los procesos de la cola de ejecucin de la CPU en la que se ejecuta. Se llama a este hilo por temporizador, por llamada del sistema o cuando se ha acabado la cola de ejecucin para equilibrar la carga con otras CPUs. Adems, se lleva la cuenta del comportamiento del proceso, si se dedica a entrada/salida o tiene carga de CPU, pudiendo cambiar dinmicamente la poltica de planificacin y la prioridad del proceso. Tal como indicaba Ingo Molnar cuando anunci el nuevo planificador en enero de 2002 (kernel 2.5.2-pre6) se pretenda mantener las cosas buenas del planificador antiguo y aadir 'algunas pocas':
y

O(1): Se eliminan unos bucles que recalculaban datos para las rutinas wakeup(), schedule() y la interrupcin por tiempo. Ahora se hacen con algoritmos que tardan un tiempo constante, independientemente de las circunstancias que rodean la ejecucin. Escalabilidad con multiproceso simtrico. Dos procesos en dos CPUs distintas se ejecutan de forma totalemente independiente. Antes se usaba

y y y

una sola cola para todos y un semforo runqueue_lock para todos los procesos de todas las CPUs. Mayor afinidad por el procesador. Un proceso tiende a ejecutarse en el mismo procesador despus de un bloqueo o suspensin. No se le cambia de procesador sin motivo. Los intervalos de tiempo se distribuyen en cada CPU por separado. Planificacin por lotes. Se ha aadido SCHED_BATCH a los posibles valores de la poltica de planificacin. Los procesos por lotes utilizan la CPU cuando no hay otros procesos listos: tienen menos prioridad que cualquier otro proceso pero sus cuantos de tiempo son mucho mayores. Capacidad para manejar grandes cargas sin colapsar la planificacin. Para la planificacin en tiempo real (RT) , que usaba cola FIFO, el algoritmo tambin es O(1). Ejecutar los hijos antes que el proceso padre. Mejora la eficiencia.

5 Apndice: Hilos y procesos.


Linux usa la misma estructura de datos (task_struct) para representar un proceso y para representar un hilo. Esto supone una ventaja importante para la planificacin: se planifica cada hilo como si fuera un proceso. A veces a esto se le llama proceso ligero (LWP- Light Weight Process). La peculiaridad es que esta estructura tiene unos campos que son punteros al espacio de direcciones de un proceso. En qu se diferencia un proceso hijo de un hilo? Al crear un proceso hijo lo que se hace es copiar la memoria del padre en otra direccin y hacer que estos punteros sealen a la nueva; al crear un hilo lo que se hace es copiar los punteros, de forma que todos los hilos de un mismo proceso comparten exactamente el mismo espacio de direcciones. La sincronizacin y exclusin mutua del acceso concurrente de los hilos a la memoria del proceso es responsabilidad del programador que los usa ;-) .

6 Apndice2: Spinlocks.
Desde los primeros das del soporte Linux los desarrolladores se encararon con el clsico problema de acceder a datos compartidos entre los diferentes tipos de contexto (procesos de usuario vs interrupciones) y diferentes instancias del mismo contexto para mltiples cpus.

Si la regin crtica del cdigo puede ser ejecutada por el contexto de los procesos y el contexto de las interrupciones, entonces la forma de protegerlo usando las instrucciones cli/sti en UP es:
save_flags(flags); cli(); /* cdigo crtico */ restore_flags(flags);

Mientras que esto est bien en UP, obviamente no lo est usndolo en SMP porque la misma secuencia de cdigo quizs sea ejecutada simultneamente en otra cpu, y mientras cli() suministra proteccin contra las carreras con el contexto de interrupciones en cada CPU individualmente, no suministra proteccin contra todas las carreras entre los contextos funcionando en diferentes CPUs. Ocurrira lo mismo si usasemos semforos Es aqu donde los spinlocks son tiles. Ejemplo de uso:
spin_lock(lock); /* seccin crtica */ spin_unlock(lock);

7 Bibliografa
y y y y y y y y y y y y

http://ftp.kernel.org/pub/linux/kernel/people/davej/misc/post-halloween2.6.txt http://www.hpl.hp.com/research/linux/kernel/o1.php http://www.escomposlinux.org/wwol26/wwol26.html http://nulies.hispalinux.es/ http://safari.iki.fi/O%281%29-scheduler.txt http://es.tldp.org/Manuales-LuCAS/DENTRO-NUCLEO-LINUX/dentronucleo-linux-html/dentro-nucleo-linux.html#toc2 http://www.kernelnewbies.org Understanding The Linux Kernel. Daniel P. Bovet, Marco Cesati. 2 Edicin. Sebastopol, Clifornia Ed. O'Really 2003. http://sopa.dis.ulpgc.es/iidso/leclinux/procesos/planificador/LEC6_CHEDULER.pdf http://www.arstechnica.com/etc/linux/index.html http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.5.tar.bz2 http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.26.tar.bz2

8 Condiciones de copia y distribucin.

Copyright 2004 Juan Antonio Rodrguez Vela, Gabriel Nez Nez-Lagos (gabriel.nnl@estudiante.uam.es).

Este documento es software libre. Se puede copiar, distribuir usar y modificar segn los trminos de la Licencia Pblica General de GNU (GPL- GNU General Public License). Tiene una copia de esta licencia en http://www.gnu.org/licenses/gpl.txt Se considerar como cdigo fuente el cdigo HTML.

Sobre este documento...


Copyright (C) 2004 Juan Antonio Rodriguez & Gabriel Nunez charla-kernelv1-0-html.html :: descargado de la seccin de documentacin de la Asociacin para el Fomento del Software Libre: http://afsl.adi.uam.es
Notas al pie

... escalable1 La habilidad de manejar con eficiencia distintas cantidades de recursos y CPUs, desde pequeos procesadores empotrados hasta sistemas multiprocesador se conoce como escalabilidad. ... repetitivas2 Esos hilos son: proceso0, proceso1, keventd, kapm, kswapd, kflush (bdflush), kupdated, ksoftirqd. En el 2.6 hay adems un hilo en cada CPU que se encarga de balancear la carga entre procesadores. ... inters3 El inters recaa en que se facilitaba el diseo del kernel si se consideraba que las estructuras de datos no podan ser modificadas por otros procesos durante la ejecucin de un proceso en modo ncleo. ...spinlock 4 Los spinlocks son una de las formas de controlar la concurrencia en el kernel. Hablaremos de ellos en el apndice segundo.

You might also like