2016-01-18 6 views
0

Selon l'article http://www.phoronix.com/scan.php?page=news_item&px=queue-spinlocks-linux-4.2, depuis la version 4.2, le noyau Linux aurait des verrous de file d'attente. Mais dans la version 4.4, je suis passé par la mise en œuvre de spin_lock et a constaté qu'ils mettent en œuvre le verrou de rotation comme celui-ci dans kernel/locking/spinlock.c:Comment Linux implémente le 'verrou de file d'attente'?

void __lockfunc __raw_##op##_lock(locktype##_t *lock)   \ 
{         \ 
    for (;;) {       \ 
     preempt_disable();     \ 
     if (likely(do_raw_##op##_trylock(lock)))  \ 
      break;      \ 
     preempt_enable();     \ 
           \ 
     if (!(lock)->break_lock)    \ 
      (lock)->break_lock = 1;    \ 
     while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\ 
      arch_##op##_relax(&lock->raw_lock);  \ 
    }        \ 
    (lock)->break_lock = 0;      \ 
}         \ 

Et il y a un cmpxchg dans do_raw_spin_trylock, donc en gros juste un spin-lock tatas .

Cependant, quand je creuser plus profond, je trouve do_raw_spin_lock volonté entre en fonction queued_spin_trylock et le type de variable lock se qspinlock. Alors, où est la file d'attente? Se cache-t-il quelque part ou n'attend que la mise en œuvre future?

Pour rechercher les identifiants dans le code source, voici l'outil: http://lxr.free-electrons.com/

Répondre

1

Le code que vous regardez est dans le cas de ce #else:

#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) 
/* 
* The __lock_function inlines are taken from 
* include/linux/spinlock_api_smp.h 
*/ 
#else 
... 

Par défaut, sur x86, CONFIG_GENERIC_LOCKBREAK n'est pas défini, donc le compilateur ne compilera pas ce code (c'est-à-dire dans la clause #else). Il y a beaucoup de chemins potentiels à travers le labyrinthe de verrouillage ifdef s. Le chemin exact suivi dépendra de votre architecture et des sélections personnalisées que vous avez faites dans votre .config.

+0

Je sais, mais dans une autre définition, '__raw_spin_lock' appelle' do_raw_spin_lock', c'est essentiellement le même comportement, n'est-ce pas? Je ne vois toujours pas où se trouve la file d'attente. – ch94

+0

Regardez 'do_raw_spin_lock' dans' include/linux/spinlock.h'. Cela appelle 'arch_spin_lock', dont une implémentation est dans' include/asm-generic/qspinlock.h' –

+0

OK, je l'ai eu. Je ne sais pas pourquoi LXR n'a pas considéré le 'do_raw_spin_lock' ici comme une définition, c'est pourquoi je l'ai manqué ... Merci beaucoup! – ch94