Sie sind auf Seite 1von 7

Estudio de un S.O. // Estudio del Ncleo del S.O. Linux.

Ttul
JuanCarlos PerezCortes

Estudio de un S.O. // Estudio del Ncleo del S.O. Linux. Ttulo

Table of Contents
Tema 6. Servicios internos.................................................................................................................................1
6.1 Introduccin.......................................................................................................................................1
6.2 Ejecucin diferida de funciones.........................................................................................................1
6.3 Softirqs...............................................................................................................................................2
6.4 Estado de las interrupciones...............................................................................................................2
6.5 Inicializacin de las softirqs...............................................................................................................2
6.6 Activando una softirq.........................................................................................................................3
6.7 Ejecucin de las softirq pendientes: do_softirq.................................................................................3
6.8 El proceso ksoftirqd...........................................................................................................................4

Tema 6. Servicios internos


Introduccin. Softirqs.
Juan Carlos Prez y Sergio Sez
Juan Carlos Prez jcperez@disca.upv.es
Sergio Sez ssaez@disca.upv.es

6.1 Introduccin
En el manejo de interrupciones, la ejecucin de los manejadores de dispositivo se lleva a cabo de
forma serie, un manejador tras otro. Adems normalmente las interrupciones estn deshabilitadas en
todo este proceso, por lo que no se suelen recibir ms interrupciones en el procesador hasta que todos
los manejadores de dispositivo pendientes han terminado de ejecutarse.
En el manejo de interrupciones, en muchas ocasiones, los manejadores de dispositivo estn
compuestos por una parte urgente, y una parte no tan urgente. Esta ltima se puede retrasar o diferir
por un periodo de tiempo realtivamente largo.
As pues, para mejorar el tiempo de respuesta del resto del sistema, Linux incorpora un sistema de
ejecucin diferida de funciones denominada genricamente softirqs. Estas funciones diferidas se
ejcutan siempre con las interrupciones habilitadas.

6.2 Ejecucin diferida de funciones.


En este tema vamos a estudiar algunos servicios bsicos que permiten la ejecucin diferida de ciertas
acciones.
Softirqs Es el mecanismo bsico para ejecutar funciones diferidas. Permite la ejecucin simultanea
en varios procesadores de varias softirqs, incluso del mismo tipo.
Tasklets Es un mecanismo un poco ms evolucionado construido encima de las softirqs.Permite la
ejecucin simultanea de varias Tasklets, pero no del mismo tipo.
Bottomhalves Es un mecanismo obsoleto que utiliza los mecanismos anteriores para su
funcionamiento y que se mantiene por compatibilidad con el cdigo anterior. No se pueden ejecutar
concurrentemente.
Colas de tareas Es un mecanismo que se diseo para extender el mecanismo de las bottomhalves y
que se mantiene por compatibilidad.

Tema 6. Servicios internos

Estudio de un S.O. // Estudio del Ncleo del S.O. Linux. Ttulo

