2012-07-22 2 views
0

J'ai lu cela depuis un certain temps mais cela n'a pas de sens pour moi .. Probablement parce que je suis nouveau dans tout cela et que je ne comprends toujours pas quelques concepts de noyau.Pourquoi spinlock no-op dans le noyau Linux (non-SMP)?

C'était ce que je suis venu avec (pas d'erreur ou de la remise NULL, il est juste pour le plaisir de la question):

spinlocks noyau sont exécutées à l'intérieur des fils du noyau, ce qui est préemptif.

void spinlock_acquire(spinlock_t *spinlock) 
{ 
    tryagain: 
    while(spinlock->plock != UNLOCKED) ; 
    context_switch_block; 
    if(spinlock->plock != UNLOCKED) { 
     context_switch_unblock; 
     goto tryagain; 
    } 
    spinlock_lock(spinlock, current_thread); 
    context_switch_unblock; 
} 
+0

Je ne comprends pas la question. Ou au moins, je ne comprends pas comment le code que vous avez inclus est lié à la question. – sblom

+0

spinlock sur un seul CPU, quel est le problème dans le code? J'ai lu que sous Linux sur CPU unique, le code spinlock est plutôt équivalent à aucun op, mais pourquoi? – sgupta

+0

Totalement ne pas comprendre votre code .... – Ace

Répondre

7

Avant Linux est un noyau préemptif, spinlocks sur UP étaient essentiellement pas d'habitation. Une fois que le noyau a été rendu préemptif, un appel à preempt_disable() a été ajouté aux spinlocks.

Il en va plus ou moins comme ceci:

  • Vous voulez protéger contre une CPU en conflit, utiliser une sorte de spinlock.
  • Vous voulez protéger contre un conflit, tasklet, ... utilisez spin_lock_bh, qui désactive les softirqs, tasklets, etc ... (bh est pour le nom historique, il vient de "moitié inférieure").
  • Vous souhaitez protéger contre une interruption matérielle en conflit, utilisez spin_lock_irq*, qui désactive les interruptions matérielles.
  • Tous les spinlocks protègent contre la préemption. Sur un noyau UP, les spinlocks ne prennent pas un véritable spinlock (puisqu'il n'y a pas de CPU en conflit, et nous ne pouvons pas être préemptés, et il existe des variantes de spinlock pour traiter les hardirqs, les softirqs, ...).
  • Sur une machine UP avec un noyau SMP, les spinlocks peuvent être transformés en nops.
  • Même sur un noyau UP avec préemption désactivée, les spinlocks peuvent avoir du code pour le débogage de spinlock, s'il est activé.
+0

À peu près la réponse la plus satisfaisante, upvoted. Mais pourquoi les spinlocks sont utilisés uniquement pour protéger contre les processeurs en conflit? Ne devrait-il pas être utilisé dans n'importe quel endroit pour se protéger contre les risques multiples de filetage comme les mutex? La seule différence entre le mutex et le spinlock réside-t-elle dans le fait que le mutex bloque le fil jusqu'à la disponibilité et le spinlock jusqu'à la disponibilité? Sélectionne ceci comme réponse une fois que ceci est effacé. – sgupta

+0

Oui, c'est vrai. Je l'ai mal exprimé. C'est couvert par le point 4: tous les spinlocks protègent contre la préemption, en vertu de l'appel 'preempt_disable()'. Rappelez-vous que les seuls dangers que vous pouvez avoir sont d'autres processeurs, interruptions (NMI, hardirqs, softirqs, tasklets, ...), et d'autres threads du noyau qui préemptent votre propre code. Couvert par les quatre premiers points de balle. – ninjalj

+0

Merci pour votre temps cependant, pourriez-vous s'il vous plaît expliquer comment si le code d'exemple dans la question est faux? – sgupta

2

Le verrouillage de spin n'est pas nécessaire sur les systèmes non SMP. Comme un verrou d'essorage est désactivé, personne d'autre ne peut avoir le verrou à ce moment-là. Une fois le thread A interrompu, il n'est pas possible pour le thread B d'essayer d'acquérir le même verrou, car il n'y a rien qui puisse faire perdre le CPU à B. En tant que tel, tout le spin lock sur le non-SMP est , bien, rien (sauf si vous lui demandez de désactiver les interruptions).

Shachar

+1

Pourquoi spinlock désactiverait-il les interruptions? – sgupta

+1

@ user1075375: les spinlocks ordinaires ne désactivent pas les interruptions, 'spin_lock_irq *' désactivent les interruptions locales, elles doivent être utilisées lorsque vous avez un gestionnaire d'interruption en conflit, qui utiliserait un spinlock normal à son tour. – ninjalj

+0

@ user1075375: le verrou d'essorage doit être exécuté avec des interruptions désactivées sur le processeur local. Le verrou de rotation lui-même n'a pas à désactiver les interruptions lui-même, si celles-ci sont déjà désactivées. Il appartient donc au programme de s'assurer qu'aucun code ** ** ne peut être exécuté pour essayer d'acquérir le verrou pendant qu'il est maintenu. –