2011-10-15 14 views
6

Da quello che ho potuto capire:Linux spin_lock vs NT KeAcquireSpinLock

  • NT KeAcquireSpinLock equivale a spin_lock_bh: quella IRQL eleva a DISPATCH_LEVEL, le altre maschere le mezze interrupt fondo - funzionalmente lo stesso. Mentre la variante NT mantiene OldIrql, la variante di Linux non sembra memorizzare "wereInterruptsAlreadyMasked" ovunque. Questo significa che spin_unlock_bh li smaschera sempre?
  • NT KeAcquireInterruptSpinLock è come spin_lock_irqsave.

Qual è l'equivalente NT di spin_lock?

Se spin_unlock_bh smaschera sempre interrupt (in NT-parlare, scende sempre IRQL a < DISPATCH_LEVEL), significa spin_lock è simile a KeAcquireSpinLockAtDpcLevel?

+0

Come indicato: il blocco della finestra viene eseguito tramite il processo IRQL. Quindi se questo concetto non è presente su linux quindi seguendo la logica spin_lock non ha effettivamente un equivalente diretto dato che entrambi i sistemi operativi usano meccanismi leggermente diversi per ottenere la stessa cosa – LordDoskias

+0

IRQL è un'astrazione oltre a mascheramento di interrupt e Linux ovviamente ha quello Quello che mi chiedo è lo scenario per cui spin_lock è utile, e perché la gente di NT non ha supportato questo scenario? – Ilya

+0

Inoltre, ho rivisto la mia domanda seguendo alcune altre cose che ho capito: spin_lock_bg. – Ilya

risposta

2

Il raw spin_lock può essere utilizzato quando si sa che nessun interrupt o fondo-metà si contenderanno mai il blocco. Evitando il mascheramento dell'interrupt, si mantiene la latenza dell'interrupt verso il basso, evitando comunque il sovraccarico di un mutex per le sezioni critiche abbastanza corte da girare.

In pratica, sembrano essere principalmente utilizzati da elementi come i driver del filesystem, per bloccare le strutture interne della cache e altre cose in cui non è mai necessario bloccare su IO quando si tiene il blocco. Poiché i dorsi e le interruzioni del driver non toccano mai direttamente il driver FS, non è necessario mascherare gli interrupt.

Sospetto che l'equivalente di Windows sia un CRITICAL_SECTION o qualsiasi sia l'equivalente dell'API del kernel NT; tuttavia, a differenza di una sezione critica NT, gli spinlock di Linux non ricadono su un mutex quando vengono contesi; continuano a girare.

E, sì, spin_unlock_bh ripristina incondizionatamente le metà inferiori. Puoi tenere traccia di quando abilitare/disabilitare manualmente (dato che in genere dovresti rilasciare i blocchi nell'ordine opposto di acquisizione, di solito non è un problema), o semplicemente ricorrere a spin_lock_irqsave.

+0

chiama ancora preempt_disable. Stai dicendo che preempt_disable contrassegna solo un flag e non disabilita gli interrupt, in particolare gli interrupt di metà inferiore (DPC in NT-speak?) E gli interrupt di dispositivo? – Ilya

+0

Su NT, tutte le funzioni che "acquisiscono" uno spinlock aumentano l'IRQL a DISPATCH_LEVEL, cioè a) nessuna prelazione, e b) le DPC (routine della metà inferiore) non verranno eseguite. Questo disabilita gli interrupt di per sé, però? L'interrupt dell'orologio non dovrebbe continuare a colpire ma semplicemente non farebbe nulla perché l'IRQL è abbastanza alto? – Ilya

+0

Anche su Linux, posso vedere che local_bh_disable alla fine chiama solo qualcosa chiamato add_preempt_count, che è la stessa funzione chiamata da preempt_disable. Quindi, cosa differenzia local_bh_disable e preempt_disable? – Ilya

Problemi correlati