1.. include:: ../disclaimer-ita.rst 2 3:Original: :ref:`Documentation/kernel-hacking/locking.rst <kernel_hacking_lock>` 4:Translator: Federico Vaga <federico.vaga@vaga.pv.it> 5 6.. _it_kernel_hacking_lock: 7 8========================================== 9L'inaffidabile guida alla sincronizzazione 10========================================== 11 12:Author: Rusty Russell 13 14Introduzione 15============ 16 17Benvenuto, alla notevole ed inaffidabile guida ai problemi di sincronizzazione 18(locking) nel kernel. Questo documento descrive il sistema di sincronizzazione 19nel kernel Linux 2.6. 20 21Dato il largo utilizzo del multi-threading e della prelazione nel kernel 22Linux, chiunque voglia dilettarsi col kernel deve conoscere i concetti 23fondamentali della concorrenza e della sincronizzazione nei sistemi 24multi-processore. 25 26Il problema con la concorrenza 27============================== 28 29(Saltatelo se sapete già cos'è una corsa critica). 30 31In un normale programma, potete incrementare un contatore nel seguente modo: 32 33:: 34 35 contatore++; 36 37Questo è quello che vi aspettereste che accada sempre: 38 39 40.. table:: Risultati attesi 41 42 +------------------------------------+------------------------------------+ 43 | Istanza 1 | Istanza 2 | 44 +====================================+====================================+ 45 | leggi contatore (5) | | 46 +------------------------------------+------------------------------------+ 47 | aggiungi 1 (6) | | 48 +------------------------------------+------------------------------------+ 49 | scrivi contatore (6) | | 50 +------------------------------------+------------------------------------+ 51 | | leggi contatore (6) | 52 +------------------------------------+------------------------------------+ 53 | | aggiungi 1 (7) | 54 +------------------------------------+------------------------------------+ 55 | | scrivi contatore (7) | 56 +------------------------------------+------------------------------------+ 57 58Questo è quello che potrebbe succedere in realtà: 59 60.. table:: Possibile risultato 61 62 +------------------------------------+------------------------------------+ 63 | Istanza 1 | Istanza 2 | 64 +====================================+====================================+ 65 | leggi contatore (5) | | 66 +------------------------------------+------------------------------------+ 67 | | leggi contatore (5) | 68 +------------------------------------+------------------------------------+ 69 | aggiungi 1 (6) | | 70 +------------------------------------+------------------------------------+ 71 | | aggiungi 1 (6) | 72 +------------------------------------+------------------------------------+ 73 | scrivi contatore (6) | | 74 +------------------------------------+------------------------------------+ 75 | | scrivi contatore (6) | 76 +------------------------------------+------------------------------------+ 77 78 79Corse critiche e sezioni critiche 80--------------------------------- 81 82Questa sovrapposizione, ovvero quando un risultato dipende dal tempo che 83intercorre fra processi diversi, è chiamata corsa critica. La porzione 84di codice che contiene questo problema è chiamata sezione critica. 85In particolar modo da quando Linux ha incominciato a girare su 86macchine multi-processore, le sezioni critiche sono diventate uno dei 87maggiori problemi di progettazione ed implementazione del kernel. 88 89La prelazione può sortire gli stessi effetti, anche se c'è una sola CPU: 90interrompendo un processo nella sua sezione critica otterremo comunque 91la stessa corsa critica. In questo caso, il thread che si avvicenda 92nell'esecuzione potrebbe eseguire anch'esso la sezione critica. 93 94La soluzione è quella di riconoscere quando avvengono questi accessi 95simultanei, ed utilizzare i *lock* per accertarsi che solo un'istanza 96per volta possa entrare nella sezione critica. Il kernel offre delle buone 97funzioni a questo scopo. E poi ci sono quelle meno buone, ma farò finta 98che non esistano. 99 100Sincronizzazione nel kernel Linux 101================================= 102 103Se posso darvi un suggerimento: non dormite mai con qualcuno più pazzo di 104voi. Ma se dovessi darvi un suggerimento sulla sincronizzazione: 105**mantenetela semplice**. 106 107Siate riluttanti nell'introduzione di nuovi *lock*. 108 109Abbastanza strano, quest'ultimo è l'esatto opposto del mio suggerimento 110su quando **avete** dormito con qualcuno più pazzo di voi. E dovreste 111pensare a prendervi un cane bello grande. 112 113I due principali tipi di *lock* nel kernel: spinlock e mutex 114------------------------------------------------------------ 115 116Ci sono due tipi principali di *lock* nel kernel. Il tipo fondamentale è lo 117spinlock (``include/asm/spinlock.h``), un semplice *lock* che può essere 118trattenuto solo da un processo: se non si può trattenere lo spinlock, allora 119rimane in attesa attiva (in inglese *spinning*) finché non ci riesce. 120Gli spinlock sono molto piccoli e rapidi, possono essere utilizzati ovunque. 121 122Il secondo tipo è il mutex (``include/linux/mutex.h``): è come uno spinlock, 123ma potreste bloccarvi trattenendolo. Se non potete trattenere un mutex 124il vostro processo si auto-sospenderà; verrà riattivato quando il mutex 125verrà rilasciato. Questo significa che il processore potrà occuparsi d'altro 126mentre il vostro processo è in attesa. Esistono molti casi in cui non potete 127permettervi di sospendere un processo (vedere 128:ref:`Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni? <it_sleeping-things>`) 129e quindi dovrete utilizzare gli spinlock. 130 131Nessuno di questi *lock* è ricorsivo: vedere 132:ref:`Stallo: semplice ed avanzato <it_deadlock>` 133 134I *lock* e i kernel per sistemi monoprocessore 135---------------------------------------------- 136 137Per i kernel compilati senza ``CONFIG_SMP`` e senza ``CONFIG_PREEMPT`` 138gli spinlock non esistono. Questa è un'ottima scelta di progettazione: 139quando nessun altro processo può essere eseguito in simultanea, allora 140non c'è la necessità di avere un *lock*. 141 142Se il kernel è compilato senza ``CONFIG_SMP`` ma con ``CONFIG_PREEMPT``, 143allora gli spinlock disabilitano la prelazione; questo è sufficiente a 144prevenire le corse critiche. Nella maggior parte dei casi, possiamo considerare 145la prelazione equivalente ad un sistema multi-processore senza preoccuparci 146di trattarla indipendentemente. 147 148Dovreste verificare sempre la sincronizzazione con le opzioni ``CONFIG_SMP`` e 149``CONFIG_PREEMPT`` abilitate, anche quando non avete un sistema 150multi-processore, questo vi permetterà di identificare alcuni problemi 151di sincronizzazione. 152 153Come vedremo di seguito, i mutex continuano ad esistere perché sono necessari 154per la sincronizzazione fra processi in contesto utente. 155 156Sincronizzazione in contesto utente 157----------------------------------- 158 159Se avete una struttura dati che verrà utilizzata solo dal contesto utente, 160allora, per proteggerla, potete utilizzare un semplice mutex 161(``include/linux/mutex.h``). Questo è il caso più semplice: inizializzate il 162mutex; invocate :c:func:`mutex_lock_interruptible()` per trattenerlo e 163:c:func:`mutex_unlock()` per rilasciarlo. C'è anche :c:func:`mutex_lock()` 164ma questa dovrebbe essere evitata perché non ritorna in caso di segnali. 165 166Per esempio: ``net/netfilter/nf_sockopt.c`` permette la registrazione 167di nuove chiamate per :c:func:`setsockopt()` e :c:func:`getsockopt()` 168usando la funzione :c:func:`nf_register_sockopt()`. La registrazione e 169la rimozione vengono eseguite solamente quando il modulo viene caricato 170o scaricato (e durante l'avvio del sistema, qui non abbiamo concorrenza), 171e la lista delle funzioni registrate viene consultata solamente quando 172:c:func:`setsockopt()` o :c:func:`getsockopt()` sono sconosciute al sistema. 173In questo caso ``nf_sockopt_mutex`` è perfetto allo scopo, in particolar modo 174visto che setsockopt e getsockopt potrebbero dormire. 175 176Sincronizzazione fra il contesto utente e i softirq 177--------------------------------------------------- 178 179Se un softirq condivide dati col contesto utente, avete due problemi. 180Primo, il contesto utente corrente potrebbe essere interroto da un softirq, 181e secondo, la sezione critica potrebbe essere eseguita da un altro 182processore. Questo è quando :c:func:`spin_lock_bh()` 183(``include/linux/spinlock.h``) viene utilizzato. Questo disabilita i softirq 184sul processore e trattiene il *lock*. Invece, :c:func:`spin_unlock_bh()` fa 185l'opposto. (Il suffisso '_bh' è un residuo storico che fa riferimento al 186"Bottom Halves", il vecchio nome delle interruzioni software. In un mondo 187perfetto questa funzione si chiamerebbe 'spin_lock_softirq()'). 188 189Da notare che in questo caso potete utilizzare anche :c:func:`spin_lock_irq()` 190o :c:func:`spin_lock_irqsave()`, queste fermano anche le interruzioni hardware: 191vedere :ref:`Contesto di interruzione hardware <it_hardirq-context>`. 192 193Questo funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock 194svaniscono e questa macro diventa semplicemente :c:func:`local_bh_disable()` 195(``include/linux/interrupt.h``), la quale impedisce ai softirq d'essere 196eseguiti. 197 198Sincronizzazione fra contesto utente e i tasklet 199------------------------------------------------ 200 201Questo caso è uguale al precedente, un tasklet viene eseguito da un softirq. 202 203Sincronizzazione fra contesto utente e i timer 204---------------------------------------------- 205 206Anche questo caso è uguale al precedente, un timer viene eseguito da un 207softirq. 208Dal punto di vista della sincronizzazione, tasklet e timer sono identici. 209 210Sincronizzazione fra tasklet e timer 211------------------------------------ 212 213Qualche volta un tasklet od un timer potrebbero condividere i dati con 214un altro tasklet o timer 215 216Lo stesso tasklet/timer 217~~~~~~~~~~~~~~~~~~~~~~~ 218 219Dato che un tasklet non viene mai eseguito contemporaneamente su due 220processori, non dovete preoccuparvi che sia rientrante (ovvero eseguito 221più volte in contemporanea), perfino su sistemi multi-processore. 222 223Differenti tasklet/timer 224~~~~~~~~~~~~~~~~~~~~~~~~ 225 226Se un altro tasklet/timer vuole condividere dati col vostro tasklet o timer, 227allora avrete bisogno entrambe di :c:func:`spin_lock()` e 228:c:func:`spin_unlock()`. Qui :c:func:`spin_lock_bh()` è inutile, siete già 229in un tasklet ed avete la garanzia che nessun altro verrà eseguito sullo 230stesso processore. 231 232Sincronizzazione fra softirq 233---------------------------- 234 235Spesso un softirq potrebbe condividere dati con se stesso o un tasklet/timer. 236 237Lo stesso softirq 238~~~~~~~~~~~~~~~~~ 239 240Lo stesso softirq può essere eseguito su un diverso processore: allo scopo 241di migliorare le prestazioni potete utilizzare dati riservati ad ogni 242processore (vedere :ref:`Dati per processore <it_per-cpu>`). Se siete arrivati 243fino a questo punto nell'uso dei softirq, probabilmente tenete alla scalabilità 244delle prestazioni abbastanza da giustificarne la complessità aggiuntiva. 245 246Dovete utilizzare :c:func:`spin_lock()` e :c:func:`spin_unlock()` per 247proteggere i dati condivisi. 248 249Diversi Softirqs 250~~~~~~~~~~~~~~~~ 251 252Dovete utilizzare :c:func:`spin_lock()` e :c:func:`spin_unlock()` per 253proteggere i dati condivisi, che siano timer, tasklet, diversi softirq o 254lo stesso o altri softirq: uno qualsiasi di essi potrebbe essere in esecuzione 255su un diverso processore. 256 257.. _`it_hardirq-context`: 258 259Contesto di interruzione hardware 260================================= 261 262Solitamente le interruzioni hardware comunicano con un tasklet o un softirq. 263Spesso questo si traduce nel mettere in coda qualcosa da fare che verrà 264preso in carico da un softirq. 265 266Sincronizzazione fra interruzioni hardware e softirq/tasklet 267------------------------------------------------------------ 268 269Se un gestore di interruzioni hardware condivide dati con un softirq, allora 270avrete due preoccupazioni. Primo, il softirq può essere interrotto da 271un'interruzione hardware, e secondo, la sezione critica potrebbe essere 272eseguita da un'interruzione hardware su un processore diverso. Questo è il caso 273dove :c:func:`spin_lock_irq()` viene utilizzato. Disabilita le interruzioni 274sul processore che l'esegue, poi trattiene il lock. :c:func:`spin_unlock_irq()` 275fa l'opposto. 276 277Il gestore d'interruzione hardware non usa :c:func:`spin_lock_irq()` perché 278i softirq non possono essere eseguiti quando il gestore d'interruzione hardware 279è in esecuzione: per questo si può usare :c:func:`spin_lock()`, che è un po' 280più veloce. L'unica eccezione è quando un altro gestore d'interruzioni 281hardware utilizza lo stesso *lock*: :c:func:`spin_lock_irq()` impedirà a questo 282secondo gestore di interrompere quello in esecuzione. 283 284Questo funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock 285svaniscono e questa macro diventa semplicemente :c:func:`local_irq_disable()` 286(``include/asm/smp.h``), la quale impedisce a softirq/tasklet/BH d'essere 287eseguiti. 288 289:c:func:`spin_lock_irqsave()` (``include/linux/spinlock.h``) è una variante che 290salva lo stato delle interruzioni in una variabile, questa verrà poi passata 291a :c:func:`spin_unlock_irqrestore()`. Questo significa che lo stesso codice 292potrà essere utilizzato in un'interruzione hardware (dove le interruzioni sono 293già disabilitate) e in un softirq (dove la disabilitazione delle interruzioni 294è richiesta). 295 296Da notare che i softirq (e quindi tasklet e timer) sono eseguiti al ritorno 297da un'interruzione hardware, quindi :c:func:`spin_lock_irq()` interrompe 298anche questi. Tenuto conto di questo si può dire che 299:c:func:`spin_lock_irqsave()` è la funzione di sincronizzazione più generica 300e potente. 301 302Sincronizzazione fra due gestori d'interruzioni hardware 303-------------------------------------------------------- 304 305Condividere dati fra due gestori di interruzione hardware è molto raro, ma se 306succede, dovreste usare :c:func:`spin_lock_irqsave()`: è una specificità 307dell'architettura il fatto che tutte le interruzioni vengano interrotte 308quando si eseguono di gestori di interruzioni. 309 310Bigino della sincronizzazione 311============================= 312 313Pete Zaitcev ci offre il seguente riassunto: 314 315- Se siete in un contesto utente (una qualsiasi chiamata di sistema) 316 e volete sincronizzarvi con altri processi, usate i mutex. Potete trattenere 317 il mutex e dormire (``copy_from_user*(`` o ``kmalloc(x,GFP_KERNEL)``). 318 319- Altrimenti (== i dati possono essere manipolati da un'interruzione) usate 320 :c:func:`spin_lock_irqsave()` e :c:func:`spin_unlock_irqrestore()`. 321 322- Evitate di trattenere uno spinlock per più di 5 righe di codice incluse 323 le chiamate a funzione (ad eccezione di quell per l'accesso come 324 :c:func:`readb()`). 325 326Tabella dei requisiti minimi 327---------------------------- 328 329La tabella seguente illustra i requisiti **minimi** per la sincronizzazione fra 330diversi contesti. In alcuni casi, lo stesso contesto può essere eseguito solo 331da un processore per volta, quindi non ci sono requisiti per la 332sincronizzazione (per esempio, un thread può essere eseguito solo su un 333processore alla volta, ma se deve condividere dati con un altro thread, allora 334la sincronizzazione è necessaria). 335 336Ricordatevi il suggerimento qui sopra: potete sempre usare 337:c:func:`spin_lock_irqsave()`, che è un sovrainsieme di tutte le altre funzioni 338per spinlock. 339 340============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== 341. IRQ Handler A IRQ Handler B Softirq A Softirq B Tasklet A Tasklet B Timer A Timer B User Context A User Context B 342============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== 343IRQ Handler A None 344IRQ Handler B SLIS None 345Softirq A SLI SLI SL 346Softirq B SLI SLI SL SL 347Tasklet A SLI SLI SL SL None 348Tasklet B SLI SLI SL SL SL None 349Timer A SLI SLI SL SL SL SL None 350Timer B SLI SLI SL SL SL SL SL None 351User Context A SLI SLI SLBH SLBH SLBH SLBH SLBH SLBH None 352User Context B SLI SLI SLBH SLBH SLBH SLBH SLBH SLBH MLI None 353============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== 354 355Table: Tabella dei requisiti per la sincronizzazione 356 357+--------+----------------------------+ 358| SLIS | spin_lock_irqsave | 359+--------+----------------------------+ 360| SLI | spin_lock_irq | 361+--------+----------------------------+ 362| SL | spin_lock | 363+--------+----------------------------+ 364| SLBH | spin_lock_bh | 365+--------+----------------------------+ 366| MLI | mutex_lock_interruptible | 367+--------+----------------------------+ 368 369Table: Legenda per la tabella dei requisiti per la sincronizzazione 370 371Le funzioni *trylock* 372===================== 373 374Ci sono funzioni che provano a trattenere un *lock* solo una volta e 375ritornano immediatamente comunicato il successo od il fallimento 376dell'operazione. Posso essere usate quando non serve accedere ai dati 377protetti dal *lock* quando qualche altro thread lo sta già facendo 378trattenendo il *lock*. Potrete acquisire il *lock* più tardi se vi 379serve accedere ai dati protetti da questo *lock*. 380 381La funzione :c:func:`spin_trylock()` non ritenta di acquisire il *lock*, 382se ci riesce al primo colpo ritorna un valore diverso da zero, altrimenti 383se fallisce ritorna 0. Questa funzione può essere utilizzata in un qualunque 384contesto, ma come :c:func:`spin_lock()`: dovete disabilitare i contesti che 385potrebbero interrompervi e quindi trattenere lo spinlock. 386 387La funzione :c:func:`mutex_trylock()` invece di sospendere il vostro processo 388ritorna un valore diverso da zero se è possibile trattenere il lock al primo 389colpo, altrimenti se fallisce ritorna 0. Nonostante non dorma, questa funzione 390non può essere usata in modo sicuro in contesti di interruzione hardware o 391software. 392 393Esempi più comuni 394================= 395 396Guardiamo un semplice esempio: una memoria che associa nomi a numeri. 397La memoria tiene traccia di quanto spesso viene utilizzato ogni oggetto; 398quando è piena, l'oggetto meno usato viene eliminato. 399 400Tutto in contesto utente 401------------------------ 402 403Nel primo esempio, supponiamo che tutte le operazioni avvengano in contesto 404utente (in soldoni, da una chiamata di sistema), quindi possiamo dormire. 405Questo significa che possiamo usare i mutex per proteggere la nostra memoria 406e tutti gli oggetti che contiene. Ecco il codice:: 407 408 #include <linux/list.h> 409 #include <linux/slab.h> 410 #include <linux/string.h> 411 #include <linux/mutex.h> 412 #include <asm/errno.h> 413 414 struct object 415 { 416 struct list_head list; 417 int id; 418 char name[32]; 419 int popularity; 420 }; 421 422 /* Protects the cache, cache_num, and the objects within it */ 423 static DEFINE_MUTEX(cache_lock); 424 static LIST_HEAD(cache); 425 static unsigned int cache_num = 0; 426 #define MAX_CACHE_SIZE 10 427 428 /* Must be holding cache_lock */ 429 static struct object *__cache_find(int id) 430 { 431 struct object *i; 432 433 list_for_each_entry(i, &cache, list) 434 if (i->id == id) { 435 i->popularity++; 436 return i; 437 } 438 return NULL; 439 } 440 441 /* Must be holding cache_lock */ 442 static void __cache_delete(struct object *obj) 443 { 444 BUG_ON(!obj); 445 list_del(&obj->list); 446 kfree(obj); 447 cache_num--; 448 } 449 450 /* Must be holding cache_lock */ 451 static void __cache_add(struct object *obj) 452 { 453 list_add(&obj->list, &cache); 454 if (++cache_num > MAX_CACHE_SIZE) { 455 struct object *i, *outcast = NULL; 456 list_for_each_entry(i, &cache, list) { 457 if (!outcast || i->popularity < outcast->popularity) 458 outcast = i; 459 } 460 __cache_delete(outcast); 461 } 462 } 463 464 int cache_add(int id, const char *name) 465 { 466 struct object *obj; 467 468 if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) 469 return -ENOMEM; 470 471 strscpy(obj->name, name, sizeof(obj->name)); 472 obj->id = id; 473 obj->popularity = 0; 474 475 mutex_lock(&cache_lock); 476 __cache_add(obj); 477 mutex_unlock(&cache_lock); 478 return 0; 479 } 480 481 void cache_delete(int id) 482 { 483 mutex_lock(&cache_lock); 484 __cache_delete(__cache_find(id)); 485 mutex_unlock(&cache_lock); 486 } 487 488 int cache_find(int id, char *name) 489 { 490 struct object *obj; 491 int ret = -ENOENT; 492 493 mutex_lock(&cache_lock); 494 obj = __cache_find(id); 495 if (obj) { 496 ret = 0; 497 strcpy(name, obj->name); 498 } 499 mutex_unlock(&cache_lock); 500 return ret; 501 } 502 503Da notare che ci assicuriamo sempre di trattenere cache_lock quando 504aggiungiamo, rimuoviamo od ispezioniamo la memoria: sia la struttura 505della memoria che il suo contenuto sono protetti dal *lock*. Questo 506caso è semplice dato che copiamo i dati dall'utente e non permettiamo 507mai loro di accedere direttamente agli oggetti. 508 509C'è una piccola ottimizzazione qui: nella funzione :c:func:`cache_add()` 510impostiamo i campi dell'oggetto prima di acquisire il *lock*. Questo è 511sicuro perché nessun altro potrà accedervi finché non lo inseriremo 512nella memoria. 513 514Accesso dal contesto utente 515--------------------------- 516 517Ora consideriamo il caso in cui :c:func:`cache_find()` può essere invocata 518dal contesto d'interruzione: sia hardware che software. Un esempio potrebbe 519essere un timer che elimina oggetti dalla memoria. 520 521Qui di seguito troverete la modifica nel formato *patch*: le righe ``-`` 522sono quelle rimosse, mentre quelle ``+`` sono quelle aggiunte. 523 524:: 525 526 --- cache.c.usercontext 2003-12-09 13:58:54.000000000 +1100 527 +++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100 528 @@ -12,7 +12,7 @@ 529 int popularity; 530 }; 531 532 -static DEFINE_MUTEX(cache_lock); 533 +static DEFINE_SPINLOCK(cache_lock); 534 static LIST_HEAD(cache); 535 static unsigned int cache_num = 0; 536 #define MAX_CACHE_SIZE 10 537 @@ -55,6 +55,7 @@ 538 int cache_add(int id, const char *name) 539 { 540 struct object *obj; 541 + unsigned long flags; 542 543 if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL) 544 return -ENOMEM; 545 @@ -63,30 +64,33 @@ 546 obj->id = id; 547 obj->popularity = 0; 548 549 - mutex_lock(&cache_lock); 550 + spin_lock_irqsave(&cache_lock, flags); 551 __cache_add(obj); 552 - mutex_unlock(&cache_lock); 553 + spin_unlock_irqrestore(&cache_lock, flags); 554 return 0; 555 } 556 557 void cache_delete(int id) 558 { 559 - mutex_lock(&cache_lock); 560 + unsigned long flags; 561 + 562 + spin_lock_irqsave(&cache_lock, flags); 563 __cache_delete(__cache_find(id)); 564 - mutex_unlock(&cache_lock); 565 + spin_unlock_irqrestore(&cache_lock, flags); 566 } 567 568 int cache_find(int id, char *name) 569 { 570 struct object *obj; 571 int ret = -ENOENT; 572 + unsigned long flags; 573 574 - mutex_lock(&cache_lock); 575 + spin_lock_irqsave(&cache_lock, flags); 576 obj = __cache_find(id); 577 if (obj) { 578 ret = 0; 579 strcpy(name, obj->name); 580 } 581 - mutex_unlock(&cache_lock); 582 + spin_unlock_irqrestore(&cache_lock, flags); 583 return ret; 584 } 585 586Da notare che :c:func:`spin_lock_irqsave()` disabiliterà le interruzioni 587se erano attive, altrimenti non farà niente (quando siamo già in un contesto 588d'interruzione); dunque queste funzioni possono essere chiamante in 589sicurezza da qualsiasi contesto. 590 591Sfortunatamente, :c:func:`cache_add()` invoca :c:func:`kmalloc()` con 592l'opzione ``GFP_KERNEL`` che è permessa solo in contesto utente. Ho supposto 593che :c:func:`cache_add()` venga chiamata dal contesto utente, altrimenti 594questa opzione deve diventare un parametro di :c:func:`cache_add()`. 595 596Esporre gli oggetti al di fuori del file 597---------------------------------------- 598 599Se i vostri oggetti contengono più informazioni, potrebbe non essere 600sufficiente copiare i dati avanti e indietro: per esempio, altre parti del 601codice potrebbero avere un puntatore a questi oggetti piuttosto che cercarli 602ogni volta. Questo introduce due problemi. 603 604Il primo problema è che utilizziamo ``cache_lock`` per proteggere gli oggetti: 605dobbiamo renderlo dinamico così che il resto del codice possa usarlo. Questo 606rende la sincronizzazione più complicata dato che non avviene più in un unico 607posto. 608 609Il secondo problema è il problema del ciclo di vita: se un'altra struttura 610mantiene un puntatore ad un oggetto, presumibilmente si aspetta che questo 611puntatore rimanga valido. Sfortunatamente, questo è garantito solo mentre 612si trattiene il *lock*, altrimenti qualcuno potrebbe chiamare 613:c:func:`cache_delete()` o peggio, aggiungere un oggetto che riutilizza lo 614stesso indirizzo. 615 616Dato che c'è un solo *lock*, non potete trattenerlo a vita: altrimenti 617nessun altro potrà eseguire il proprio lavoro. 618 619La soluzione a questo problema è l'uso di un contatore di riferimenti: 620chiunque punti ad un oggetto deve incrementare il contatore, e decrementarlo 621quando il puntatore non viene più usato. Quando il contatore raggiunge lo zero 622significa che non è più usato e l'oggetto può essere rimosso. 623 624Ecco il codice:: 625 626 --- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100 627 +++ cache.c.refcnt 2003-12-09 14:33:05.000000000 +1100 628 @@ -7,6 +7,7 @@ 629 struct object 630 { 631 struct list_head list; 632 + unsigned int refcnt; 633 int id; 634 char name[32]; 635 int popularity; 636 @@ -17,6 +18,35 @@ 637 static unsigned int cache_num = 0; 638 #define MAX_CACHE_SIZE 10 639 640 +static void __object_put(struct object *obj) 641 +{ 642 + if (--obj->refcnt == 0) 643 + kfree(obj); 644 +} 645 + 646 +static void __object_get(struct object *obj) 647 +{ 648 + obj->refcnt++; 649 +} 650 + 651 +void object_put(struct object *obj) 652 +{ 653 + unsigned long flags; 654 + 655 + spin_lock_irqsave(&cache_lock, flags); 656 + __object_put(obj); 657 + spin_unlock_irqrestore(&cache_lock, flags); 658 +} 659 + 660 +void object_get(struct object *obj) 661 +{ 662 + unsigned long flags; 663 + 664 + spin_lock_irqsave(&cache_lock, flags); 665 + __object_get(obj); 666 + spin_unlock_irqrestore(&cache_lock, flags); 667 +} 668 + 669 /* Must be holding cache_lock */ 670 static struct object *__cache_find(int id) 671 { 672 @@ -35,6 +65,7 @@ 673 { 674 BUG_ON(!obj); 675 list_del(&obj->list); 676 + __object_put(obj); 677 cache_num--; 678 } 679 680 @@ -63,6 +94,7 @@ 681 strscpy(obj->name, name, sizeof(obj->name)); 682 obj->id = id; 683 obj->popularity = 0; 684 + obj->refcnt = 1; /* The cache holds a reference */ 685 686 spin_lock_irqsave(&cache_lock, flags); 687 __cache_add(obj); 688 @@ -79,18 +111,15 @@ 689 spin_unlock_irqrestore(&cache_lock, flags); 690 } 691 692 -int cache_find(int id, char *name) 693 +struct object *cache_find(int id) 694 { 695 struct object *obj; 696 - int ret = -ENOENT; 697 unsigned long flags; 698 699 spin_lock_irqsave(&cache_lock, flags); 700 obj = __cache_find(id); 701 - if (obj) { 702 - ret = 0; 703 - strcpy(name, obj->name); 704 - } 705 + if (obj) 706 + __object_get(obj); 707 spin_unlock_irqrestore(&cache_lock, flags); 708 - return ret; 709 + return obj; 710 } 711 712Abbiamo incapsulato il contatore di riferimenti nelle tipiche funzioni 713di 'get' e 'put'. Ora possiamo ritornare l'oggetto da :c:func:`cache_find()` 714col vantaggio che l'utente può dormire trattenendo l'oggetto (per esempio, 715:c:func:`copy_to_user()` per copiare il nome verso lo spazio utente). 716 717Un altro punto da notare è che ho detto che il contatore dovrebbe incrementarsi 718per ogni puntatore ad un oggetto: quindi il contatore di riferimenti è 1 719quando l'oggetto viene inserito nella memoria. In altre versione il framework 720non trattiene un riferimento per se, ma diventa più complicato. 721 722Usare operazioni atomiche per il contatore di riferimenti 723~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 724 725In sostanza, :c:type:`atomic_t` viene usato come contatore di riferimenti. 726Ci sono un certo numbero di operazioni atomiche definite 727in ``include/asm/atomic.h``: queste sono garantite come atomiche su qualsiasi 728processore del sistema, quindi non sono necessari i *lock*. In questo caso è 729più semplice rispetto all'uso degli spinlock, benché l'uso degli spinlock 730sia più elegante per casi non banali. Le funzioni :c:func:`atomic_inc()` e 731:c:func:`atomic_dec_and_test()` vengono usate al posto dei tipici operatori di 732incremento e decremento, e i *lock* non sono più necessari per proteggere il 733contatore stesso. 734 735:: 736 737 --- cache.c.refcnt 2003-12-09 15:00:35.000000000 +1100 738 +++ cache.c.refcnt-atomic 2003-12-11 15:49:42.000000000 +1100 739 @@ -7,7 +7,7 @@ 740 struct object 741 { 742 struct list_head list; 743 - unsigned int refcnt; 744 + atomic_t refcnt; 745 int id; 746 char name[32]; 747 int popularity; 748 @@ -18,33 +18,15 @@ 749 static unsigned int cache_num = 0; 750 #define MAX_CACHE_SIZE 10 751 752 -static void __object_put(struct object *obj) 753 -{ 754 - if (--obj->refcnt == 0) 755 - kfree(obj); 756 -} 757 - 758 -static void __object_get(struct object *obj) 759 -{ 760 - obj->refcnt++; 761 -} 762 - 763 void object_put(struct object *obj) 764 { 765 - unsigned long flags; 766 - 767 - spin_lock_irqsave(&cache_lock, flags); 768 - __object_put(obj); 769 - spin_unlock_irqrestore(&cache_lock, flags); 770 + if (atomic_dec_and_test(&obj->refcnt)) 771 + kfree(obj); 772 } 773 774 void object_get(struct object *obj) 775 { 776 - unsigned long flags; 777 - 778 - spin_lock_irqsave(&cache_lock, flags); 779 - __object_get(obj); 780 - spin_unlock_irqrestore(&cache_lock, flags); 781 + atomic_inc(&obj->refcnt); 782 } 783 784 /* Must be holding cache_lock */ 785 @@ -65,7 +47,7 @@ 786 { 787 BUG_ON(!obj); 788 list_del(&obj->list); 789 - __object_put(obj); 790 + object_put(obj); 791 cache_num--; 792 } 793 794 @@ -94,7 +76,7 @@ 795 strscpy(obj->name, name, sizeof(obj->name)); 796 obj->id = id; 797 obj->popularity = 0; 798 - obj->refcnt = 1; /* The cache holds a reference */ 799 + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ 800 801 spin_lock_irqsave(&cache_lock, flags); 802 __cache_add(obj); 803 @@ -119,7 +101,7 @@ 804 spin_lock_irqsave(&cache_lock, flags); 805 obj = __cache_find(id); 806 if (obj) 807 - __object_get(obj); 808 + object_get(obj); 809 spin_unlock_irqrestore(&cache_lock, flags); 810 return obj; 811 } 812 813Proteggere l'oggetto stesso 814--------------------------- 815 816In questo esempio, assumiamo che gli oggetti (ad eccezione del contatore 817di riferimenti) non cambino mai dopo la loro creazione. Se vogliamo permettere 818al nome di cambiare abbiamo tre possibilità: 819 820- Si può togliere static da ``cache_lock`` e dire agli utenti che devono 821 trattenere il *lock* prima di modificare il nome di un oggetto. 822 823- Si può fornire una funzione :c:func:`cache_obj_rename()` che prende il 824 *lock* e cambia il nome per conto del chiamante; si dirà poi agli utenti 825 di usare questa funzione. 826 827- Si può decidere che ``cache_lock`` protegge solo la memoria stessa, ed 828 un altro *lock* è necessario per la protezione del nome. 829 830Teoricamente, possiamo avere un *lock* per ogni campo e per ogni oggetto. 831In pratica, le varianti più comuni sono: 832 833- un *lock* che protegge l'infrastruttura (la lista ``cache`` di questo 834 esempio) e gli oggetti. Questo è quello che abbiamo fatto finora. 835 836- un *lock* che protegge l'infrastruttura (inclusi i puntatori alla lista 837 negli oggetti), e un *lock* nell'oggetto per proteggere il resto 838 dell'oggetto stesso. 839 840- *lock* multipli per proteggere l'infrastruttura (per esempio un *lock* 841 per ogni lista), possibilmente con un *lock* per oggetto. 842 843Qui di seguito un'implementazione con "un lock per oggetto": 844 845:: 846 847 --- cache.c.refcnt-atomic 2003-12-11 15:50:54.000000000 +1100 848 +++ cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 849 @@ -6,11 +6,17 @@ 850 851 struct object 852 { 853 + /* These two protected by cache_lock. */ 854 struct list_head list; 855 + int popularity; 856 + 857 atomic_t refcnt; 858 + 859 + /* Doesn't change once created. */ 860 int id; 861 + 862 + spinlock_t lock; /* Protects the name */ 863 char name[32]; 864 - int popularity; 865 }; 866 867 static DEFINE_SPINLOCK(cache_lock); 868 @@ -77,6 +84,7 @@ 869 obj->id = id; 870 obj->popularity = 0; 871 atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ 872 + spin_lock_init(&obj->lock); 873 874 spin_lock_irqsave(&cache_lock, flags); 875 __cache_add(obj); 876 877Da notare che ho deciso che il contatore di popolarità dovesse essere 878protetto da ``cache_lock`` piuttosto che dal *lock* dell'oggetto; questo 879perché è logicamente parte dell'infrastruttura (come 880:c:type:`struct list_head <list_head>` nell'oggetto). In questo modo, 881in :c:func:`__cache_add()`, non ho bisogno di trattenere il *lock* di ogni 882oggetto mentre si cerca il meno popolare. 883 884Ho anche deciso che il campo id è immutabile, quindi non ho bisogno di 885trattenere il lock dell'oggetto quando si usa :c:func:`__cache_find()` 886per leggere questo campo; il *lock* dell'oggetto è usato solo dal chiamante 887che vuole leggere o scrivere il campo name. 888 889Inoltre, da notare che ho aggiunto un commento che descrive i dati che sono 890protetti dal *lock*. Questo è estremamente importante in quanto descrive il 891comportamento del codice, che altrimenti sarebbe di difficile comprensione 892leggendo solamente il codice. E come dice Alan Cox: “Lock data, not code”. 893 894Problemi comuni 895=============== 896 897.. _`it_deadlock`: 898 899Stallo: semplice ed avanzato 900---------------------------- 901 902Esiste un tipo di baco dove un pezzo di codice tenta di trattenere uno 903spinlock due volte: questo rimarrà in attesa attiva per sempre aspettando che 904il *lock* venga rilasciato (in Linux spinlocks, rwlocks e mutex non sono 905ricorsivi). 906Questo è facile da diagnosticare: non è uno di quei problemi che ti tengono 907sveglio 5 notti a parlare da solo. 908 909Un caso un pochino più complesso; immaginate d'avere una spazio condiviso 910fra un softirq ed il contesto utente. Se usate :c:func:`spin_lock()` per 911proteggerlo, il contesto utente potrebbe essere interrotto da un softirq 912mentre trattiene il lock, da qui il softirq rimarrà in attesa attiva provando 913ad acquisire il *lock* già trattenuto nel contesto utente. 914 915Questi casi sono chiamati stalli (*deadlock*), e come mostrato qui sopra, 916può succedere anche con un solo processore (Ma non sui sistemi 917monoprocessore perché gli spinlock spariscano quando il kernel è compilato 918con ``CONFIG_SMP``\ =n. Nonostante ciò, nel secondo caso avrete comunque 919una corruzione dei dati). 920 921Questi casi sono facili da diagnosticare; sui sistemi multi-processore 922il supervisione (*watchdog*) o l'opzione di compilazione ``DEBUG_SPINLOCK`` 923(``include/linux/spinlock.h``) permettono di scovare immediatamente quando 924succedono. 925 926Esiste un caso più complesso che è conosciuto come l'abbraccio della morte; 927questo coinvolge due o più *lock*. Diciamo che avete un vettore di hash in cui 928ogni elemento è uno spinlock a cui è associata una lista di elementi con lo 929stesso hash. In un gestore di interruzioni software, dovete modificare un 930oggetto e spostarlo su un altro hash; quindi dovrete trattenete lo spinlock 931del vecchio hash e di quello nuovo, quindi rimuovere l'oggetto dal vecchio ed 932inserirlo nel nuovo. 933 934Qui abbiamo due problemi. Primo, se il vostro codice prova a spostare un 935oggetto all'interno della stessa lista, otterrete uno stallo visto che 936tenterà di trattenere lo stesso *lock* due volte. Secondo, se la stessa 937interruzione software su un altro processore sta tentando di spostare 938un altro oggetto nella direzione opposta, potrebbe accadere quanto segue: 939 940+---------------------------------+---------------------------------+ 941| CPU 1 | CPU 2 | 942+=================================+=================================+ 943| Trattiene *lock* A -> OK | Trattiene *lock* B -> OK | 944+---------------------------------+---------------------------------+ 945| Trattiene *lock* B -> attesa | Trattiene *lock* A -> attesa | 946+---------------------------------+---------------------------------+ 947 948Table: Conseguenze 949 950Entrambe i processori rimarranno in attesa attiva sul *lock* per sempre, 951aspettando che l'altro lo rilasci. Sembra e puzza come un blocco totale. 952 953Prevenire gli stalli 954-------------------- 955 956I libri di testo vi diranno che se trattenete i *lock* sempre nello stesso 957ordine non avrete mai un simile stallo. La pratica vi dirà che questo 958approccio non funziona all'ingrandirsi del sistema: quando creo un nuovo 959*lock* non ne capisco abbastanza del kernel per dire in quale dei 5000 *lock* 960si incastrerà. 961 962I *lock* migliori sono quelli incapsulati: non vengono esposti nei file di 963intestazione, e non vengono mai trattenuti fuori dallo stesso file. Potete 964rileggere questo codice e vedere che non ci sarà mai uno stallo perché 965non tenterà mai di trattenere un altro *lock* quando lo ha già. 966Le persone che usano il vostro codice non devono nemmeno sapere che voi 967state usando dei *lock*. 968 969Un classico problema deriva dall'uso di *callback* e di *hook*: se li 970chiamate mentre trattenete un *lock*, rischiate uno stallo o un abbraccio 971della morte (chi lo sa cosa farà una *callback*?). 972 973Ossessiva prevenzione degli stalli 974~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 975 976Gli stalli sono un problema, ma non così terribile come la corruzione dei dati. 977Un pezzo di codice trattiene un *lock* di lettura, cerca in una lista, 978fallisce nel trovare quello che vuole, quindi rilascia il *lock* di lettura, 979trattiene un *lock* di scrittura ed inserisce un oggetto; questo genere di 980codice presenta una corsa critica. 981 982Se non riuscite a capire il perché, per favore state alla larga dal mio 983codice. 984 985corsa fra temporizzatori: un passatempo del kernel 986-------------------------------------------------- 987 988I temporizzatori potrebbero avere dei problemi con le corse critiche. 989Considerate una collezione di oggetti (liste, hash, eccetera) dove ogni oggetto 990ha un temporizzatore che sta per distruggerlo. 991 992Se volete eliminare l'intera collezione (diciamo quando rimuovete un modulo), 993potreste fare come segue:: 994 995 /* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE 996 HUNGARIAN NOTATION */ 997 spin_lock_bh(&list_lock); 998 999 while (list) { 1000 struct foo *next = list->next; 1001 del_timer(&list->timer); 1002 kfree(list); 1003 list = next; 1004 } 1005 1006 spin_unlock_bh(&list_lock); 1007 1008Primo o poi, questo esploderà su un sistema multiprocessore perché un 1009temporizzatore potrebbe essere già partiro prima di :c:func:`spin_lock_bh()`, 1010e prenderà il *lock* solo dopo :c:func:`spin_unlock_bh()`, e cercherà 1011di eliminare il suo oggetto (che però è già stato eliminato). 1012 1013Questo può essere evitato controllando il valore di ritorno di 1014:c:func:`del_timer()`: se ritorna 1, il temporizzatore è stato già 1015rimosso. Se 0, significa (in questo caso) che il temporizzatore è in 1016esecuzione, quindi possiamo fare come segue:: 1017 1018 retry: 1019 spin_lock_bh(&list_lock); 1020 1021 while (list) { 1022 struct foo *next = list->next; 1023 if (!del_timer(&list->timer)) { 1024 /* Give timer a chance to delete this */ 1025 spin_unlock_bh(&list_lock); 1026 goto retry; 1027 } 1028 kfree(list); 1029 list = next; 1030 } 1031 1032 spin_unlock_bh(&list_lock); 1033 1034Un altro problema è l'eliminazione dei temporizzatori che si riavviano 1035da soli (chiamando :c:func:`add_timer()` alla fine della loro esecuzione). 1036Dato che questo è un problema abbastanza comune con una propensione 1037alle corse critiche, dovreste usare :c:func:`del_timer_sync()` 1038(``include/linux/timer.h``) per gestire questo caso. Questa ritorna il 1039numero di volte che il temporizzatore è stato interrotto prima che 1040fosse in grado di fermarlo senza che si riavviasse. 1041 1042Velocità della sincronizzazione 1043=============================== 1044 1045Ci sono tre cose importanti da tenere in considerazione quando si valuta 1046la velocità d'esecuzione di un pezzo di codice che necessita di 1047sincronizzazione. La prima è la concorrenza: quante cose rimangono in attesa 1048mentre qualcuno trattiene un *lock*. La seconda è il tempo necessario per 1049acquisire (senza contese) e rilasciare un *lock*. La terza è di usare meno 1050*lock* o di più furbi. Immagino che i *lock* vengano usati regolarmente, 1051altrimenti, non sareste interessati all'efficienza. 1052 1053La concorrenza dipende da quanto a lungo un *lock* è trattenuto: dovreste 1054trattenere un *lock* solo il tempo minimo necessario ma non un istante in più. 1055Nella memoria dell'esempio precedente, creiamo gli oggetti senza trattenere 1056il *lock*, poi acquisiamo il *lock* quando siamo pronti per inserirlo nella 1057lista. 1058 1059Il tempo di acquisizione di un *lock* dipende da quanto danno fa 1060l'operazione sulla *pipeline* (ovvero stalli della *pipeline*) e quant'è 1061probabile che il processore corrente sia stato anche l'ultimo ad acquisire 1062il *lock* (in pratica, il *lock* è nella memoria cache del processore 1063corrente?): su sistemi multi-processore questa probabilità precipita 1064rapidamente. Consideriamo un processore Intel Pentium III a 700Mhz: questo 1065esegue un'istruzione in 0.7ns, un incremento atomico richiede 58ns, acquisire 1066un *lock* che è nella memoria cache del processore richiede 160ns, e un 1067trasferimento dalla memoria cache di un altro processore richiede altri 1068170/360ns (Leggetevi l'articolo di Paul McKenney's `Linux Journal RCU 1069article <http://www.linuxjournal.com/article.php?sid=6993>`__). 1070 1071Questi due obiettivi sono in conflitto: trattenere un *lock* per il minor 1072tempo possibile potrebbe richiedere la divisione in più *lock* per diverse 1073parti (come nel nostro ultimo esempio con un *lock* per ogni oggetto), 1074ma questo aumenta il numero di acquisizioni di *lock*, ed il risultato 1075spesso è che tutto è più lento che con un singolo *lock*. Questo è un altro 1076argomento in favore della semplicità quando si parla di sincronizzazione. 1077 1078Il terzo punto è discusso di seguito: ci sono alcune tecniche per ridurre 1079il numero di sincronizzazioni che devono essere fatte. 1080 1081Read/Write Lock Variants 1082------------------------ 1083 1084Sia gli spinlock che i mutex hanno una variante per la lettura/scrittura 1085(read/write): ``rwlock_t`` e :c:type:`struct rw_semaphore <rw_semaphore>`. 1086Queste dividono gli utenti in due categorie: i lettori e gli scrittori. 1087Se state solo leggendo i dati, potete acquisire il *lock* di lettura, ma 1088per scrivere avrete bisogno del *lock* di scrittura. Molti possono trattenere 1089il *lock* di lettura, ma solo uno scrittore alla volta può trattenere 1090quello di scrittura. 1091 1092Se il vostro codice si divide chiaramente in codice per lettori e codice 1093per scrittori (come nel nostro esempio), e il *lock* dei lettori viene 1094trattenuto per molto tempo, allora l'uso di questo tipo di *lock* può aiutare. 1095Questi sono leggermente più lenti rispetto alla loro versione normale, quindi 1096nella pratica l'uso di ``rwlock_t`` non ne vale la pena. 1097 1098Evitare i *lock*: Read Copy Update 1099-------------------------------------------- 1100 1101Esiste un metodo di sincronizzazione per letture e scritture detto 1102Read Copy Update. Con l'uso della tecnica RCU, i lettori possono scordarsi 1103completamente di trattenere i *lock*; dato che nel nostro esempio ci 1104aspettiamo d'avere più lettore che scrittori (altrimenti questa memoria 1105sarebbe uno spreco) possiamo dire che questo meccanismo permette 1106un'ottimizzazione. 1107 1108Come facciamo a sbarazzarci dei *lock* di lettura? Sbarazzarsi dei *lock* di 1109lettura significa che uno scrittore potrebbe cambiare la lista sotto al naso 1110dei lettori. Questo è abbastanza semplice: possiamo leggere una lista 1111concatenata se lo scrittore aggiunge elementi alla fine e con certe 1112precauzioni. Per esempio, aggiungendo ``new`` ad una lista concatenata 1113chiamata ``list``:: 1114 1115 new->next = list->next; 1116 wmb(); 1117 list->next = new; 1118 1119La funzione :c:func:`wmb()` è una barriera di sincronizzazione delle 1120scritture. Questa garantisce che la prima operazione (impostare l'elemento 1121``next`` del nuovo elemento) venga completata e vista da tutti i processori 1122prima che venga eseguita la seconda operazione (che sarebbe quella di mettere 1123il nuovo elemento nella lista). Questo è importante perché i moderni 1124compilatori ed i moderni processori possono, entrambe, riordinare le istruzioni 1125se non vengono istruiti altrimenti: vogliamo che i lettori non vedano 1126completamente il nuovo elemento; oppure che lo vedano correttamente e quindi 1127il puntatore ``next`` deve puntare al resto della lista. 1128 1129Fortunatamente, c'è una funzione che fa questa operazione sulle liste 1130:c:type:`struct list_head <list_head>`: :c:func:`list_add_rcu()` 1131(``include/linux/list.h``). 1132 1133Rimuovere un elemento dalla lista è anche più facile: sostituiamo il puntatore 1134al vecchio elemento con quello del suo successore, e i lettori vedranno 1135l'elemento o lo salteranno. 1136 1137:: 1138 1139 list->next = old->next; 1140 1141La funzione :c:func:`list_del_rcu()` (``include/linux/list.h``) fa esattamente 1142questo (la versione normale corrompe il vecchio oggetto, e non vogliamo che 1143accada). 1144 1145Anche i lettori devono stare attenti: alcuni processori potrebbero leggere 1146attraverso il puntatore ``next`` il contenuto dell'elemento successivo 1147troppo presto, ma non accorgersi che il contenuto caricato è sbagliato quando 1148il puntatore ``next`` viene modificato alla loro spalle. Ancora una volta 1149c'è una funzione che viene in vostro aiuto :c:func:`list_for_each_entry_rcu()` 1150(``include/linux/list.h``). Ovviamente, gli scrittori possono usare 1151:c:func:`list_for_each_entry()` dato che non ci possono essere due scrittori 1152in contemporanea. 1153 1154Il nostro ultimo dilemma è il seguente: quando possiamo realmente distruggere 1155l'elemento rimosso? Ricordate, un lettore potrebbe aver avuto accesso a questo 1156elemento proprio ora: se eliminiamo questo elemento ed il puntatore ``next`` 1157cambia, il lettore salterà direttamente nella spazzatura e scoppierà. Dobbiamo 1158aspettare finché tutti i lettori che stanno attraversando la lista abbiano 1159finito. Utilizziamo :c:func:`call_rcu()` per registrare una funzione di 1160richiamo che distrugga l'oggetto quando tutti i lettori correnti hanno 1161terminato. In alternative, potrebbe essere usata la funzione 1162:c:func:`synchronize_rcu()` che blocca l'esecuzione finché tutti i lettori 1163non terminano di ispezionare la lista. 1164 1165Ma come fa l'RCU a sapere quando i lettori sono finiti? Il meccanismo è 1166il seguente: innanzi tutto i lettori accedono alla lista solo fra la coppia 1167:c:func:`rcu_read_lock()`/:c:func:`rcu_read_unlock()` che disabilita la 1168prelazione così che i lettori non vengano sospesi mentre stanno leggendo 1169la lista. 1170 1171Poi, l'RCU aspetta finché tutti i processori non abbiano dormito almeno 1172una volta; a questo punto, dato che i lettori non possono dormire, possiamo 1173dedurre che un qualsiasi lettore che abbia consultato la lista durante la 1174rimozione abbia già terminato, quindi la *callback* viene eseguita. Il vero 1175codice RCU è un po' più ottimizzato di così, ma questa è l'idea di fondo. 1176 1177:: 1178 1179 --- cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 1180 +++ cache.c.rcupdate 2003-12-11 17:55:14.000000000 +1100 1181 @@ -1,15 +1,18 @@ 1182 #include <linux/list.h> 1183 #include <linux/slab.h> 1184 #include <linux/string.h> 1185 +#include <linux/rcupdate.h> 1186 #include <linux/mutex.h> 1187 #include <asm/errno.h> 1188 1189 struct object 1190 { 1191 - /* These two protected by cache_lock. */ 1192 + /* This is protected by RCU */ 1193 struct list_head list; 1194 int popularity; 1195 1196 + struct rcu_head rcu; 1197 + 1198 atomic_t refcnt; 1199 1200 /* Doesn't change once created. */ 1201 @@ -40,7 +43,7 @@ 1202 { 1203 struct object *i; 1204 1205 - list_for_each_entry(i, &cache, list) { 1206 + list_for_each_entry_rcu(i, &cache, list) { 1207 if (i->id == id) { 1208 i->popularity++; 1209 return i; 1210 @@ -49,19 +52,25 @@ 1211 return NULL; 1212 } 1213 1214 +/* Final discard done once we know no readers are looking. */ 1215 +static void cache_delete_rcu(void *arg) 1216 +{ 1217 + object_put(arg); 1218 +} 1219 + 1220 /* Must be holding cache_lock */ 1221 static void __cache_delete(struct object *obj) 1222 { 1223 BUG_ON(!obj); 1224 - list_del(&obj->list); 1225 - object_put(obj); 1226 + list_del_rcu(&obj->list); 1227 cache_num--; 1228 + call_rcu(&obj->rcu, cache_delete_rcu); 1229 } 1230 1231 /* Must be holding cache_lock */ 1232 static void __cache_add(struct object *obj) 1233 { 1234 - list_add(&obj->list, &cache); 1235 + list_add_rcu(&obj->list, &cache); 1236 if (++cache_num > MAX_CACHE_SIZE) { 1237 struct object *i, *outcast = NULL; 1238 list_for_each_entry(i, &cache, list) { 1239 @@ -104,12 +114,11 @@ 1240 struct object *cache_find(int id) 1241 { 1242 struct object *obj; 1243 - unsigned long flags; 1244 1245 - spin_lock_irqsave(&cache_lock, flags); 1246 + rcu_read_lock(); 1247 obj = __cache_find(id); 1248 if (obj) 1249 object_get(obj); 1250 - spin_unlock_irqrestore(&cache_lock, flags); 1251 + rcu_read_unlock(); 1252 return obj; 1253 } 1254 1255Da notare che i lettori modificano il campo popularity nella funzione 1256:c:func:`__cache_find()`, e ora non trattiene alcun *lock*. Una soluzione 1257potrebbe essere quella di rendere la variabile ``atomic_t``, ma per l'uso 1258che ne abbiamo fatto qui, non ci interessano queste corse critiche perché un 1259risultato approssimativo è comunque accettabile, quindi non l'ho cambiato. 1260 1261Il risultato è che la funzione :c:func:`cache_find()` non ha bisogno di alcuna 1262sincronizzazione con le altre funzioni, quindi è veloce su un sistema 1263multi-processore tanto quanto lo sarebbe su un sistema mono-processore. 1264 1265Esiste un'ulteriore ottimizzazione possibile: vi ricordate il codice originale 1266della nostra memoria dove non c'erano contatori di riferimenti e il chiamante 1267semplicemente tratteneva il *lock* prima di accedere ad un oggetto? Questo è 1268ancora possibile: se trattenete un *lock* nessuno potrà cancellare l'oggetto, 1269quindi non avete bisogno di incrementare e decrementare il contatore di 1270riferimenti. 1271 1272Ora, dato che il '*lock* di lettura' di un RCU non fa altro che disabilitare 1273la prelazione, un chiamante che ha sempre la prelazione disabilitata fra le 1274chiamate :c:func:`cache_find()` e :c:func:`object_put()` non necessita 1275di incrementare e decrementare il contatore di riferimenti. Potremmo 1276esporre la funzione :c:func:`__cache_find()` dichiarandola non-static, 1277e quel chiamante potrebbe usare direttamente questa funzione. 1278 1279Il beneficio qui sta nel fatto che il contatore di riferimenti no 1280viene scritto: l'oggetto non viene alterato in alcun modo e quindi diventa 1281molto più veloce su sistemi molti-processore grazie alla loro memoria cache. 1282 1283.. _`it_per-cpu`: 1284 1285Dati per processore 1286------------------- 1287 1288Un'altra tecnica comunemente usata per evitare la sincronizzazione è quella 1289di duplicare le informazioni per ogni processore. Per esempio, se volete 1290avere un contatore di qualcosa, potreste utilizzare uno spinlock ed un 1291singolo contatore. Facile e pulito. 1292 1293Se questo dovesse essere troppo lento (solitamente non lo è, ma se avete 1294dimostrato che lo è devvero), potreste usare un contatore per ogni processore 1295e quindi non sarebbe più necessaria la mutua esclusione. Vedere 1296:c:func:`DEFINE_PER_CPU()`, :c:func:`get_cpu_var()` e :c:func:`put_cpu_var()` 1297(``include/linux/percpu.h``). 1298 1299Il tipo di dato ``local_t``, la funzione :c:func:`cpu_local_inc()` e tutte 1300le altre funzioni associate, sono di particolare utilità per semplici contatori 1301per-processore; su alcune architetture sono anche più efficienti 1302(``include/asm/local.h``). 1303 1304Da notare che non esiste un modo facile ed affidabile per ottenere il valore 1305di un simile contatore senza introdurre altri *lock*. In alcuni casi questo 1306non è un problema. 1307 1308Dati che sono usati prevalentemente dai gestori d'interruzioni 1309-------------------------------------------------------------- 1310 1311Se i dati vengono utilizzati sempre dallo stesso gestore d'interruzioni, 1312allora i *lock* non vi servono per niente: il kernel già vi garantisce che 1313il gestore d'interruzione non verrà eseguito in contemporanea su diversi 1314processori. 1315 1316Manfred Spraul fa notare che potreste comunque comportarvi così anche 1317se i dati vengono occasionalmente utilizzati da un contesto utente o 1318da un'interruzione software. Il gestore d'interruzione non utilizza alcun 1319*lock*, e tutti gli altri accessi verranno fatti così:: 1320 1321 spin_lock(&lock); 1322 disable_irq(irq); 1323 ... 1324 enable_irq(irq); 1325 spin_unlock(&lock); 1326 1327La funzione :c:func:`disable_irq()` impedisce al gestore d'interruzioni 1328d'essere eseguito (e aspetta che finisca nel caso fosse in esecuzione su 1329un altro processore). Lo spinlock, invece, previene accessi simultanei. 1330Naturalmente, questo è più lento della semplice chiamata 1331:c:func:`spin_lock_irq()`, quindi ha senso solo se questo genere di accesso 1332è estremamente raro. 1333 1334.. _`it_sleeping-things`: 1335 1336Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni? 1337========================================================================= 1338 1339Molte funzioni del kernel dormono (in sostanza, chiamano ``schedule()``) 1340direttamente od indirettamente: non potete chiamarle se trattenere uno 1341spinlock o avete la prelazione disabilitata, mai. Questo significa che 1342dovete necessariamente essere nel contesto utente: chiamarle da un 1343contesto d'interruzione è illegale. 1344 1345Alcune funzioni che dormono 1346--------------------------- 1347 1348Le più comuni sono elencate qui di seguito, ma solitamente dovete leggere 1349il codice per scoprire se altre chiamate sono sicure. Se chiunque altro 1350le chiami dorme, allora dovreste poter dormire anche voi. In particolar 1351modo, le funzioni di registrazione e deregistrazione solitamente si 1352aspettano d'essere chiamante da un contesto utente e quindi che possono 1353dormire. 1354 1355- Accessi allo spazio utente: 1356 1357 - :c:func:`copy_from_user()` 1358 1359 - :c:func:`copy_to_user()` 1360 1361 - :c:func:`get_user()` 1362 1363 - :c:func:`put_user()` 1364 1365- :c:func:`kmalloc(GFP_KERNEL) <kmalloc>` 1366 1367- :c:func:`mutex_lock_interruptible()` and 1368 :c:func:`mutex_lock()` 1369 1370 C'è anche :c:func:`mutex_trylock()` che però non dorme. 1371 Comunque, non deve essere usata in un contesto d'interruzione dato 1372 che la sua implementazione non è sicura in quel contesto. 1373 Anche :c:func:`mutex_unlock()` non dorme mai. Non può comunque essere 1374 usata in un contesto d'interruzione perché un mutex deve essere rilasciato 1375 dallo stesso processo che l'ha acquisito. 1376 1377Alcune funzioni che non dormono 1378------------------------------- 1379 1380Alcune funzioni possono essere chiamate tranquillamente da qualsiasi 1381contesto, o trattenendo un qualsiasi *lock*. 1382 1383- :c:func:`printk()` 1384 1385- :c:func:`kfree()` 1386 1387- :c:func:`add_timer()` e :c:func:`del_timer()` 1388 1389Riferimento per l'API dei Mutex 1390=============================== 1391 1392.. kernel-doc:: include/linux/mutex.h 1393 :internal: 1394 1395.. kernel-doc:: kernel/locking/mutex.c 1396 :export: 1397 1398Riferimento per l'API dei Futex 1399=============================== 1400 1401.. kernel-doc:: kernel/futex.c 1402 :internal: 1403 1404Approfondimenti 1405=============== 1406 1407- ``Documentation/locking/spinlocks.rst``: la guida di Linus Torvalds agli 1408 spinlock del kernel. 1409 1410- Unix Systems for Modern Architectures: Symmetric Multiprocessing and 1411 Caching for Kernel Programmers. 1412 1413 L'introduzione alla sincronizzazione a livello di kernel di Curt Schimmel 1414 è davvero ottima (non è scritta per Linux, ma approssimativamente si adatta 1415 a tutte le situazioni). Il libro è costoso, ma vale ogni singolo spicciolo 1416 per capire la sincronizzazione nei sistemi multi-processore. 1417 [ISBN: 0201633388] 1418 1419Ringraziamenti 1420============== 1421 1422Grazie a Telsa Gwynne per aver formattato questa guida in DocBook, averla 1423pulita e aggiunto un po' di stile. 1424 1425Grazie a Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul Mackerras, 1426Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim Waugh, Pete Zaitcev, 1427James Morris, Robert Love, Paul McKenney, John Ashby per aver revisionato, 1428corretto, maledetto e commentato. 1429 1430Grazie alla congrega per non aver avuto alcuna influenza su questo documento. 1431 1432Glossario 1433========= 1434 1435prelazione 1436 Prima del kernel 2.5, o quando ``CONFIG_PREEMPT`` non è impostato, i processi 1437 in contesto utente non si avvicendano nell'esecuzione (in pratica, il 1438 processo userà il processore fino al proprio termine, a meno che non ci siano 1439 delle interruzioni). Con l'aggiunta di ``CONFIG_PREEMPT`` nella versione 1440 2.5.4 questo è cambiato: quando si è in contesto utente, processi con una 1441 priorità maggiore possono subentrare nell'esecuzione: gli spinlock furono 1442 cambiati per disabilitare la prelazioni, anche su sistemi monoprocessore. 1443 1444bh 1445 Bottom Half: per ragioni storiche, le funzioni che contengono '_bh' nel 1446 loro nome ora si riferiscono a qualsiasi interruzione software; per esempio, 1447 :c:func:`spin_lock_bh()` blocca qualsiasi interuzione software sul processore 1448 corrente. I *Bottom Halves* sono deprecati, e probabilmente verranno 1449 sostituiti dai tasklet. In un dato momento potrà esserci solo un 1450 *bottom half* in esecuzione. 1451 1452contesto d'interruzione 1453 Non è il contesto utente: qui si processano le interruzioni hardware e 1454 software. La macro :c:func:`in_interrupt()` ritorna vero. 1455 1456contesto utente 1457 Il kernel che esegue qualcosa per conto di un particolare processo (per 1458 esempio una chiamata di sistema) o di un thread del kernel. Potete 1459 identificare il processo con la macro ``current``. Da non confondere 1460 con lo spazio utente. Può essere interrotto sia da interruzioni software 1461 che hardware. 1462 1463interruzione hardware 1464 Richiesta di interruzione hardware. :c:func:`in_irq()` ritorna vero in un 1465 gestore d'interruzioni hardware. 1466 1467interruzione software / softirq 1468 Gestore di interruzioni software: :c:func:`in_irq()` ritorna falso; 1469 :c:func:`in_softirq()` ritorna vero. I tasklet e le softirq sono entrambi 1470 considerati 'interruzioni software'. 1471 1472 In soldoni, un softirq è uno delle 32 interruzioni software che possono 1473 essere eseguite su più processori in contemporanea. A volte si usa per 1474 riferirsi anche ai tasklet (in pratica tutte le interruzioni software). 1475 1476monoprocessore / UP 1477 (Uni-Processor) un solo processore, ovvero non è SMP. (``CONFIG_SMP=n``). 1478 1479multi-processore / SMP 1480 (Symmetric Multi-Processor) kernel compilati per sistemi multi-processore 1481 (``CONFIG_SMP=y``). 1482 1483spazio utente 1484 Un processo che esegue il proprio codice fuori dal kernel. 1485 1486tasklet 1487 Un'interruzione software registrabile dinamicamente che ha la garanzia 1488 d'essere eseguita solo su un processore alla volta. 1489 1490timer 1491 Un'interruzione software registrabile dinamicamente che viene eseguita 1492 (circa) in un determinato momento. Quando è in esecuzione è come un tasklet 1493 (infatti, sono chiamati da ``TIMER_SOFTIRQ``). 1494