Question

Je lisais le LKMPG ( Voir la section 4.1.4. Désenregistrement Un dispositif ) et il n'a pas été clair pour moi d'utiliser les fonctions de try_module_get / module_put. Quelques-uns des exemples LKMPG les utiliser, d'autres pas.

Pour ajouter à la confusion, try_module_get apparaît 282 fois dans 193 fichiers dans la source 2.6.24, mais en Linux Pilotes de périphériques (LDD3) et Essential Linux Device Drivers , ils apparaissent dans même pas un seul exemple de code .

Je pensais que peut-être qu'ils étaient liés à l'ancienne interface register_chrdev (remplacée en 2.6 par l'interface cdev), mais ils apparaissent seulement ensemble dans les mêmes fichiers 8 fois:

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

Alors, quand est-il approprié d'utiliser ces fonctions et sont-ils liés à l'utilisation d'une interface particulière ou un ensemble de circonstances?

Modifier

J'ai chargé l'exemple sched.c du LKMPG et essayé l'expérience suivante:

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

Cela me porte à croire que le noyau fait maintenant propre comptabilité et de l'obtient / met peut-être obsolète. Quelqu'un peut-il vérifier?

Était-ce utile?

La solution

Vous devriez avoir essentiellement jamais utiliser try_module_get (THIS_MODULE); à peu près toutes ces utilisations ne sont pas sûrs car si vous êtes déjà dans votre module, il est trop tard pour remonter le nombre de références - il y aura toujours une (petite) fenêtre où vous exécutez le code dans votre module, mais n'avez pas incrémentée la référence compter. Si quelqu'un supprime exactement le module dans cette fenêtre, alors vous êtes dans la mauvaise situation de l'exécution de code dans un module chargé.

L'exemple particulier que vous avez lié à LKMPG où le code ne try_module_get () dans la méthode open () serait traitée dans le noyau moderne en définissant le champ .owner dans file_operations struct:

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

fera le code VFS prendre une référence au module avant remettre en elle, ce qui élimine la fenêtre dangereuse - soit la try_module_get () réussira avant l'appel à .Open (), ou try_module_get () échouera et le VFS ne sera jamais appel dans le module. Dans les deux cas, nous courons jamais le code d'un module qui a déjà été déchargé.

Le seul bon moment pour utiliser try_module_get () est lorsque vous voulez prendre une référence sur un module différent avant d'appeler dans ou de l'utiliser d'une certaine façon (par exemple que le fichier code ouvert fait dans l'exemple je l'ai expliqué ci-dessus). Il y a un certain nombre d'utilisations de try_module_get (THIS_MODULE) dans la source du noyau, mais la plupart sinon tous sont des insectes latents qui doivent être nettoyés.

La raison pour laquelle vous n'êtes pas en mesure de décharger l'exemple sched est que votre

$ tail /proc/sched -f &

commande continue / proc / sched ouvert, et à cause de

        Our_Proc_File->owner = THIS_MODULE;

dans le code sched.c, ouverture / proc / incréments sched le compteur de référence du module sched, qui représente la référence 1 que vos émissions lsmod. D'un lait écrémé rapide du reste du code, je pense que si vous relâchez / proc / sched en tuant votre commande de queue, vous seriez en mesure de retirer le module sched.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top