2009-11-16 20 views
16

Estaba leyendo el LKMPG (See Section 4.1.4. Unregistering A Device) y no me queda claro cuándo utilizar las funciones try_module_get/module_put. Algunos de los ejemplos de LKMPG los usan, otros no.Linux Kernel Modules: Cuándo usar try_module_get/module_put

Para aumentar la confusión, aparece try_module_get 282 veces en 193 archivos de la fuente 2.6.24, sin embargo, en Linux Device Drivers (LDD3) y Essential Linux Device Drivers, que aparece en ni un solo ejemplo de código.

pensé que tal vez estaban atadas a la edad register_chrdev interfaz (sustituida en 2,6 por la interfaz cdev), pero sólo aparecen juntos en los mismos archivos 8 veces:

find -type f -name *.c | xargs grep -l try_module_get | sort -u | xargs grep -l register_chrdev | sort -u | grep -c . 

Por eso, cuando es apropiado utilizar estas funciones y están ligadas al uso de una interfaz particular o conjunto de circunstancias?

Editar

he cargado el ejemplo sched.c del LKMPG y probamos el siguiente experimento:

[email protected]:~/kernel-source/lkmpg/2.6.24$ tail /proc/sched -f & 
Timer called 5041 times so far 
[1] 14594 

[email protected]:~$ lsmod | grep sched 
sched     2868 1 

[email protected]:~$ sudo rmmod sched 
ERROR: Module sched is in use 

Esto me lleva a creer que el núcleo ahora tiene su propia contabilidad y la obtiene/puts puede ser obsoleto. ¿Alguien puede verificar esto?

+0

hay una aparición de 'try_module_get' en el capítulo 14, en el inciso manipulation' cuenta de referencia '(página 367) –

+0

que significaba el libro LDD en mi comentario anterior –

Respuesta

15

En esencia, nunca debería tener que usar try_module_get (THIS_MODULE); Prácticamente todos estos usos son inseguros ya que si ya está en su módulo, es demasiado tarde para alcanzar el recuento de referencias: siempre habrá una ventana (pequeña) donde está ejecutando código en su módulo pero no ha incrementado la referencia. contar. Si alguien elimina el módulo exactamente en esa ventana, entonces está en la mala situación de ejecutar el código en un módulo descargado.

El ejemplo particular se enlazó en LKMPG donde el código no try_module_get() en el método open() serían gestionados por el núcleo moderno definiendo el campo .owner en file_operations struct:

struct file_operations fops = { 
     .owner = THIS_MODULE, 
     .open = device_open, 
     //... 
}; 

esta voluntad haga que el código VFS haga referencia al módulo antes de llamar al, lo que elimina la ventana insegura: el try_module_get() tendrá éxito antes de que falle la llamada a .open() o try_module_get() y el VFS nunca llamará al módulo. En cualquier caso, nunca ejecutamos código desde un módulo que ya ha sido descargado.

El único buen momento para usar try_module_get() es cuando se quiere tener una referencia en un módulo diferente antes de llamar a él o utilizarlo de alguna manera (por ejemplo, como el código de apertura de archivo hace en el ejemplo he explicado encima). Hay una serie de usos de try_module_get (THIS_MODULE) en la fuente del kernel, pero la mayoría, si no todos, son errores latentes que deberían limpiarse.

La razón por la que no fuera capaz de descargar el ejemplo sched es que su

$ tail /proc/sched -f & 

comando mantiene/proc/sched abierta, y debido a

 Our_Proc_File->owner = THIS_MODULE; 

en el código sched.c, opening/proc/sched incrementa el recuento de referencias del módulo sched, que representa la referencia 1 que muestra su lsmod.De una rápida revisión del resto del código, creo que si liberas/proc/sched matando tu comando tail, podrás eliminar el módulo sched.

+0

--- Bueno, como saben recientemente mientras se trabaja en el controlador de dispositivo Watchdog, hay una función llamada no-salida, lo que significa que una vez que se inicia este dispositivo, no puede detenerlo. Por esta razón, este módulo no se pudo descargar, por lo tanto, en la implementación open() del controlador de dispositivo, se usa un __module_get (THIS_MODULE), con el módulo de controlador de dispositivo, sabemos, cuando el recuento de referencia de un módulo no es cero , no puedes descargarlo En conclusión, tal vez este es el caso donde necesita usar module_get, module_put, etc. Gracias. –

+0

Un 'try_module_get' dentro de la función' init_module' es seguro, pero un 'module_put' coincidente tendría que hacerse en algún punto anterior a' cleanup_module'. – fche