linux kernel - the - Módulos del kernel de Linux: cuándo usar try_module_get/module_put
write linux kernel (1)
Estaba leyendo el LKMPG ( consulte la Sección 4.1.4. Anulación del registro de un dispositivo ) y no tenía claro cuándo usar las funciones try_module_get / module_put
. Algunos de los ejemplos de LKMPG los usan, otros no.
Para aumentar la confusión, try_module_get
aparece 282 veces en 193 archivos en la fuente 2.6.24, pero en Linux Device Drivers (LDD3) y Essential Linux Device Drivers , no aparecen ni en un solo ejemplo de código.
Pensé que tal vez estaban vinculados a la antigua interfaz register_chrdev
(reemplazada en 2.6 por la interfaz cdev), pero solo aparecen juntas 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 .
Entonces, ¿cuándo es apropiado usar estas funciones y están relacionadas con el uso de una interfaz particular o un conjunto de circunstancias?
Editar
sched.c ejemplo sched.c de LKMPG y probé el siguiente experimento:
anon@anon:~/kernel-source/lkmpg/2.6.24$ tail /proc/sched -f &
Timer called 5041 times so far
[1] 14594
anon@anon:~$ lsmod | grep sched
sched 2868 1
anon@anon:~$ sudo rmmod sched
ERROR: Module sched is in use
Esto me lleva a creer que el kernel ahora tiene su propia contabilidad y que las entradas y salidas pueden estar obsoletas. ¿Alguien puede verificar esto?
Básicamente, nunca debería tener que usar try_module_get (THIS_MODULE); casi todos estos usos son inseguros ya que si ya está en su módulo, es demasiado tarde para aumentar el recuento de referencias; siempre habrá una ventana (pequeña) donde está ejecutando el 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 que vinculó en LKMPG donde el código hace try_module_get () en el método open () se manejaría en el kernel moderno al establecer el campo .owner en struct file_operations:
struct file_operations fops = {
.owner = THIS_MODULE,
.open = device_open,
//...
};
esto hará que el código VFS tome una referencia al módulo antes de llamar, lo que elimina la ventana insegura: o try_module_get () tendrá éxito antes de la llamada a .open (), o try_module_get () fallará y VFS nunca llamará al módulo. En cualquier caso, nunca ejecutamos código de un módulo que ya se ha descargado.
El único buen momento para usar try_module_get () es cuando desea tomar una referencia en un módulo diferente antes de llamarlo o usarlo de alguna manera (por ejemplo, como lo hace el código de archivo abierto en el ejemplo que expliqué anteriormente). 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 se deben limpiar.
La razón por la que no pudo descargar el ejemplo de programación es que su
$ tail /proc/sched -f &
el comando mantiene / proc / sched abierto, y debido a
Our_Proc_File->owner = THIS_MODULE;
en el código sched.c, apertura / proc / sched incrementa el recuento de referencia del módulo de programación, que representa la referencia 1 que muestra su lsmod. Desde un vistazo rápido al resto del código, creo que si libera / proc / sched eliminando el comando tail, podrá eliminar el módulo de programación.