Domanda

stavo leggendo il LKMPG ( Vedere Sezione 4.1.4. Annullamento della registrazione di un dispositivo ) e non era chiaro per me quando utilizzare le funzioni try_module_get / module_put. Alcuni dei LKMPG esempi li usano, altri no.

Per aumentare la confusione, try_module_get appare 282 volte in 193 file nella sorgente 2.6.24, ma in Linux device Drivers (LDD3) e essenziali Linux device Drivers , che appare in nemmeno un solo esempio di codice .

Ho pensato che forse erano legati alla vecchia interfaccia register_chrdev (sostituita nel 2.6 dall'interfaccia cdev), ma compaiono solo insieme negli stessi file 8 volte:

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

Così, quando è opportuno utilizzare queste funzioni e sono hanno legato all'uso di una particolare interfaccia o un insieme di circostanze?

Modifica

ho caricato l'esempio sched.c dal LKMPG e ha cercato il seguente esperimento:

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

Questo mi porta a credere che il kernel ora fa di essa la propria contabilità e la ottiene / put possono essere obsoleti. Chiunque può verificare questo?

È stato utile?

Soluzione

Si dovrebbe in sostanza, non hanno mai usare try_module_get (THIS_MODULE); praticamente tutti tali usi non sono sicure in quanto se si è già nel vostro modulo, è troppo tardi per urtare il conteggio di riferimento - ci sarà sempre un (piccolo) finestra in cui si sta eseguendo codice nel tuo modulo, ma non è stato incrementato il riferimento contare. Se qualcuno rimuove il modulo esattamente in quella finestra, allora sei nel brutta situazione di esecuzione di codice in un modulo senza carico.

L'esempio particolare si è collegato in LKMPG in cui il codice non try_module_get () nel metodo open () sarebbe stato gestito nel kernel moderno impostando il campo .owner in file_operations struct:

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

questo renderà il codice VFS prendere un riferimento al modulo prima mettere in esso, che elimina la finestra non sicuri - sia il try_module_get () riuscirà prima della chiamata a .open (), o la try_module_get () avrà esito negativo e il VFS non chiamerà mai nel modulo. In entrambi i casi, non abbiamo mai eseguire codice da un modulo che è già stato scaricato.

L'unico momento buono da utilizzare try_module_get () è quando si vuole prendere un punto di riferimento su una diverso modulo prima di chiamare in esso o di utilizzarlo in qualche modo (ad esempio, come il file di codice aperto lo fa in nell'esempio ho spiegato sopra). Ci sono un certo numero di utilizzi di try_module_get (THIS_MODULE) nei sorgenti del kernel, ma la maggior parte se non tutti sono bug latenti che devono essere puliti.

La ragione per cui non sono stati in grado di scaricare l'esempio sched è che il vostro

$ tail /proc/sched -f &

comando mantiene / proc / sched aperto, ed a causa di

        Our_Proc_File->owner = THIS_MODULE;

nel codice sched.c, apertura / proc / incrementi sched il conteggio dei riferimenti del modulo sched, che rappresenta il riferimento 1 che i vostri spettacoli lsmod. Da un rapido scremato del resto del codice, penso che se si rilascia / proc / sched uccidendo il tuo comando tail, si sarebbe in grado di rimuovere il modulo sched.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top