6.3 Softirqs
Las softirqs es la versin ms simple de la ejecucin de funciones difereidas y la que da soporte a las dems.
El nemro de softirqs que puede haber en el sistemas est limitado a 32, algunas de las cuales se reservan ya
en el proceso de arranque.
Las estructuras de datos que definen las softirqs son bastante sencillas:
softirq_vec[32][kernel/softirq.c#L45] (struct
softirq_action[include/linux/interrupt.h#L68]): un vector que contiene la informacin sobre las
32 posibles funciones diferidas como softirqs.
irq_stat[NR_CPUS][kernel/softirq.c#L20] (irq_cpustat_t[include/asmi386/hardirq.h#L8]): es
un vector que contiene el estado de las interrupciones en cada CPU. A sus campos no se
accede directamente, sino a travs de unas macros definidas en
include/linux/irq_cpustat.h#L28.

6.4 Estado de las interrupciones


El estado de las interrupciones en el vector
irq_stat[NR_CPUS][kernel/softirq.c#L20] (irq_cpustat_t[include/asmi386/hardirq.h#L8]) se accede con las
siguientes macros:
softirq_pending(cpu)[include/linux/irq_cpustat.h#L29]: se utiliza como un mapa de 32 bits que indica
que softirqs estn pendientes en dicha CPU.
local_irq_count(cpu)[include/linux/irq_cpustat.h#L30]: indica el nmero de interrupciones anidadas
en dicha CPU. Este campo ya lo vimos en el manejo de interrupciones, ya que era accedido por las
macros irq_enter[include/asmi386/hardirq.h#L34] y irq_exit[include/asmi386/hardirq.h#L35].
local_bh_count(cpu)[include/linux/irq_cpustat.h#L31]: indica cuantas veces se han deshabilitado las
softirqs. Aunque hace referencia a las bottomhalves (bh), se refiere a las softirqs en general.
ksoftirqd_task(cpu)[include/linux/irq_cpustat.h#L33]: es un puntero al proceso del ncleo encargado
de ejecutar las softirqs de la CPU correspondiente cuando hay demasiada carga para ejecutarlas en la
funcin do_softirq().

6.5 Inicializacin de las softirqs


Las softirqs se inicializan/instalan con la funcin open_softirq[kernel/softirq.c#L140], y no parece que
exista ninguna funcin que las desinstale. As pues, parece razonable que su uso sea exclusivamente
en tiempo de compilacin (Las softirqs no son aptas para su uso desde los mdulos cargados en
tiempo de ejecucin. En estos casos se pueden utilizar tasklets.).
Algunas softirqs estn predefinidas (su identificador) y algunas de stas adems tambin se instalan
en el proceso de arranque.
Las nicas 4 softirqs preestablecidas aparecen en la enumeracin definida en
include/linux/interrupt.h#L50.
En el proceso de arranque se instalan las funciones asociadas con las softirqs
6.3 Softirqs

Estudio de un S.O. // Estudio del Ncleo del S.O. Linux. Ttulo


HI_SOFTIRQ y TASKLET_SOFTIRQ, en la funcin
softirq_init()[kernel/softirq.c#L324][#3312].
La funcin open_softirq[kernel/softirq.c#L139] lo nico que hace es establecer los valores de los
campos data y action de la entrada correspondiente del vector
softirq_vec[][kernel/softirq.c#L45].

6.6 Activando una softirq


Para activar una softirq, es decir, para programar su ejecucin diferida, se utiliza la funcin
raise_softirq()[kernel/softirq.c#L131]. Cabe destacar que aunque las funciones que representan a
cada softirq se definen a nivel global, su activacin es independiente para cada CPU.
La funcin raise_softirq()[kernel/softirq.c#L131] activa la softirq solicitada, en el procesador en el
que se est ejecutando la funcin, invocando con las interrupciones deshabilitadas a la funcin
cpu_raise_softirq()[kernel/softirq.c#L111] con
smp_processor_id()[include/asmi386/smp.h#L107] como primer parmetro. Una softirq se ejecuta en
la CPU en la que se ha activado, quizs con la intencin de aprovechar, en la medida de lo posible,
los contenidos de la cache.
La funcin cpu_raise_softirq()[kernel/softirq.c#L111] utiliza la macro
__cpu_raise_softirq()[include/linux/interrupt.h#L77][#116] para poner a 1 el bit correspondiente del
campo softirq_pending(cpu) de la estructura irq_cpustat_t[include/asmi386/hardirq.h#L8] que
representa a la CPU actual. Posteriormente, si no estamos durante el manejo de una interrupcin o de
las bottomhalves o con las bottomhalves desactivadas, entonces despierta al proceso
ksoftirqd de esta CPU para que atienda las softirqs pendientes. De lo contrario stas se atendern
al final de las irq o BH.

6.7 Ejecucin de las softirq pendientes: do_softirq


La ejecucin de las softirqs se lleva a cabo o bien en la funcin do_softirq[kernel/softirq.c#L60].
La funcin do_softirq utiliza algunas funciones macros interesantes.
local_irq_save(flags)[include/asmi386/system.h#L321]: salva el estado de la CPU actual
(EFLAGS) en una variable y con ello tambin el flag IF que indica si las interrupciones estn o no
habilitadas en dicha CPU. Una vez salvados los flags, deshabilita las interrupciones.
local_irq_restore(flags)[include/asmi386/system.h#L322]: reestablece el estado de la CPU,
restableciendo a su vez el estado de las interrupciones.
local_irq_disable, local_irq_enable[include/asmi386/system.h#L323]: deshabilitan y
habilitan las interrupciones en la CPU actual respectivamente.
local_bh_disable, __local_bh_enable[include/asmi386/softirq.h#L13]: deshabilitan y habilitan
las softirqs en la CPU actual respectivamente, incrementando y decrementando el campo
local_bh_count(cpu)[include/linux/irq_cpustat.h#L31] (de la estructura
irq_cpustat_t[include/asmi386/hardirq.h#L8]) en la CPU actual. Ojo! La macro es
__local_bh_enable, porque la macro local_bh_enable[include/asmi386/softirq.h#L26], a parte de
decrementar el contador de local_bh_count(cpu), tambin comprueba si hay softirqs
pendientes, ejecutando la funcin do_softirq[kernel/softirq.c#L60] si fuera necesario.

La funcin do_softirq[kernel/softirq.c#L60] lleva a cabo las sigueintes acciones:


6.6 Activando una softirq

Estudio de un S.O. // Estudio del Ncleo del S.O. Linux. Ttulo


Obtiene un identificador de la CPU en la que se est ejecutando [#63] y posteriormente invoca a la
macro in_interrupt[include/asmi386/hardirq.h#L24] para ver si puede continuar [#63]. Si est dentro del
manejo de interrupciones o con las bottomhalves deshabilitadas en esta CPU retornar
inmediatamente. La macro in_interrupt[include/asmi386/hardirq.h#L24] comprueba que la suma de los
contadores local_bh_count(cpu)[include/linux/irq_cpustat.h#L31] y
local_irq_count(cpu)[include/linux/irq_cpustat.h#L30] en la CPU actual es distinto de cero.
Salva el estado de las interrupciones con la macro local_irq_save(flags)[#71].
Obtiene una copia local en la variable pending del mapa de bits con las softirqs pendientes en esta
CPU (softirq_pending(cpu)) [#71].
Si no hay softirqs pendientes en esta CPU [#75], sale de la funcin reestableciendo el estado que tiene
las interrupciones al entrar, utilizando para ello la macro local_irq_restore(flags)[#108].
Si hay interrupciones pendientes, almacena en mask una copia de las softirqs que no estn activas
[#78].
Pone a 0 el mapa de bits de con las softirqs pendientes en esta CPU (softirq_pending(cpu))
[#82].
Una vez llegado este punto, habilita las interrupciones con la macro local_irq_enable, puesto
que las softirqs queremos que puedan ser interrumpidas por cualquier manejador de interrupciones
[#84].
A continuacin se obtiene un puntero h al primer elemento del vector de softirqs
softirq_vec[#86] y se comienza un bucle que ejecutar todas aquellas softirqs que tenga a uno su
bit correspondiente en la variable pending[#8893].
Una vez ejecutadas todas las funciones asociadas a las softirqs se vuelven a inhibir las interrupciones
con la macro local_irq_disable[#95]. Ojo! Con las macros local_irq_enable y
local_irq_disable habilitamos y deshabilitamos las interrupciones, no como con
local_irq_restore que dejamos las interrupciones como estaban anteriormente.
Finalmente, se vuelve a obtener una copia de las softirqs pendientes [#97], ya que durante la ejecucin
de las softirqs se podran haber activado ms softirqs (las mismas u otras distintas).
Se comprueba si las nuevas softirqs activas son distintas de las que ya se han tratado en esta
invocacin de do_softirq[#98]. Para ello se utiliza la variable mask que mantiene un mapa de bits
con las softirqs que no se han ejecutado en la invocacin actual.
Si durante la ejecucin de las softirqs se ha activado alguna softirqs que todava no se haba
ejecutado, se elimina dicha softirqs del mapa de bits que hay en mask y se repite el proceso saltando
a la etiqueta restart.
Si durante la ejecucin de las softirqs slo se han activado softirqs que YA se haban ejecutado, stas
se dejarn pendientes para que las ejecute el proceso del ncleo ksoftirqd perteneciente a esta
CPU. Dicho proceso se despierta con la funcin wakeup_softirqd[kernel/softirq.c#L53].

6.8 El proceso ksoftirqd


El proceso ksoftirqd[kernel/softirq.c#L361] es el encargado de ejecutar las softirqs que han quedado pendientes
por exceso de carga en la funcin do_softirq.
En la inicializacin del proceso ste realiza lo siguiente:
Invoca a la funcin daemonize() que todos los posibles recursos asociados a la memoria y a los
ficheros, que no son necesarios para un proceso del ncleo [#367].
6.8 El proceso ksoftirqd

Estudio de un S.O. // Estudio del Ncleo del S.O. Linux. Ttulo


Posteriormente, se baja la prioridad a casi el mnimo [#368] y bloquea todas las seales [#369].
Establece en que CPU se quiere ejecutar e invoca al planificador hasta que este proceso se este
ejecutando en la CPU seleccionada [#3724].
Finalmente, se cambia el nombre del proceso, se cambia a estado bloqueado y apunta su identificador
en el campo ksoftirqd_task(cpu) para su posterior identificacin.

6.8 El proceso ksoftirqd

Das könnte Ihnen auch gefallen