Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

doc:it_IT: translation for kernel-hacking

This patch includes the kernel-hacking translation in Italian (both
hacking.rst and locking.rst).

It adds also the anchors for the english kernel-hacking documents.

Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>

authored by

Federico Vaga and committed by
Jonathan Corbet
1497624f c8cce10a

+2369
+2
Documentation/kernel-hacking/hacking.rst
··· 1 + .. _kernel_hacking_hack: 2 + 1 3 ============================================ 2 4 Unreliable Guide To Hacking The Linux Kernel 3 5 ============================================
+2
Documentation/kernel-hacking/locking.rst
··· 1 + .. _kernel_hacking_lock: 2 + 1 3 =========================== 2 4 Unreliable Guide To Locking 3 5 ===========================
+1
Documentation/translations/it_IT/index.rst
··· 87 87 :maxdepth: 2 88 88 89 89 doc-guide/index 90 + kernel-hacking/index 90 91 91 92 .. warning:: 92 93
+855
Documentation/translations/it_IT/kernel-hacking/hacking.rst
··· 1 + .. include:: ../disclaimer-ita.rst 2 + 3 + .. note:: Per leggere la documentazione originale in inglese: 4 + :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>` 5 + 6 + :Original: :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>` 7 + :Translator: Federico Vaga <federico.vaga@vaga.pv.it> 8 + 9 + .. _it_kernel_hacking_hack: 10 + 11 + ================================================= 12 + L'inaffidabile guida all'hacking del kernel Linux 13 + ================================================= 14 + 15 + :Author: Rusty Russell 16 + 17 + Introduzione 18 + ============ 19 + 20 + Benvenuto, gentile lettore, alla notevole ed inaffidabile guida all'hacking 21 + del kernel Linux ad opera di Rusty. Questo documento descrive le procedure 22 + più usate ed i concetti necessari per scrivere codice per il kernel: lo scopo 23 + è di fornire ai programmatori C più esperti un manuale di base per sviluppo. 24 + Eviterò dettagli implementativi: per questo abbiamo il codice, 25 + ed ignorerò intere parti di alcune procedure. 26 + 27 + Prima di leggere questa guida, sappiate che non ho mai voluto scriverla, 28 + essendo esageratamente sotto qualificato, ma ho sempre voluto leggere 29 + qualcosa di simile, e quindi questa era l'unica via. Spero che possa 30 + crescere e diventare un compendio di buone pratiche, punti di partenza 31 + e generiche informazioni. 32 + 33 + Gli attori 34 + ========== 35 + 36 + In qualsiasi momento ognuna delle CPU di un sistema può essere: 37 + 38 + - non associata ad alcun processo, servendo un'interruzione hardware; 39 + 40 + - non associata ad alcun processo, servendo un softirq o tasklet; 41 + 42 + - in esecuzione nello spazio kernel, associata ad un processo 43 + (contesto utente); 44 + 45 + - in esecuzione di un processo nello spazio utente; 46 + 47 + Esiste un ordine fra questi casi. Gli ultimi due possono avvicendarsi (preempt) 48 + l'un l'altro, ma a parte questo esiste una gerarchia rigida: ognuno di questi 49 + può avvicendarsi solo ad uno di quelli sottostanti. Per esempio, mentre un 50 + softirq è in esecuzione su d'una CPU, nessun altro softirq può avvicendarsi 51 + nell'esecuzione, ma un'interruzione hardware può. Ciò nonostante, le altre CPU 52 + del sistema operano indipendentemente. 53 + 54 + Più avanti vedremo alcuni modi in cui dal contesto utente è possibile bloccare 55 + le interruzioni, così da impedirne davvero il diritto di prelazione. 56 + 57 + Contesto utente 58 + --------------- 59 + 60 + Ci si trova nel contesto utente quando si arriva da una chiamata di sistema 61 + od altre eccezioni: come nello spazio utente, altre procedure più importanti, 62 + o le interruzioni, possono far valere il proprio diritto di prelazione sul 63 + vostro processo. Potete sospendere l'esecuzione chiamando :c:func:`schedule()`. 64 + 65 + .. note:: 66 + 67 + Si è sempre in contesto utente quando un modulo viene caricato o rimosso, 68 + e durante le operazioni nello strato dei dispositivi a blocchi 69 + (*block layer*). 70 + 71 + Nel contesto utente, il puntatore ``current`` (il quale indica il processo al 72 + momento in esecuzione) è valido, e :c:func:`in_interrupt()` 73 + (``include/linux/preempt.h``) è falsa. 74 + 75 + .. warning:: 76 + 77 + Attenzione che se avete la prelazione o i softirq disabilitati (vedere 78 + di seguito), :c:func:`in_interrupt()` ritornerà un falso positivo. 79 + 80 + Interruzioni hardware (Hard IRQs) 81 + --------------------------------- 82 + 83 + Temporizzatori, schede di rete e tastiere sono esempi di vero hardware 84 + che possono produrre interruzioni in un qualsiasi momento. Il kernel esegue 85 + i gestori d'interruzione che prestano un servizio all'hardware. Il kernel 86 + garantisce che questi gestori non vengano mai interrotti: se una stessa 87 + interruzione arriva, questa verrà accodata (o scartata). 88 + Dato che durante la loro esecuzione le interruzioni vengono disabilitate, 89 + i gestori d'interruzioni devono essere veloci: spesso si limitano 90 + esclusivamente a notificare la presa in carico dell'interruzione, 91 + programmare una 'interruzione software' per l'esecuzione e quindi terminare. 92 + 93 + Potete dire d'essere in una interruzione hardware perché :c:func:`in_irq()` 94 + ritorna vero. 95 + 96 + .. warning:: 97 + 98 + Attenzione, questa ritornerà un falso positivo se le interruzioni 99 + sono disabilitate (vedere di seguito). 100 + 101 + Contesto d'interruzione software: softirq e tasklet 102 + --------------------------------------------------- 103 + 104 + Quando una chiamata di sistema sta per tornare allo spazio utente, 105 + oppure un gestore d'interruzioni termina, qualsiasi 'interruzione software' 106 + marcata come pendente (solitamente da un'interruzione hardware) viene 107 + eseguita (``kernel/softirq.c``). 108 + 109 + La maggior parte del lavoro utile alla gestione di un'interruzione avviene qui. 110 + All'inizio della transizione ai sistemi multiprocessore, c'erano solo i 111 + cosiddetti 'bottom half' (BH), i quali non traevano alcun vantaggio da questi 112 + sistemi. Non appena abbandonammo i computer raffazzonati con fiammiferi e 113 + cicche, abbandonammo anche questa limitazione e migrammo alle interruzioni 114 + software 'softirqs'. 115 + 116 + Il file ``include/linux/interrupt.h`` elenca i differenti tipi di 'softirq'. 117 + Un tipo di softirq molto importante è il timer (``include/linux/timer.h``): 118 + potete programmarlo per far si che esegua funzioni dopo un determinato 119 + periodo di tempo. 120 + 121 + Dato che i softirq possono essere eseguiti simultaneamente su più di un 122 + processore, spesso diventa estenuante l'averci a che fare. Per questa ragione, 123 + i tasklet (``include/linux/interrupt.h``) vengo usati più di frequente: 124 + possono essere registrati dinamicamente (il che significa che potete averne 125 + quanti ne volete), e garantiscono che un qualsiasi tasklet verrà eseguito 126 + solo su un processore alla volta, sebbene diversi tasklet possono essere 127 + eseguiti simultaneamente. 128 + 129 + .. warning:: 130 + 131 + Il nome 'tasklet' è ingannevole: non hanno niente a che fare 132 + con i 'processi' ('tasks'), e probabilmente hanno più a che vedere 133 + con qualche pessima vodka che Alexey Kuznetsov si fece a quel tempo. 134 + 135 + Potete determinate se siete in un softirq (o tasklet) utilizzando la 136 + macro :c:func:`in_softirq()` (``include/linux/preempt.h``). 137 + 138 + .. warning:: 139 + 140 + State attenti che questa macro ritornerà un falso positivo 141 + se :ref:`botton half lock <it_local_bh_disable>` è bloccato. 142 + 143 + Alcune regole basilari 144 + ====================== 145 + 146 + Nessuna protezione della memoria 147 + Se corrompete la memoria, che sia in contesto utente o d'interruzione, 148 + la macchina si pianterà. Siete sicuri che quello che volete fare 149 + non possa essere fatto nello spazio utente? 150 + 151 + Nessun numero in virgola mobile o MMX 152 + Il contesto della FPU non è salvato; anche se siete in contesto utente 153 + lo stato dell'FPU probabilmente non corrisponde a quello del processo 154 + corrente: vi incasinerete con lo stato di qualche altro processo. Se 155 + volete davvero usare la virgola mobile, allora dovrete salvare e recuperare 156 + lo stato dell'FPU (ed evitare cambi di contesto). Generalmente è una 157 + cattiva idea; usate l'aritmetica a virgola fissa. 158 + 159 + Un limite rigido dello stack 160 + A seconda della configurazione del kernel lo stack è fra 3K e 6K per la 161 + maggior parte delle architetture a 32-bit; è di 14K per la maggior 162 + parte di quelle a 64-bit; e spesso è condiviso con le interruzioni, 163 + per cui non si può usare. 164 + Evitare profonde ricorsioni ad enormi array locali nello stack 165 + (allocateli dinamicamente). 166 + 167 + Il kernel Linux è portabile 168 + Quindi mantenetelo tale. Il vostro codice dovrebbe essere a 64-bit ed 169 + indipendente dall'ordine dei byte (endianess) di un processore. Inoltre, 170 + dovreste minimizzare il codice specifico per un processore; per esempio 171 + il codice assembly dovrebbe essere incapsulato in modo pulito e minimizzato 172 + per facilitarne la migrazione. Generalmente questo codice dovrebbe essere 173 + limitato alla parte di kernel specifica per un'architettura. 174 + 175 + ioctl: non scrivere nuove chiamate di sistema 176 + ============================================= 177 + 178 + Una chiamata di sistema, generalmente, è scritta così:: 179 + 180 + asmlinkage long sys_mycall(int arg) 181 + { 182 + return 0; 183 + } 184 + 185 + Primo, nella maggior parte dei casi non volete creare nuove chiamate di 186 + sistema. 187 + Create un dispositivo a caratteri ed implementate l'appropriata chiamata ioctl. 188 + Questo meccanismo è molto più flessibile delle chiamate di sistema: esso non 189 + dev'essere dichiarato in tutte le architetture nei file 190 + ``include/asm/unistd.h`` e ``arch/kernel/entry.S``; inoltre, è improbabile 191 + che questo venga accettato da Linus. 192 + 193 + Se tutto quello che il vostro codice fa è leggere o scrivere alcuni parametri, 194 + considerate l'implementazione di un'interfaccia :c:func:`sysfs()`. 195 + 196 + All'interno di una ioctl vi trovate nel contesto utente di un processo. Quando 197 + avviene un errore dovete ritornare un valore negativo di errno (consultate 198 + ``include/uapi/asm-generic/errno-base.h``, 199 + ``include/uapi/asm-generic/errno.h`` e ``include/linux/errno.h``), altrimenti 200 + ritornate 0. 201 + 202 + Dopo aver dormito dovreste verificare se ci sono stati dei segnali: il modo 203 + Unix/Linux di gestire un segnale è di uscire temporaneamente dalla chiamata 204 + di sistema con l'errore ``-ERESTARTSYS``. La chiamata di sistema ritornerà 205 + al contesto utente, eseguirà il gestore del segnale e poi la vostra chiamata 206 + di sistema riprenderà (a meno che l'utente non l'abbia disabilitata). Quindi, 207 + dovreste essere pronti per continuare l'esecuzione, per esempio nel mezzo 208 + della manipolazione di una struttura dati. 209 + 210 + :: 211 + 212 + if (signal_pending(current)) 213 + return -ERESTARTSYS; 214 + 215 + Se dovete eseguire dei calcoli molto lunghi: pensate allo spazio utente. 216 + Se **davvero** volete farlo nel kernel ricordatevi di verificare periodicamente 217 + se dovete *lasciare* il processore (ricordatevi che, per ogni processore, c'è 218 + un sistema multi-processo senza diritto di prelazione). 219 + Esempio:: 220 + 221 + cond_resched(); /* Will sleep */ 222 + 223 + Una breve nota sulla progettazione delle interfacce: il motto dei sistemi 224 + UNIX è "fornite meccanismi e non politiche" 225 + 226 + La ricetta per uno stallo 227 + ========================= 228 + 229 + Non è permesso invocare una procedura che potrebbe dormire, fanno eccezione 230 + i seguenti casi: 231 + 232 + - Siete in un contesto utente. 233 + 234 + - Non trattenete alcun spinlock. 235 + 236 + - Avete abilitato le interruzioni (in realtà, Andy Kleen dice che 237 + lo schedulatore le abiliterà per voi, ma probabilmente questo non è quello 238 + che volete). 239 + 240 + Da tener presente che alcune funzioni potrebbero dormire implicitamente: 241 + le più comuni sono quelle per l'accesso allo spazio utente (\*_user) e 242 + quelle per l'allocazione della memoria senza l'opzione ``GFP_ATOMIC`` 243 + 244 + Dovreste sempre compilare il kernel con l'opzione ``CONFIG_DEBUG_ATOMIC_SLEEP`` 245 + attiva, questa vi avviserà se infrangete una di queste regole. 246 + Se **infrangete** le regole, allora potreste bloccare il vostro scatolotto. 247 + 248 + Veramente. 249 + 250 + Alcune delle procedure più comuni 251 + ================================= 252 + 253 + :c:func:`printk()` 254 + ------------------ 255 + 256 + Definita in ``include/linux/printk.h`` 257 + 258 + :c:func:`printk()` fornisce messaggi alla console, dmesg, e al demone syslog. 259 + Essa è utile per il debugging o per la notifica di errori; può essere 260 + utilizzata anche all'interno del contesto d'interruzione, ma usatela con 261 + cautela: una macchina che ha la propria console inondata da messaggi diventa 262 + inutilizzabile. La funzione utilizza un formato stringa quasi compatibile con 263 + la printf ANSI C, e la concatenazione di una stringa C come primo argomento 264 + per indicare la "priorità":: 265 + 266 + printk(KERN_INFO "i = %u\n", i); 267 + 268 + Consultate ``include/linux/kern_levels.h`` per gli altri valori ``KERN_``; 269 + questi sono interpretati da syslog come livelli. Un caso speciale: 270 + per stampare un indirizzo IP usate:: 271 + 272 + __be32 ipaddress; 273 + printk(KERN_INFO "my ip: %pI4\n", &ipaddress); 274 + 275 + 276 + :c:func:`printk()` utilizza un buffer interno di 1K e non s'accorge di 277 + eventuali sforamenti. Accertatevi che vi basti. 278 + 279 + .. note:: 280 + 281 + Saprete di essere un vero hacker del kernel quando inizierete a digitare 282 + nei vostri programmi utenti le printf come se fossero printk :) 283 + 284 + .. note:: 285 + 286 + Un'altra nota a parte: la versione originale di Unix 6 aveva un commento 287 + sopra alla funzione printf: "Printf non dovrebbe essere usata per il 288 + chiacchiericcio". Dovreste seguire questo consiglio. 289 + 290 + :c:func:`copy_to_user()` / :c:func:`copy_from_user()` / :c:func:`get_user()` / :c:func:`put_user()` 291 + --------------------------------------------------------------------------------------------------- 292 + 293 + Definite in ``include/linux/uaccess.h`` / ``asm/uaccess.h`` 294 + 295 + **[DORMONO]** 296 + 297 + :c:func:`put_user()` e :c:func:`get_user()` sono usate per ricevere ed 298 + impostare singoli valori (come int, char, o long) da e verso lo spazio utente. 299 + Un puntatore nello spazio utente non dovrebbe mai essere dereferenziato: i dati 300 + dovrebbero essere copiati usando suddette procedure. Entrambe ritornano 301 + ``-EFAULT`` oppure 0. 302 + 303 + :c:func:`copy_to_user()` e :c:func:`copy_from_user()` sono più generiche: 304 + esse copiano una quantità arbitraria di dati da e verso lo spazio utente. 305 + 306 + .. warning:: 307 + 308 + Al contrario di:c:func:`put_user()` e :c:func:`get_user()`, queste 309 + funzioni ritornano la quantità di dati copiati (0 è comunque un successo). 310 + 311 + [Sì, questa stupida interfaccia mi imbarazza. La battaglia torna in auge anno 312 + dopo anno. --RR] 313 + 314 + Le funzioni potrebbero dormire implicitamente. Queste non dovrebbero mai essere 315 + invocate fuori dal contesto utente (non ha senso), con le interruzioni 316 + disabilitate, o con uno spinlock trattenuto. 317 + 318 + :c:func:`kmalloc()`/:c:func:`kfree()` 319 + ------------------------------------- 320 + 321 + Definite in ``include/linux/slab.h`` 322 + 323 + **[POTREBBERO DORMIRE: LEGGI SOTTO]** 324 + 325 + Queste procedure sono utilizzate per la richiesta dinamica di un puntatore ad 326 + un pezzo di memoria allineato, esattamente come malloc e free nello spazio 327 + utente, ma :c:func:`kmalloc()` ha un argomento aggiuntivo per indicare alcune 328 + opzioni. Le opzioni più importanti sono: 329 + 330 + ``GFP_KERNEL`` 331 + Potrebbe dormire per librarare della memoria. L'opzione fornisce il modo 332 + più affidabile per allocare memoria, ma il suo uso è strettamente limitato 333 + allo spazio utente. 334 + 335 + ``GFP_ATOMIC`` 336 + Non dorme. Meno affidabile di ``GFP_KERNEL``, ma può essere usata in un 337 + contesto d'interruzione. Dovreste avere **davvero** una buona strategia 338 + per la gestione degli errori in caso di mancanza di memoria. 339 + 340 + ``GFP_DMA`` 341 + Alloca memoria per il DMA sul bus ISA nello spazio d'indirizzamento 342 + inferiore ai 16MB. Se non sapete cos'è allora non vi serve. 343 + Molto inaffidabile. 344 + 345 + Se vedete un messaggio d'avviso per una funzione dormiente che viene chiamata 346 + da un contesto errato, allora probabilmente avete usato una funzione 347 + d'allocazione dormiente da un contesto d'interruzione senza ``GFP_ATOMIC``. 348 + Dovreste correggerlo. Sbrigatevi, non cincischiate. 349 + 350 + Se allocate almeno ``PAGE_SIZE``(``asm/page.h`` o ``asm/page_types.h``) byte, 351 + considerate l'uso di :c:func:`__get_free_pages()` (``include/linux/gfp.h``). 352 + Accetta un argomento che definisce l'ordine (0 per per la dimensione di una 353 + pagine, 1 per una doppia pagina, 2 per quattro pagine, eccetra) e le stesse 354 + opzioni d'allocazione viste precedentemente. 355 + 356 + Se state allocando un numero di byte notevolemnte superiore ad una pagina 357 + potete usare :c:func:`vmalloc()`. Essa allocherà memoria virtuale all'interno 358 + dello spazio kernel. Questo è un blocco di memoria fisica non contiguo, ma 359 + la MMU vi darà l'impressione che lo sia (quindi, sarà contiguo solo dal punto 360 + di vista dei processori, non dal punto di vista dei driver dei dispositivi 361 + esterni). 362 + Se per qualche strana ragione avete davvero bisogno di una grossa quantità di 363 + memoria fisica contigua, avete un problema: Linux non ha un buon supporto per 364 + questo caso d'uso perché, dopo un po' di tempo, la frammentazione della memoria 365 + rende l'operazione difficile. Il modo migliore per allocare un simile blocco 366 + all'inizio dell'avvio del sistema è attraverso la procedura 367 + :c:func:`alloc_bootmem()`. 368 + 369 + Prima di inventare la vostra cache per gli oggetti più usati, considerate 370 + l'uso di una cache slab disponibile in ``include/linux/slab.h``. 371 + 372 + :c:func:`current()` 373 + ------------------- 374 + 375 + Definita in ``include/asm/current.h`` 376 + 377 + Questa variabile globale (in realtà una macro) contiene un puntatore alla 378 + struttura del processo corrente, quindi è valido solo dal contesto utente. 379 + Per esempio, quando un processo esegue una chiamata di sistema, questo 380 + punterà alla struttura dati del processo chiamate. 381 + Nel contesto d'interruzione in suo valore **non è NULL**. 382 + 383 + :c:func:`mdelay()`/:c:func:`udelay()` 384 + ------------------------------------- 385 + 386 + Definite in ``include/asm/delay.h`` / ``include/linux/delay.h`` 387 + 388 + Le funzioni :c:func:`udelay()` e :c:func:`ndelay()` possono essere utilizzate 389 + per brevi pause. Non usate grandi valori perché rischiate d'avere un 390 + overflow - in questo contesto la funzione :c:func:`mdelay()` è utile, 391 + oppure considerate :c:func:`msleep()`. 392 + 393 + :c:func:`cpu_to_be32()`/:c:func:`be32_to_cpu()`/:c:func:`cpu_to_le32()`/:c:func:`le32_to_cpu()` 394 + ----------------------------------------------------------------------------------------------- 395 + 396 + Definite in ``include/asm/byteorder.h`` 397 + 398 + La famiglia di funzioni :c:func:`cpu_to_be32()` (dove "32" può essere 399 + sostituito da 64 o 16, e "be" con "le") forniscono un modo generico 400 + per fare conversioni sull'ordine dei byte (endianess): esse ritornano 401 + il valore convertito. Tutte le varianti supportano anche il processo inverso: 402 + :c:func:`be32_to_cpu()`, eccetera. 403 + 404 + Queste funzioni hanno principalmente due varianti: la variante per 405 + puntatori, come :c:func:`cpu_to_be32p(), che prende un puntatore 406 + ad un tipo, e ritorna il valore convertito. L'altra variante per 407 + la famiglia di conversioni "in-situ", come :c:func:`cpu_to_be32s()`, 408 + che convertono il valore puntato da un puntatore, e ritornano void. 409 + 410 + :c:func:`local_irq_save()`/:c:func:`local_irq_restore()` 411 + -------------------------------------------------------- 412 + 413 + Definite in ``include/linux/irqflags.h`` 414 + 415 + Queste funzioni abilitano e disabilitano le interruzioni hardware 416 + sul processore locale. Entrambe sono rientranti; esse salvano lo stato 417 + precedente nel proprio argomento ``unsigned long flags``. Se sapete 418 + che le interruzioni sono abilite, potete semplicemente utilizzare 419 + :c:func:`local_irq_disable()` e :c:func:`local_irq_enable()`. 420 + 421 + .. _it_local_bh_disable: 422 + 423 + :c:func:`local_bh_disable()`/:c:func:`local_bh_enable()` 424 + -------------------------------------------------------- 425 + 426 + Definite in ``include/linux/bottom_half.h`` 427 + 428 + 429 + Queste funzioni abilitano e disabilitano le interruzioni software 430 + sul processore locale. Entrambe sono rientranti; se le interruzioni 431 + software erano già state disabilitate in precedenza, rimarranno 432 + disabilitate anche dopo aver invocato questa coppia di funzioni. 433 + Lo scopo è di prevenire l'esecuzione di softirq e tasklet sul processore 434 + attuale. 435 + 436 + :c:func:`smp_processor_id()` 437 + ---------------------------- 438 + 439 + Definita in ``include/linux/smp.h`` 440 + 441 + :c:func:`get_cpu()` nega il diritto di prelazione (quindi non potete essere 442 + spostati su un altro processore all'improvviso) e ritorna il numero 443 + del processore attuale, fra 0 e ``NR_CPUS``. Da notare che non è detto 444 + che la numerazione dei processori sia continua. Quando avete terminato, 445 + ritornate allo stato precedente con :c:func:`put_cpu()`. 446 + 447 + Se sapete che non dovete essere interrotti da altri processi (per esempio, 448 + se siete in un contesto d'interruzione, o il diritto di prelazione 449 + è disabilitato) potete utilizzare smp_processor_id(). 450 + 451 + 452 + ``__init``/``__exit``/``__initdata`` 453 + ------------------------------------ 454 + 455 + Definite in ``include/linux/init.h`` 456 + 457 + Dopo l'avvio, il kernel libera una sezione speciale; le funzioni marcate 458 + con ``__init`` e le strutture dati marcate con ``__initdata`` vengono 459 + eliminate dopo il completamento dell'avvio: in modo simile i moduli eliminano 460 + questa memoria dopo l'inizializzazione. ``__exit`` viene utilizzato per 461 + dichiarare che una funzione verrà utilizzata solo in fase di rimozione: 462 + la detta funzione verrà eliminata quando il file che la contiene non è 463 + compilato come modulo. Guardate l'header file per informazioni. Da notare che 464 + non ha senso avere una funzione marcata come ``__init`` e al tempo stesso 465 + esportata ai moduli utilizzando :c:func:`EXPORT_SYMBOL()` o 466 + :c:func:`EXPORT_SYMBOL_GPL()` - non funzionerà. 467 + 468 + 469 + :c:func:`__initcall()`/:c:func:`module_init()` 470 + ---------------------------------------------- 471 + 472 + Definite in ``include/linux/init.h`` / ``include/linux/module.h`` 473 + 474 + Molte parti del kernel funzionano bene come moduli (componenti del kernel 475 + caricabili dinamicamente). L'utilizzo delle macro :c:func:`module_init()` 476 + e :c:func:`module_exit()` semplifica la scrittura di codice che può funzionare 477 + sia come modulo, sia come parte del kernel, senza l'ausilio di #ifdef. 478 + 479 + La macro :c:func:`module_init()` definisce quale funzione dev'essere 480 + chiamata quando il modulo viene inserito (se il file è stato compilato come 481 + tale), o in fase di avvio : se il file non è stato compilato come modulo la 482 + macro :c:func:`module_init()` diventa equivalente a :c:func:`__initcall()`, 483 + la quale, tramite qualche magia del linker, s'assicura che la funzione venga 484 + chiamata durante l'avvio. 485 + 486 + La funzione può ritornare un numero d'errore negativo per scatenare un 487 + fallimento del caricamento (sfortunatamente, questo non ha effetto se il 488 + modulo è compilato come parte integrante del kernel). Questa funzione è chiamata 489 + in contesto utente con le interruzioni abilitate, quindi potrebbe dormire. 490 + 491 + 492 + :c:func:`module_exit()` 493 + ----------------------- 494 + 495 + 496 + Definita in ``include/linux/module.h`` 497 + 498 + Questa macro definisce la funzione che dev'essere chiamata al momento della 499 + rimozione (o mai, nel caso in cui il file sia parte integrante del kernel). 500 + Essa verrà chiamata solo quando il contatore d'uso del modulo raggiunge lo 501 + zero. Questa funzione può anche dormire, ma non può fallire: tutto dev'essere 502 + ripulito prima che la funzione ritorni. 503 + 504 + Da notare che questa macro è opzionale: se non presente, il modulo non sarà 505 + removibile (a meno che non usiate 'rmmod -f' ). 506 + 507 + 508 + :c:func:`try_module_get()`/:c:func:`module_put()` 509 + ------------------------------------------------- 510 + 511 + Definite in ``include/linux/module.h`` 512 + 513 + Queste funzioni maneggiano il contatore d'uso del modulo per proteggerlo dalla 514 + rimozione (in aggiunta, un modulo non può essere rimosso se un altro modulo 515 + utilizzo uno dei sui simboli esportati: vedere di seguito). Prima di eseguire 516 + codice del modulo, dovreste chiamare :c:func:`try_module_get()` su quel modulo: 517 + se fallisce significa che il modulo è stato rimosso e dovete agire come se 518 + non fosse presente. Altrimenti, potete accedere al modulo in sicurezza, e 519 + chiamare :c:func:`module_put()` quando avete finito. 520 + 521 + La maggior parte delle strutture registrabili hanno un campo owner 522 + (proprietario), come nella struttura 523 + :c:type:`struct file_operations <file_operations>`. 524 + Impostate questo campo al valore della macro ``THIS_MODULE``. 525 + 526 + 527 + Code d'attesa ``include/linux/wait.h`` 528 + ====================================== 529 + 530 + **[DORMONO]** 531 + 532 + Una coda d'attesa è usata per aspettare che qualcuno vi attivi quando una 533 + certa condizione s'avvera. Per evitare corse critiche, devono essere usate 534 + con cautela. Dichiarate una :c:type:`wait_queue_head_t`, e poi i processi 535 + che vogliono attendere il verificarsi di quella condizione dichiareranno 536 + una :c:type:`wait_queue_entry_t` facendo riferimento a loro stessi, poi 537 + metteranno questa in coda. 538 + 539 + Dichiarazione 540 + ------------- 541 + 542 + Potere dichiarare una ``wait_queue_head_t`` utilizzando la macro 543 + :c:func:`DECLARE_WAIT_QUEUE_HEAD()` oppure utilizzando la procedura 544 + :c:func:`init_waitqueue_head()` nel vostro codice d'inizializzazione. 545 + 546 + Accodamento 547 + ----------- 548 + 549 + Mettersi in una coda d'attesa è piuttosto complesso, perché dovete 550 + mettervi in coda prima di verificare la condizione. Esiste una macro 551 + a questo scopo: :c:func:`wait_event_interruptible()` (``include/linux/wait.h``). 552 + Il primo argomento è la testa della coda d'attesa, e il secondo è 553 + un'espressione che dev'essere valutata; la macro ritorna 0 quando questa 554 + espressione è vera, altrimenti ``-ERESTARTSYS`` se è stato ricevuto un segnale. 555 + La versione :c:func:`wait_event()` ignora i segnali. 556 + 557 + Svegliare una procedura in coda 558 + ------------------------------- 559 + 560 + Chiamate :c:func:`wake_up()` (``include/linux/wait.h``); questa attiverà tutti 561 + i processi in coda. Ad eccezione se uno di questi è impostato come 562 + ``TASK_EXCLUSIVE``, in questo caso i rimanenti non verranno svegliati. 563 + Nello stesso header file esistono altre varianti di questa funzione. 564 + 565 + Operazioni atomiche 566 + =================== 567 + 568 + Certe operazioni sono garantite come atomiche su tutte le piattaforme. 569 + Il primo gruppo di operazioni utilizza :c:type:`atomic_t` 570 + (``include/asm/atomic.h``); questo contiene un intero con segno (minimo 32bit), 571 + e dovete utilizzare queste funzione per modificare o leggere variabili di tipo 572 + :c:type:`atomic_t`. :c:func:`atomic_read()` e :c:func:`atomic_set()` leggono ed 573 + impostano il contatore, :c:func:`atomic_add()`, :c:func:`atomic_sub()`, 574 + :c:func:`atomic_inc()`, :c:func:`atomic_dec()`, e 575 + :c:func:`atomic_dec_and_test()` (ritorna vero se raggiunge zero dopo essere 576 + stata decrementata). 577 + 578 + Sì. Ritorna vero (ovvero != 0) se la variabile atomica è zero. 579 + 580 + Da notare che queste funzioni sono più lente rispetto alla normale aritmetica, 581 + e quindi non dovrebbero essere usate a sproposito. 582 + 583 + Il secondo gruppo di operazioni atomiche sono definite in 584 + ``include/linux/bitops.h`` ed agiscono sui bit d'una variabile di tipo 585 + ``unsigned long``. Queste operazioni prendono come argomento un puntatore 586 + alla variabile, e un numero di bit dove 0 è quello meno significativo. 587 + :c:func:`set_bit()`, :c:func:`clear_bit()` e :c:func:`change_bit()` 588 + impostano, cancellano, ed invertono il bit indicato. 589 + :c:func:`test_and_set_bit()`, :c:func:`test_and_clear_bit()` e 590 + :c:func:`test_and_change_bit()` fanno la stessa cosa, ad eccezione che 591 + ritornano vero se il bit era impostato; queste sono particolarmente 592 + utili quando si vuole impostare atomicamente dei flag. 593 + 594 + Con queste operazioni è possibile utilizzare indici di bit che eccedono 595 + il valore ``BITS_PER_LONG``. Il comportamento è strano sulle piattaforme 596 + big-endian quindi è meglio evitarlo. 597 + 598 + Simboli 599 + ======= 600 + 601 + All'interno del kernel, si seguono le normali regole del linker (ovvero, 602 + a meno che un simbolo non venga dichiarato con visibilita limitata ad un 603 + file con la parola chiave ``static``, esso può essere utilizzato in qualsiasi 604 + parte del kernel). Nonostante ciò, per i moduli, esiste una tabella dei 605 + simboli esportati che limita i punti di accesso al kernel. Anche i moduli 606 + possono esportare simboli. 607 + 608 + :c:func:`EXPORT_SYMBOL()` 609 + ------------------------- 610 + 611 + Definita in ``include/linux/export.h`` 612 + 613 + Questo è il classico metodo per esportare un simbolo: i moduli caricati 614 + dinamicamente potranno utilizzare normalmente il simbolo. 615 + 616 + :c:func:`EXPORT_SYMBOL_GPL()` 617 + ----------------------------- 618 + 619 + Definita in ``include/linux/export.h`` 620 + 621 + Essa è simile a :c:func:`EXPORT_SYMBOL()` ad eccezione del fatto che i 622 + simboli esportati con :c:func:`EXPORT_SYMBOL_GPL()` possono essere 623 + utilizzati solo dai moduli che hanno dichiarato una licenza compatibile 624 + con la GPL attraverso :c:func:`MODULE_LICENSE()`. Questo implica che la 625 + funzione esportata è considerata interna, e non una vera e propria interfaccia. 626 + Alcuni manutentori e sviluppatori potrebbero comunque richiedere 627 + :c:func:`EXPORT_SYMBOL_GPL()` quando si aggiungono nuove funzionalità o 628 + interfacce. 629 + 630 + Procedure e convenzioni 631 + ======================= 632 + 633 + Liste doppiamente concatenate ``include/linux/list.h`` 634 + ------------------------------------------------------ 635 + 636 + Un tempo negli header del kernel c'erano tre gruppi di funzioni per 637 + le liste concatenate, ma questa è stata la vincente. Se non avete particolari 638 + necessità per una semplice lista concatenata, allora questa è una buona scelta. 639 + 640 + In particolare, :c:func:`list_for_each_entry()` è utile. 641 + 642 + Convenzione dei valori di ritorno 643 + --------------------------------- 644 + 645 + Per codice chiamato in contesto utente, è molto comune sfidare le convenzioni 646 + C e ritornare 0 in caso di successo, ed un codice di errore negativo 647 + (eg. ``-EFAULT``) nei casi fallimentari. Questo potrebbe essere controintuitivo 648 + a prima vista, ma è abbastanza diffuso nel kernel. 649 + 650 + Utilizzate :c:func:`ERR_PTR()` (``include/linux/err.h``) per codificare 651 + un numero d'errore negativo in un puntatore, e :c:func:`IS_ERR()` e 652 + :c:func:`PTR_ERR()` per recuperarlo di nuovo: così si evita d'avere un 653 + puntatore dedicato per il numero d'errore. Da brividi, ma in senso positivo. 654 + 655 + Rompere la compilazione 656 + ----------------------- 657 + 658 + Linus e gli altri sviluppatori a volte cambiano i nomi delle funzioni e 659 + delle strutture nei kernel in sviluppo; questo non è solo per tenere 660 + tutti sulle spine: questo riflette cambiamenti fondamentati (eg. la funzione 661 + non può più essere chiamata con le funzioni attive, o fa controlli aggiuntivi, 662 + o non fa più controlli che venivano fatti in precedenza). Solitamente a questo 663 + s'accompagna un'adeguata e completa nota sulla lista di discussone 664 + linux-kernel; cercate negli archivi. 665 + Solitamente eseguire una semplice sostituzione su tutto un file rendere 666 + le cose **peggiori**. 667 + 668 + Inizializzazione dei campi d'una struttura 669 + ------------------------------------------ 670 + 671 + Il metodo preferito per l'inizializzazione delle strutture è quello 672 + di utilizzare gli inizializzatori designati, come definiti nello 673 + standard ISO C99, eg:: 674 + 675 + static struct block_device_operations opt_fops = { 676 + .open = opt_open, 677 + .release = opt_release, 678 + .ioctl = opt_ioctl, 679 + .check_media_change = opt_media_change, 680 + }; 681 + 682 + Questo rende più facile la ricerca con grep, e rende più chiaro quale campo 683 + viene impostato. Dovreste fare così perché si mostra meglio. 684 + 685 + Estensioni GNU 686 + -------------- 687 + 688 + Le estensioni GNU sono esplicitamente permesse nel kernel Linux. Da notare 689 + che alcune delle più complesse non sono ben supportate, per via dello scarso 690 + sviluppo, ma le seguenti sono da considerarsi la norma (per maggiori dettagli, 691 + leggete la sezione "C Extensions" nella pagina info di GCC - Sì, davvero 692 + la pagina info, la pagina man è solo un breve riassunto delle cose nella 693 + pagina info). 694 + 695 + - Funzioni inline 696 + 697 + - Istruzioni in espressioni (ie. il costrutto ({ and }) ). 698 + 699 + - Dichiarate attributi di una funzione / variabile / tipo 700 + (__attribute__) 701 + 702 + - typeof 703 + 704 + - Array con lunghezza zero 705 + 706 + - Macro varargs 707 + 708 + - Aritmentica sui puntatori void 709 + 710 + - Inizializzatori non costanti 711 + 712 + - Istruzioni assembler (non al di fuori di 'arch/' e 'include/asm/') 713 + 714 + - Nomi delle funzioni come stringhe (__func__). 715 + 716 + - __builtin_constant_p() 717 + 718 + Siate sospettosi quando utilizzate long long nel kernel, il codice generato 719 + da gcc è orribile ed anche peggio: le divisioni e le moltiplicazioni non 720 + funzionano sulle piattaforme i386 perché le rispettive funzioni di runtime 721 + di GCC non sono incluse nell'ambiente del kernel. 722 + 723 + C++ 724 + --- 725 + 726 + Solitamente utilizzare il C++ nel kernel è una cattiva idea perché 727 + il kernel non fornisce il necessario ambiente di runtime e gli header file 728 + non sono stati verificati. Rimane comunque possibile, ma non consigliato. 729 + Se davvero volete usarlo, almeno evitate le eccezioni. 730 + 731 + NUMif 732 + ----- 733 + 734 + Viene generalmente considerato più pulito l'uso delle macro negli header file 735 + (o all'inizio dei file .c) per astrarre funzioni piuttosto che utlizzare 736 + l'istruzione di pre-processore \`#if' all'interno del codice sorgente. 737 + 738 + Mettere le vostre cose nel kernel 739 + ================================= 740 + 741 + Al fine d'avere le vostre cose in ordine per l'inclusione ufficiale, o 742 + anche per avere patch pulite, c'è del lavoro amministrativo da fare: 743 + 744 + - Trovare di chi è lo stagno in cui state pisciando. Guardare in cima 745 + ai file sorgenti, all'interno del file ``MAINTAINERS``, ed alla fine 746 + di tutti nel file ``CREDITS``. Dovreste coordinarvi con queste persone 747 + per evitare di duplicare gli sforzi, o provare qualcosa che è già stato 748 + rigettato. 749 + 750 + Assicuratevi di mettere il vostro nome ed indirizzo email in cima a 751 + tutti i file che create o che mangeggiate significativamente. Questo è 752 + il primo posto dove le persone guarderanno quando troveranno un baco, 753 + o quando **loro** vorranno fare una modifica. 754 + 755 + - Solitamente vorrete un'opzione di configurazione per la vostra modifica 756 + al kernel. Modificate ``Kconfig`` nella cartella giusta. Il linguaggio 757 + Config è facile con copia ed incolla, e c'è una completa documentazione 758 + nel file ``Documentation/kbuild/kconfig-language.txt``. 759 + 760 + Nella descrizione della vostra opzione, assicuratevi di parlare sia agli 761 + utenti esperti sia agli utente che non sanno nulla del vostro lavoro. 762 + Menzionate qui le incompatibilità ed i problemi. Chiaramente la 763 + descrizione deve terminare con “if in doubt, say N” (se siete in dubbio, 764 + dite N) (oppure, occasionalmente, \`Y'); questo è per le persone che non 765 + hanno idea di che cosa voi stiate parlando. 766 + 767 + - Modificate il file ``Makefile``: le variabili CONFIG sono esportate qui, 768 + quindi potete solitamente aggiungere una riga come la seguete 769 + "obj-$(CONFIG_xxx) += xxx.o". La sintassi è documentata nel file 770 + ``Documentation/kbuild/makefiles.txt``. 771 + 772 + - Aggiungete voi stessi in ``CREDITS`` se avete fatto qualcosa di notevole, 773 + solitamente qualcosa che supera il singolo file (comunque il vostro nome 774 + dovrebbe essere all'inizio dei file sorgenti). ``MAINTAINERS`` significa 775 + che volete essere consultati quando vengono fatte delle modifiche ad un 776 + sottosistema, e quando ci sono dei bachi; questo implica molto di più 777 + di un semplice impegno su una parte del codice. 778 + 779 + - Infine, non dimenticatevi di leggere 780 + ``Documentation/process/submitting-patches.rst`` e possibilmente anche 781 + ``Documentation/process/submitting-drivers.rst``. 782 + 783 + Trucchetti del kernel 784 + ===================== 785 + 786 + Dopo una rapida occhiata al codice, questi sono i preferiti. Sentitevi liberi 787 + di aggiungerne altri. 788 + 789 + ``arch/x86/include/asm/delay.h``:: 790 + 791 + #define ndelay(n) (__builtin_constant_p(n) ? \ 792 + ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ 793 + __ndelay(n)) 794 + 795 + 796 + ``include/linux/fs.h``:: 797 + 798 + /* 799 + * Kernel pointers have redundant information, so we can use a 800 + * scheme where we can return either an error code or a dentry 801 + * pointer with the same return value. 802 + * 803 + * This should be a per-architecture thing, to allow different 804 + * error and pointer decisions. 805 + */ 806 + #define ERR_PTR(err) ((void *)((long)(err))) 807 + #define PTR_ERR(ptr) ((long)(ptr)) 808 + #define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000)) 809 + 810 + ``arch/x86/include/asm/uaccess_32.h:``:: 811 + 812 + #define copy_to_user(to,from,n) \ 813 + (__builtin_constant_p(n) ? \ 814 + __constant_copy_to_user((to),(from),(n)) : \ 815 + __generic_copy_to_user((to),(from),(n))) 816 + 817 + 818 + ``arch/sparc/kernel/head.S:``:: 819 + 820 + /* 821 + * Sun people can't spell worth damn. "compatability" indeed. 822 + * At least we *know* we can't spell, and use a spell-checker. 823 + */ 824 + 825 + /* Uh, actually Linus it is I who cannot spell. Too much murky 826 + * Sparc assembly will do this to ya. 827 + */ 828 + C_LABEL(cputypvar): 829 + .asciz "compatibility" 830 + 831 + /* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */ 832 + .align 4 833 + C_LABEL(cputypvar_sun4m): 834 + .asciz "compatible" 835 + 836 + 837 + ``arch/sparc/lib/checksum.S:``:: 838 + 839 + /* Sun, you just can't beat me, you just can't. Stop trying, 840 + * give up. I'm serious, I am going to kick the living shit 841 + * out of you, game over, lights out. 842 + */ 843 + 844 + 845 + Ringraziamenti 846 + ============== 847 + 848 + Ringrazio Andi Kleen per le sue idee, le risposte alle mie domande, 849 + le correzioni dei miei errori, l'aggiunta di contenuti, eccetera. 850 + Philipp Rumpf per l'ortografia e per aver reso più chiaro il testo, e 851 + per alcuni eccellenti punti tutt'altro che ovvi. Werner Almesberger 852 + per avermi fornito un ottimo riassunto di :c:func:`disable_irq()`, 853 + e Jes Sorensen e Andrea Arcangeli per le precisazioni. Michael Elizabeth 854 + Chastain per aver verificato ed aggiunto la sezione configurazione. 855 + Telsa Gwynne per avermi insegnato DocBook.
+16
Documentation/translations/it_IT/kernel-hacking/index.rst
··· 1 + .. include:: ../disclaimer-ita.rst 2 + 3 + :Original: :ref:`Documentation/kernel-hacking/index.rst <kernel_hacking>` 4 + :Translator: Federico Vaga <federico.vaga@vaga.pv.it> 5 + 6 + .. _it_kernel_hacking: 7 + 8 + ============================ 9 + Guida all'hacking del kernel 10 + ============================ 11 + 12 + .. toctree:: 13 + :maxdepth: 2 14 + 15 + hacking 16 + locking
+1493
Documentation/translations/it_IT/kernel-hacking/locking.rst
··· 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 + ========================================== 9 + L'inaffidabile guida alla sincronizzazione 10 + ========================================== 11 + 12 + :Author: Rusty Russell 13 + 14 + Introduzione 15 + ============ 16 + 17 + Benvenuto, alla notevole ed inaffidabile guida ai problemi di sincronizzazione 18 + (locking) nel kernel. Questo documento descrive il sistema di sincronizzazione 19 + nel kernel Linux 2.6. 20 + 21 + Dato il largo utilizzo del multi-threading e della prelazione nel kernel 22 + Linux, chiunque voglia dilettarsi col kernel deve conoscere i concetti 23 + fondamentali della concorrenza e della sincronizzazione nei sistemi 24 + multi-processore. 25 + 26 + Il problema con la concorrenza 27 + ============================== 28 + 29 + (Saltatelo se sapete già cos'è una corsa critica). 30 + 31 + In un normale programma, potete incrementare un contatore nel seguente modo: 32 + 33 + :: 34 + 35 + contatore++; 36 + 37 + Questo è 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 + 58 + Questo è 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 + 79 + Corse critiche e sezioni critiche 80 + --------------------------------- 81 + 82 + Questa sovrapposizione, ovvero quando un risultato dipende dal tempo che 83 + intercorre fra processi diversi, è chiamata corsa critica. La porzione 84 + di codice che contiene questo problema è chiamata sezione critica. 85 + In particolar modo da quando Linux ha incominciato a girare su 86 + macchine multi-processore, le sezioni critiche sono diventate uno dei 87 + maggiori problemi di progettazione ed implementazione del kernel. 88 + 89 + La prelazione può sortire gli stessi effetti, anche se c'è una sola CPU: 90 + interrompendo un processo nella sua sezione critica otterremo comunque 91 + la stessa corsa critica. In questo caso, il thread che si avvicenda 92 + nell'esecuzione potrebbe eseguire anch'esso la sezione critica. 93 + 94 + La soluzione è quella di riconoscere quando avvengono questi accessi 95 + simultanei, ed utilizzare i *lock* per accertarsi che solo un'istanza 96 + per volta possa entrare nella sezione critica. Il kernel offre delle buone 97 + funzioni a questo scopo. E poi ci sono quelle meno buone, ma farò finta 98 + che non esistano. 99 + 100 + Sincronizzazione nel kernel Linux 101 + ================================= 102 + 103 + Se posso darvi un suggerimento: non dormite mai con qualcuno più pazzo di 104 + voi. Ma se dovessi darvi un suggerimento sulla sincronizzazione: 105 + **mantenetela semplice**. 106 + 107 + Siate riluttanti nell'introduzione di nuovi *lock*. 108 + 109 + Abbastanza strano, quest'ultimo è l'esatto opposto del mio suggerimento 110 + su quando **avete** dormito con qualcuno più pazzo di voi. E dovreste 111 + pensare a prendervi un cane bello grande. 112 + 113 + I due principali tipi di *lock* nel kernel: spinlock e mutex 114 + ------------------------------------------------------------ 115 + 116 + Ci sono due tipi principali di *lock* nel kernel. Il tipo fondamentale è lo 117 + spinlock (``include/asm/spinlock.h``), un semplice *lock* che può essere 118 + trattenuto solo da un processo: se non si può trattenere lo spinlock, allora 119 + rimane in attesa attiva (in inglese *spinning*) finché non ci riesce. 120 + Gli spinlock sono molto piccoli e rapidi, possono essere utilizzati ovunque. 121 + 122 + Il secondo tipo è il mutex (``include/linux/mutex.h``): è come uno spinlock, 123 + ma potreste bloccarvi trattenendolo. Se non potete trattenere un mutex 124 + il vostro processo si auto-sospenderà; verrà riattivato quando il mutex 125 + verrà rilasciato. Questo significa che il processore potrà occuparsi d'altro 126 + mentre il vostro processo è in attesa. Esistono molti casi in cui non potete 127 + permettervi di sospendere un processo (vedere 128 + :ref:`Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni? <it_sleeping-things>`) 129 + e quindi dovrete utilizzare gli spinlock. 130 + 131 + Nessuno di questi *lock* è ricorsivo: vedere 132 + :ref:`Stallo: semplice ed avanzato <it_deadlock>` 133 + 134 + I *lock* e i kernel per sistemi monoprocessore 135 + ---------------------------------------------- 136 + 137 + Per i kernel compilati senza ``CONFIG_SMP`` e senza ``CONFIG_PREEMPT`` 138 + gli spinlock non esistono. Questa è un'ottima scelta di progettazione: 139 + quando nessun altro processo può essere eseguito in simultanea, allora 140 + non c'è la necessità di avere un *lock*. 141 + 142 + Se il kernel è compilato senza ``CONFIG_SMP`` ma con ``CONFIG_PREEMPT``, 143 + allora gli spinlock disabilitano la prelazione; questo è sufficiente a 144 + prevenire le corse critiche. Nella maggior parte dei casi, possiamo considerare 145 + la prelazione equivalente ad un sistema multi-processore senza preoccuparci 146 + di trattarla indipendentemente. 147 + 148 + Dovreste verificare sempre la sincronizzazione con le opzioni ``CONFIG_SMP`` e 149 + ``CONFIG_PREEMPT`` abilitate, anche quando non avete un sistema 150 + multi-processore, questo vi permetterà di identificare alcuni problemi 151 + di sincronizzazione. 152 + 153 + Come vedremo di seguito, i mutex continuano ad esistere perché sono necessari 154 + per la sincronizzazione fra processi in contesto utente. 155 + 156 + Sincronizzazione in contesto utente 157 + ----------------------------------- 158 + 159 + Se avete una struttura dati che verrà utilizzata solo dal contesto utente, 160 + allora, per proteggerla, potete utilizzare un semplice mutex 161 + (``include/linux/mutex.h``). Questo è il caso più semplice: inizializzate il 162 + mutex; invocate :c:func:`mutex_lock_interruptible()` per trattenerlo e 163 + :c:func:`mutex_unlock()` per rilasciarlo. C'è anche :c:func:`mutex_lock()` 164 + ma questa dovrebbe essere evitata perché non ritorna in caso di segnali. 165 + 166 + Per esempio: ``net/netfilter/nf_sockopt.c`` permette la registrazione 167 + di nuove chiamate per :c:func:`setsockopt()` e :c:func:`getsockopt()` 168 + usando la funzione :c:func:`nf_register_sockopt()`. La registrazione e 169 + la rimozione vengono eseguite solamente quando il modulo viene caricato 170 + o scaricato (e durante l'avvio del sistema, qui non abbiamo concorrenza), 171 + e la lista delle funzioni registrate viene consultata solamente quando 172 + :c:func:`setsockopt()` o :c:func:`getsockopt()` sono sconosciute al sistema. 173 + In questo caso ``nf_sockopt_mutex`` è perfetto allo scopo, in particolar modo 174 + visto che setsockopt e getsockopt potrebbero dormire. 175 + 176 + Sincronizzazione fra il contesto utente e i softirq 177 + --------------------------------------------------- 178 + 179 + Se un softirq condivide dati col contesto utente, avete due problemi. 180 + Primo, il contesto utente corrente potrebbe essere interroto da un softirq, 181 + e secondo, la sezione critica potrebbe essere eseguita da un altro 182 + processore. Questo è quando :c:func:`spin_lock_bh()` 183 + (``include/linux/spinlock.h``) viene utilizzato. Questo disabilita i softirq 184 + sul processore e trattiene il *lock*. Invece, :c:func:`spin_unlock_bh()` fa 185 + l'opposto. (Il suffisso '_bh' è un residuo storico che fa riferimento al 186 + "Bottom Halves", il vecchio nome delle interruzioni software. In un mondo 187 + perfetto questa funzione si chiamerebbe 'spin_lock_softirq()'). 188 + 189 + Da notare che in questo caso potete utilizzare anche :c:func:`spin_lock_irq()` 190 + o :c:func:`spin_lock_irqsave()`, queste fermano anche le interruzioni hardware: 191 + vedere :ref:`Contesto di interruzione hardware <it_hardirq-context>`. 192 + 193 + Questo funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock 194 + svaniscono e questa macro diventa semplicemente :c:func:`local_bh_disable()` 195 + (``include/linux/interrupt.h``), la quale impedisce ai softirq d'essere 196 + eseguiti. 197 + 198 + Sincronizzazione fra contesto utente e i tasklet 199 + ------------------------------------------------ 200 + 201 + Questo caso è uguale al precedente, un tasklet viene eseguito da un softirq. 202 + 203 + Sincronizzazione fra contesto utente e i timer 204 + ---------------------------------------------- 205 + 206 + Anche questo caso è uguale al precedente, un timer viene eseguito da un 207 + softirq. 208 + Dal punto di vista della sincronizzazione, tasklet e timer sono identici. 209 + 210 + Sincronizzazione fra tasklet e timer 211 + ------------------------------------ 212 + 213 + Qualche volta un tasklet od un timer potrebbero condividere i dati con 214 + un altro tasklet o timer 215 + 216 + Lo stesso tasklet/timer 217 + ~~~~~~~~~~~~~~~~~~~~~~~ 218 + 219 + Dato che un tasklet non viene mai eseguito contemporaneamente su due 220 + processori, non dovete preoccuparvi che sia rientrante (ovvero eseguito 221 + più volte in contemporanea), perfino su sistemi multi-processore. 222 + 223 + Differenti tasklet/timer 224 + ~~~~~~~~~~~~~~~~~~~~~~~~ 225 + 226 + Se un altro tasklet/timer vuole condividere dati col vostro tasklet o timer, 227 + allora avrete bisogno entrambe di :c:func:`spin_lock()` e 228 + :c:func:`spin_unlock()`. Qui :c:func:`spin_lock_bh()` è inutile, siete già 229 + in un tasklet ed avete la garanzia che nessun altro verrà eseguito sullo 230 + stesso processore. 231 + 232 + Sincronizzazione fra softirq 233 + ---------------------------- 234 + 235 + Spesso un softirq potrebbe condividere dati con se stesso o un tasklet/timer. 236 + 237 + Lo stesso softirq 238 + ~~~~~~~~~~~~~~~~~ 239 + 240 + Lo stesso softirq può essere eseguito su un diverso processore: allo scopo 241 + di migliorare le prestazioni potete utilizzare dati riservati ad ogni 242 + processore (vedere :ref:`Dati per processore <it_per-cpu>`). Se siete arrivati 243 + fino a questo punto nell'uso dei softirq, probabilmente tenete alla scalabilità 244 + delle prestazioni abbastanza da giustificarne la complessità aggiuntiva. 245 + 246 + Dovete utilizzare :c:func:`spin_lock()` e :c:func:`spin_unlock()` per 247 + proteggere i dati condivisi. 248 + 249 + Diversi Softirqs 250 + ~~~~~~~~~~~~~~~~ 251 + 252 + Dovete utilizzare :c:func:`spin_lock()` e :c:func:`spin_unlock()` per 253 + proteggere i dati condivisi, che siano timer, tasklet, diversi softirq o 254 + lo stesso o altri softirq: uno qualsiasi di essi potrebbe essere in esecuzione 255 + su un diverso processore. 256 + 257 + .. _`it_hardirq-context`: 258 + 259 + Contesto di interruzione hardware 260 + ================================= 261 + 262 + Solitamente le interruzioni hardware comunicano con un tasklet o un softirq. 263 + Spesso questo si traduce nel mettere in coda qualcosa da fare che verrà 264 + preso in carico da un softirq. 265 + 266 + Sincronizzazione fra interruzioni hardware e softirq/tasklet 267 + ------------------------------------------------------------ 268 + 269 + Se un gestore di interruzioni hardware condivide dati con un softirq, allora 270 + avrete due preoccupazioni. Primo, il softirq può essere interrotto da 271 + un'interruzione hardware, e secondo, la sezione critica potrebbe essere 272 + eseguita da un'interruzione hardware su un processore diverso. Questo è il caso 273 + dove :c:func:`spin_lock_irq()` viene utilizzato. Disabilita le interruzioni 274 + sul processore che l'esegue, poi trattiene il lock. :c:func:`spin_unlock_irq()` 275 + fa l'opposto. 276 + 277 + Il gestore d'interruzione hardware non usa :c:func:`spin_lock_irq()` perché 278 + i 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' 280 + più veloce. L'unica eccezione è quando un altro gestore d'interruzioni 281 + hardware utilizza lo stesso *lock*: :c:func:`spin_lock_irq()` impedirà a questo 282 + secondo gestore di interrompere quello in esecuzione. 283 + 284 + Questo funziona alla perfezione anche sui sistemi monoprocessore: gli spinlock 285 + svaniscono e questa macro diventa semplicemente :c:func:`local_irq_disable()` 286 + (``include/asm/smp.h``), la quale impedisce a softirq/tasklet/BH d'essere 287 + eseguiti. 288 + 289 + :c:func:`spin_lock_irqsave()` (``include/linux/spinlock.h``) è una variante che 290 + salva lo stato delle interruzioni in una variabile, questa verrà poi passata 291 + a :c:func:`spin_unlock_irqrestore()`. Questo significa che lo stesso codice 292 + potrà essere utilizzato in un'interruzione hardware (dove le interruzioni sono 293 + già disabilitate) e in un softirq (dove la disabilitazione delle interruzioni 294 + è richiesta). 295 + 296 + Da notare che i softirq (e quindi tasklet e timer) sono eseguiti al ritorno 297 + da un'interruzione hardware, quindi :c:func:`spin_lock_irq()` interrompe 298 + anche questi. Tenuto conto di questo si può dire che 299 + :c:func:`spin_lock_irqsave()` è la funzione di sincronizzazione più generica 300 + e potente. 301 + 302 + Sincronizzazione fra due gestori d'interruzioni hardware 303 + -------------------------------------------------------- 304 + 305 + Condividere dati fra due gestori di interruzione hardware è molto raro, ma se 306 + succede, dovreste usare :c:func:`spin_lock_irqsave()`: è una specificità 307 + dell'architettura il fatto che tutte le interruzioni vengano interrotte 308 + quando si eseguono di gestori di interruzioni. 309 + 310 + Bigino della sincronizzazione 311 + ============================= 312 + 313 + Pete 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 + 326 + Tabella dei requisiti minimi 327 + ---------------------------- 328 + 329 + La tabella seguente illustra i requisiti **minimi** per la sincronizzazione fra 330 + diversi contesti. In alcuni casi, lo stesso contesto può essere eseguito solo 331 + da un processore per volta, quindi non ci sono requisiti per la 332 + sincronizzazione (per esempio, un thread può essere eseguito solo su un 333 + processore alla volta, ma se deve condividere dati con un altro thread, allora 334 + la sincronizzazione è necessaria). 335 + 336 + Ricordatevi il suggerimento qui sopra: potete sempre usare 337 + :c:func:`spin_lock_irqsave()`, che è un sovrainsieme di tutte le altre funzioni 338 + per 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 + ============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== 343 + IRQ Handler A None 344 + IRQ Handler B SLIS None 345 + Softirq A SLI SLI SL 346 + Softirq B SLI SLI SL SL 347 + Tasklet A SLI SLI SL SL None 348 + Tasklet B SLI SLI SL SL SL None 349 + Timer A SLI SLI SL SL SL SL None 350 + Timer B SLI SLI SL SL SL SL SL None 351 + User Context A SLI SLI SLBH SLBH SLBH SLBH SLBH SLBH None 352 + User Context B SLI SLI SLBH SLBH SLBH SLBH SLBH SLBH MLI None 353 + ============== ============= ============= ========= ========= ========= ========= ======= ======= ============== ============== 354 + 355 + Table: 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 + 369 + Table: Legenda per la tabella dei requisiti per la sincronizzazione 370 + 371 + Le funzioni *trylock* 372 + ===================== 373 + 374 + Ci sono funzioni che provano a trattenere un *lock* solo una volta e 375 + ritornano immediatamente comunicato il successo od il fallimento 376 + dell'operazione. Posso essere usate quando non serve accedere ai dati 377 + protetti dal *lock* quando qualche altro thread lo sta già facendo 378 + trattenendo il *lock*. Potrete acquisire il *lock* più tardi se vi 379 + serve accedere ai dati protetti da questo *lock*. 380 + 381 + La funzione :c:func:`spin_trylock()` non ritenta di acquisire il *lock*, 382 + se ci riesce al primo colpo ritorna un valore diverso da zero, altrimenti 383 + se fallisce ritorna 0. Questa funzione può essere utilizzata in un qualunque 384 + contesto, ma come :c:func:`spin_lock()`: dovete disabilitare i contesti che 385 + potrebbero interrompervi e quindi trattenere lo spinlock. 386 + 387 + La funzione :c:func:`mutex_trylock()` invece di sospendere il vostro processo 388 + ritorna un valore diverso da zero se è possibile trattenere il lock al primo 389 + colpo, altrimenti se fallisce ritorna 0. Nonostante non dorma, questa funzione 390 + non può essere usata in modo sicuro in contesti di interruzione hardware o 391 + software. 392 + 393 + Esempi più comuni 394 + ================= 395 + 396 + Guardiamo un semplice esempio: una memoria che associa nomi a numeri. 397 + La memoria tiene traccia di quanto spesso viene utilizzato ogni oggetto; 398 + quando è piena, l'oggetto meno usato viene eliminato. 399 + 400 + Tutto in contesto utente 401 + ------------------------ 402 + 403 + Nel primo esempio, supponiamo che tutte le operazioni avvengano in contesto 404 + utente (in soldoni, da una chiamata di sistema), quindi possiamo dormire. 405 + Questo significa che possiamo usare i mutex per proteggere la nostra memoria 406 + e 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 + strlcpy(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 + 503 + Da notare che ci assicuriamo sempre di trattenere cache_lock quando 504 + aggiungiamo, rimuoviamo od ispezioniamo la memoria: sia la struttura 505 + della memoria che il suo contenuto sono protetti dal *lock*. Questo 506 + caso è semplice dato che copiamo i dati dall'utente e non permettiamo 507 + mai loro di accedere direttamente agli oggetti. 508 + 509 + C'è una piccola ottimizzazione qui: nella funzione :c:func:`cache_add()` 510 + impostiamo i campi dell'oggetto prima di acquisire il *lock*. Questo è 511 + sicuro perché nessun altro potrà accedervi finché non lo inseriremo 512 + nella memoria. 513 + 514 + Accesso dal contesto utente 515 + --------------------------- 516 + 517 + Ora consideriamo il caso in cui :c:func:`cache_find()` può essere invocata 518 + dal contesto d'interruzione: sia hardware che software. Un esempio potrebbe 519 + essere un timer che elimina oggetti dalla memoria. 520 + 521 + Qui di seguito troverete la modifica nel formato *patch*: le righe ``-`` 522 + sono 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 + 586 + Da notare che :c:func:`spin_lock_irqsave()` disabiliterà le interruzioni 587 + se erano attive, altrimenti non farà niente (quando siamo già in un contesto 588 + d'interruzione); dunque queste funzioni possono essere chiamante in 589 + sicurezza da qualsiasi contesto. 590 + 591 + Sfortunatamente, :c:func:`cache_add()` invoca :c:func:`kmalloc()` con 592 + l'opzione ``GFP_KERNEL`` che è permessa solo in contesto utente. Ho supposto 593 + che :c:func:`cache_add()` venga chiamata dal contesto utente, altrimenti 594 + questa opzione deve diventare un parametro di :c:func:`cache_add()`. 595 + 596 + Exposing Objects Outside This File 597 + ---------------------------------- 598 + 599 + Se i vostri oggetti contengono più informazioni, potrebbe non essere 600 + sufficiente copiare i dati avanti e indietro: per esempio, altre parti del 601 + codice potrebbero avere un puntatore a questi oggetti piuttosto che cercarli 602 + ogni volta. Questo introduce due problemi. 603 + 604 + Il primo problema è che utilizziamo ``cache_lock`` per proteggere gli oggetti: 605 + dobbiamo renderlo dinamico così che il resto del codice possa usarlo. Questo 606 + rende la sincronizzazione più complicata dato che non avviene più in un unico 607 + posto. 608 + 609 + Il secondo problema è il problema del ciclo di vita: se un'altra struttura 610 + mantiene un puntatore ad un oggetto, presumibilmente si aspetta che questo 611 + puntatore rimanga valido. Sfortunatamente, questo è garantito solo mentre 612 + si trattiene il *lock*, altrimenti qualcuno potrebbe chiamare 613 + :c:func:`cache_delete()` o peggio, aggiungere un oggetto che riutilizza lo 614 + stesso indirizzo. 615 + 616 + Dato che c'è un solo *lock*, non potete trattenerlo a vita: altrimenti 617 + nessun altro potrà eseguire il proprio lavoro. 618 + 619 + La soluzione a questo problema è l'uso di un contatore di riferimenti: 620 + chiunque punti ad un oggetto deve incrementare il contatore, e decrementarlo 621 + quando il puntatore non viene più usato. Quando il contatore raggiunge lo zero 622 + significa che non è più usato e l'oggetto può essere rimosso. 623 + 624 + Ecco 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 + strlcpy(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 + 712 + Abbiamo incapsulato il contatore di riferimenti nelle tipiche funzioni 713 + di 'get' e 'put'. Ora possiamo ritornare l'oggetto da :c:func:`cache_find()` 714 + col 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 + 717 + Un altro punto da notare è che ho detto che il contatore dovrebbe incrementarsi 718 + per ogni puntatore ad un oggetto: quindi il contatore di riferimenti è 1 719 + quando l'oggetto viene inserito nella memoria. In altre versione il framework 720 + non trattiene un riferimento per se, ma diventa più complicato. 721 + 722 + Usare operazioni atomiche per il contatore di riferimenti 723 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 724 + 725 + In sostanza, :c:type:`atomic_t` viene usato come contatore di riferimenti. 726 + Ci sono un certo numbero di operazioni atomiche definite 727 + in ``include/asm/atomic.h``: queste sono garantite come atomiche su qualsiasi 728 + processore del sistema, quindi non sono necessari i *lock*. In questo caso è 729 + più semplice rispetto all'uso degli spinlock, benché l'uso degli spinlock 730 + sia 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 732 + incremento e decremento, e i *lock* non sono più necessari per proteggere il 733 + contatore 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 + strlcpy(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 + 813 + Proteggere l'oggetto stesso 814 + --------------------------- 815 + 816 + In questo esempio, assumiamo che gli oggetti (ad eccezione del contatore 817 + di riferimenti) non cambino mai dopo la loro creazione. Se vogliamo permettere 818 + al 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 + 830 + Teoricamente, possiamo avere un *lock* per ogni campo e per ogni oggetto. 831 + In 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 + 843 + Qui 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 + 877 + Da notare che ho deciso che il contatore di popolarità dovesse essere 878 + protetto da ``cache_lock`` piuttosto che dal *lock* dell'oggetto; questo 879 + perché è logicamente parte dell'infrastruttura (come 880 + :c:type:`struct list_head <list_head>` nell'oggetto). In questo modo, 881 + in :c:func:`__cache_add()`, non ho bisogno di trattenere il *lock* di ogni 882 + oggetto mentre si cerca il meno popolare. 883 + 884 + Ho anche deciso che il campo id è immutabile, quindi non ho bisogno di 885 + trattenere il lock dell'oggetto quando si usa :c:func:`__cache_find()` 886 + per leggere questo campo; il *lock* dell'oggetto è usato solo dal chiamante 887 + che vuole leggere o scrivere il campo name. 888 + 889 + Inoltre, da notare che ho aggiunto un commento che descrive i dati che sono 890 + protetti dal *lock*. Questo è estremamente importante in quanto descrive il 891 + comportamento del codice, che altrimenti sarebbe di difficile comprensione 892 + leggendo solamente il codice. E come dice Alan Cox: “Lock data, not code”. 893 + 894 + Problemi comuni 895 + =============== 896 + 897 + .. _`it_deadlock`: 898 + 899 + Stallo: semplice ed avanzato 900 + ---------------------------- 901 + 902 + Esiste un tipo di baco dove un pezzo di codice tenta di trattenere uno 903 + spinlock due volte: questo rimarrà in attesa attiva per sempre aspettando che 904 + il *lock* venga rilasciato (in Linux spinlocks, rwlocks e mutex non sono 905 + ricorsivi). 906 + Questo è facile da diagnosticare: non è uno di quei problemi che ti tengono 907 + sveglio 5 notti a parlare da solo. 908 + 909 + Un caso un pochino più complesso; immaginate d'avere una spazio condiviso 910 + fra un softirq ed il contesto utente. Se usate :c:func:`spin_lock()` per 911 + proteggerlo, il contesto utente potrebbe essere interrotto da un softirq 912 + mentre trattiene il lock, da qui il softirq rimarrà in attesa attiva provando 913 + ad acquisire il *lock* già trattenuto nel contesto utente. 914 + 915 + Questi casi sono chiamati stalli (*deadlock*), e come mostrato qui sopra, 916 + può succedere anche con un solo processore (Ma non sui sistemi 917 + monoprocessore perché gli spinlock spariscano quando il kernel è compilato 918 + con ``CONFIG_SMP``\ =n. Nonostante ciò, nel secondo caso avrete comunque 919 + una corruzione dei dati). 920 + 921 + Questi casi sono facili da diagnosticare; sui sistemi multi-processore 922 + il supervisione (*watchdog*) o l'opzione di compilazione ``DEBUG_SPINLOCK`` 923 + (``include/linux/spinlock.h``) permettono di scovare immediatamente quando 924 + succedono. 925 + 926 + Esiste un caso più complesso che è conosciuto come l'abbraccio della morte; 927 + questo coinvolge due o più *lock*. Diciamo che avete un vettore di hash in cui 928 + ogni elemento è uno spinlock a cui è associata una lista di elementi con lo 929 + stesso hash. In un gestore di interruzioni software, dovete modificare un 930 + oggetto e spostarlo su un altro hash; quindi dovrete trattenete lo spinlock 931 + del vecchio hash e di quello nuovo, quindi rimuovere l'oggetto dal vecchio ed 932 + inserirlo nel nuovo. 933 + 934 + Qui abbiamo due problemi. Primo, se il vostro codice prova a spostare un 935 + oggetto all'interno della stessa lista, otterrete uno stallo visto che 936 + tenterà di trattenere lo stesso *lock* due volte. Secondo, se la stessa 937 + interruzione software su un altro processore sta tentando di spostare 938 + un 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 + 948 + Table: Conseguenze 949 + 950 + Entrambe i processori rimarranno in attesa attiva sul *lock* per sempre, 951 + aspettando che l'altro lo rilasci. Sembra e puzza come un blocco totale. 952 + 953 + Prevenire gli stalli 954 + -------------------- 955 + 956 + I libri di testo vi diranno che se trattenete i *lock* sempre nello stesso 957 + ordine non avrete mai un simile stallo. La pratica vi dirà che questo 958 + approccio 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* 960 + si incastrerà. 961 + 962 + I *lock* migliori sono quelli incapsulati: non vengono esposti nei file di 963 + intestazione, e non vengono mai trattenuti fuori dallo stesso file. Potete 964 + rileggere questo codice e vedere che non ci sarà mai uno stallo perché 965 + non tenterà mai di trattenere un altro *lock* quando lo ha già. 966 + Le persone che usano il vostro codice non devono nemmeno sapere che voi 967 + state usando dei *lock*. 968 + 969 + Un classico problema deriva dall'uso di *callback* e di *hook*: se li 970 + chiamate mentre trattenete un *lock*, rischiate uno stallo o un abbraccio 971 + della morte (chi lo sa cosa farà una *callback*?). 972 + 973 + Ossessiva prevenzione degli stalli 974 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 975 + 976 + Gli stalli sono un problema, ma non così terribile come la corruzione dei dati. 977 + Un pezzo di codice trattiene un *lock* di lettura, cerca in una lista, 978 + fallisce nel trovare quello che vuole, quindi rilascia il *lock* di lettura, 979 + trattiene un *lock* di scrittura ed inserisce un oggetto; questo genere di 980 + codice presenta una corsa critica. 981 + 982 + Se non riuscite a capire il perché, per favore state alla larga dal mio 983 + codice. 984 + 985 + corsa fra temporizzatori: un passatempo del kernel 986 + -------------------------------------------------- 987 + 988 + I temporizzatori potrebbero avere dei problemi con le corse critiche. 989 + Considerate una collezione di oggetti (liste, hash, eccetera) dove ogni oggetto 990 + ha un temporizzatore che sta per distruggerlo. 991 + 992 + Se volete eliminare l'intera collezione (diciamo quando rimuovete un modulo), 993 + potreste 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 + 1008 + Primo o poi, questo esploderà su un sistema multiprocessore perché un 1009 + temporizzatore potrebbe essere già partiro prima di :c:func:`spin_lock_bh()`, 1010 + e prenderà il *lock* solo dopo :c:func:`spin_unlock_bh()`, e cercherà 1011 + di eliminare il suo oggetto (che però è già stato eliminato). 1012 + 1013 + Questo può essere evitato controllando il valore di ritorno di 1014 + :c:func:`del_timer()`: se ritorna 1, il temporizzatore è stato già 1015 + rimosso. Se 0, significa (in questo caso) che il temporizzatore è in 1016 + esecuzione, 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 + 1034 + Un altro problema è l'eliminazione dei temporizzatori che si riavviano 1035 + da soli (chiamando :c:func:`add_timer()` alla fine della loro esecuzione). 1036 + Dato che questo è un problema abbastanza comune con una propensione 1037 + alle corse critiche, dovreste usare :c:func:`del_timer_sync()` 1038 + (``include/linux/timer.h``) per gestire questo caso. Questa ritorna il 1039 + numero di volte che il temporizzatore è stato interrotto prima che 1040 + fosse in grado di fermarlo senza che si riavviasse. 1041 + 1042 + Velocità della sincronizzazione 1043 + =============================== 1044 + 1045 + Ci sono tre cose importanti da tenere in considerazione quando si valuta 1046 + la velocità d'esecuzione di un pezzo di codice che necessita di 1047 + sincronizzazione. La prima è la concorrenza: quante cose rimangono in attesa 1048 + mentre qualcuno trattiene un *lock*. La seconda è il tempo necessario per 1049 + acquisire (senza contese) e rilasciare un *lock*. La terza è di usare meno 1050 + *lock* o di più furbi. Immagino che i *lock* vengano usati regolarmente, 1051 + altrimenti, non sareste interessati all'efficienza. 1052 + 1053 + La concorrenza dipende da quanto a lungo un *lock* è trattenuto: dovreste 1054 + trattenere un *lock* solo il tempo minimo necessario ma non un istante in più. 1055 + Nella memoria dell'esempio precedente, creiamo gli oggetti senza trattenere 1056 + il *lock*, poi acquisiamo il *lock* quando siamo pronti per inserirlo nella 1057 + lista. 1058 + 1059 + Il tempo di acquisizione di un *lock* dipende da quanto danno fa 1060 + l'operazione sulla *pipeline* (ovvero stalli della *pipeline*) e quant'è 1061 + probabile che il processore corrente sia stato anche l'ultimo ad acquisire 1062 + il *lock* (in pratica, il *lock* è nella memoria cache del processore 1063 + corrente?): su sistemi multi-processore questa probabilità precipita 1064 + rapidamente. Consideriamo un processore Intel Pentium III a 700Mhz: questo 1065 + esegue un'istruzione in 0.7ns, un incremento atomico richiede 58ns, acquisire 1066 + un *lock* che è nella memoria cache del processore richiede 160ns, e un 1067 + trasferimento dalla memoria cache di un altro processore richiede altri 1068 + 170/360ns (Leggetevi l'articolo di Paul McKenney's `Linux Journal RCU 1069 + article <http://www.linuxjournal.com/article.php?sid=6993>`__). 1070 + 1071 + Questi due obiettivi sono in conflitto: trattenere un *lock* per il minor 1072 + tempo possibile potrebbe richiedere la divisione in più *lock* per diverse 1073 + parti (come nel nostro ultimo esempio con un *lock* per ogni oggetto), 1074 + ma questo aumenta il numero di acquisizioni di *lock*, ed il risultato 1075 + spesso è che tutto è più lento che con un singolo *lock*. Questo è un altro 1076 + argomento in favore della semplicità quando si parla di sincronizzazione. 1077 + 1078 + Il terzo punto è discusso di seguito: ci sono alcune tecniche per ridurre 1079 + il numero di sincronizzazioni che devono essere fatte. 1080 + 1081 + Read/Write Lock Variants 1082 + ------------------------ 1083 + 1084 + Sia 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>`. 1086 + Queste dividono gli utenti in due categorie: i lettori e gli scrittori. 1087 + Se state solo leggendo i dati, potete acquisire il *lock* di lettura, ma 1088 + per scrivere avrete bisogno del *lock* di scrittura. Molti possono trattenere 1089 + il *lock* di lettura, ma solo uno scrittore alla volta può trattenere 1090 + quello di scrittura. 1091 + 1092 + Se il vostro codice si divide chiaramente in codice per lettori e codice 1093 + per scrittori (come nel nostro esempio), e il *lock* dei lettori viene 1094 + trattenuto per molto tempo, allora l'uso di questo tipo di *lock* può aiutare. 1095 + Questi sono leggermente più lenti rispetto alla loro versione normale, quindi 1096 + nella pratica l'uso di ``rwlock_t`` non ne vale la pena. 1097 + 1098 + Evitare i *lock*: Read Copy Update 1099 + -------------------------------------------- 1100 + 1101 + Esiste un metodo di sincronizzazione per letture e scritture detto 1102 + Read Copy Update. Con l'uso della tecnica RCU, i lettori possono scordarsi 1103 + completamente di trattenere i *lock*; dato che nel nostro esempio ci 1104 + aspettiamo d'avere più lettore che scrittori (altrimenti questa memoria 1105 + sarebbe uno spreco) possiamo dire che questo meccanismo permette 1106 + un'ottimizzazione. 1107 + 1108 + Come facciamo a sbarazzarci dei *lock* di lettura? Sbarazzarsi dei *lock* di 1109 + lettura significa che uno scrittore potrebbe cambiare la lista sotto al naso 1110 + dei lettori. Questo è abbastanza semplice: possiamo leggere una lista 1111 + concatenata se lo scrittore aggiunge elementi alla fine e con certe 1112 + precauzioni. Per esempio, aggiungendo ``new`` ad una lista concatenata 1113 + chiamata ``list``:: 1114 + 1115 + new->next = list->next; 1116 + wmb(); 1117 + list->next = new; 1118 + 1119 + La funzione :c:func:`wmb()` è una barriera di sincronizzazione delle 1120 + scritture. Questa garantisce che la prima operazione (impostare l'elemento 1121 + ``next`` del nuovo elemento) venga completata e vista da tutti i processori 1122 + prima che venga eseguita la seconda operazione (che sarebbe quella di mettere 1123 + il nuovo elemento nella lista). Questo è importante perché i moderni 1124 + compilatori ed i moderni processori possono, entrambe, riordinare le istruzioni 1125 + se non vengono istruiti altrimenti: vogliamo che i lettori non vedano 1126 + completamente il nuovo elemento; oppure che lo vedano correttamente e quindi 1127 + il puntatore ``next`` deve puntare al resto della lista. 1128 + 1129 + Fortunatamente, 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 + 1133 + Rimuovere un elemento dalla lista è anche più facile: sostituiamo il puntatore 1134 + al vecchio elemento con quello del suo successore, e i lettori vedranno 1135 + l'elemento o lo salteranno. 1136 + 1137 + :: 1138 + 1139 + list->next = old->next; 1140 + 1141 + La funzione :c:func:`list_del_rcu()` (``include/linux/list.h``) fa esattamente 1142 + questo (la versione normale corrompe il vecchio oggetto, e non vogliamo che 1143 + accada). 1144 + 1145 + Anche i lettori devono stare attenti: alcuni processori potrebbero leggere 1146 + attraverso il puntatore ``next`` il contenuto dell'elemento successivo 1147 + troppo presto, ma non accorgersi che il contenuto caricato è sbagliato quando 1148 + il puntatore ``next`` viene modificato alla loro spalle. Ancora una volta 1149 + c'è 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 1152 + in contemporanea. 1153 + 1154 + Il nostro ultimo dilemma è il seguente: quando possiamo realmente distruggere 1155 + l'elemento rimosso? Ricordate, un lettore potrebbe aver avuto accesso a questo 1156 + elemento proprio ora: se eliminiamo questo elemento ed il puntatore ``next`` 1157 + cambia, il lettore salterà direttamente nella spazzatura e scoppierà. Dobbiamo 1158 + aspettare finché tutti i lettori che stanno attraversando la lista abbiano 1159 + finito. Utilizziamo :c:func:`call_rcu()` per registrare una funzione di 1160 + richiamo che distrugga l'oggetto quando tutti i lettori correnti hanno 1161 + terminato. In alternative, potrebbe essere usata la funzione 1162 + :c:func:`synchronize_rcu()` che blocca l'esecuzione finché tutti i lettori 1163 + non terminano di ispezionare la lista. 1164 + 1165 + Ma come fa l'RCU a sapere quando i lettori sono finiti? Il meccanismo è 1166 + il 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 1168 + prelazione così che i lettori non vengano sospesi mentre stanno leggendo 1169 + la lista. 1170 + 1171 + Poi, l'RCU aspetta finché tutti i processori non abbiano dormito almeno 1172 + una volta; a questo punto, dato che i lettori non possono dormire, possiamo 1173 + dedurre che un qualsiasi lettore che abbia consultato la lista durante la 1174 + rimozione abbia già terminato, quindi la *callback* viene eseguita. Il vero 1175 + codice 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 + 1255 + Da notare che i lettori modificano il campo popularity nella funzione 1256 + :c:func:`__cache_find()`, e ora non trattiene alcun *lock*. Una soluzione 1257 + potrebbe essere quella di rendere la variabile ``atomic_t``, ma per l'uso 1258 + che ne abbiamo fatto qui, non ci interessano queste corse critiche perché un 1259 + risultato approssimativo è comunque accettabile, quindi non l'ho cambiato. 1260 + 1261 + Il risultato è che la funzione :c:func:`cache_find()` non ha bisogno di alcuna 1262 + sincronizzazione con le altre funzioni, quindi è veloce su un sistema 1263 + multi-processore tanto quanto lo sarebbe su un sistema mono-processore. 1264 + 1265 + Esiste un'ulteriore ottimizzazione possibile: vi ricordate il codice originale 1266 + della nostra memoria dove non c'erano contatori di riferimenti e il chiamante 1267 + semplicemente tratteneva il *lock* prima di accedere ad un oggetto? Questo è 1268 + ancora possibile: se trattenete un *lock* nessuno potrà cancellare l'oggetto, 1269 + quindi non avete bisogno di incrementare e decrementare il contatore di 1270 + riferimenti. 1271 + 1272 + Ora, dato che il '*lock* di lettura' di un RCU non fa altro che disabilitare 1273 + la prelazione, un chiamante che ha sempre la prelazione disabilitata fra le 1274 + chiamate :c:func:`cache_find()` e :c:func:`object_put()` non necessita 1275 + di incrementare e decrementare il contatore di riferimenti. Potremmo 1276 + esporre la funzione :c:func:`__cache_find()` dichiarandola non-static, 1277 + e quel chiamante potrebbe usare direttamente questa funzione. 1278 + 1279 + Il beneficio qui sta nel fatto che il contatore di riferimenti no 1280 + viene scritto: l'oggetto non viene alterato in alcun modo e quindi diventa 1281 + molto più veloce su sistemi molti-processore grazie alla loro memoria cache. 1282 + 1283 + .. _`it_per-cpu`: 1284 + 1285 + Dati per processore 1286 + ------------------- 1287 + 1288 + Un'altra tecnica comunemente usata per evitare la sincronizzazione è quella 1289 + di duplicare le informazioni per ogni processore. Per esempio, se volete 1290 + avere un contatore di qualcosa, potreste utilizzare uno spinlock ed un 1291 + singolo contatore. Facile e pulito. 1292 + 1293 + Se questo dovesse essere troppo lento (solitamente non lo è, ma se avete 1294 + dimostrato che lo è devvero), potreste usare un contatore per ogni processore 1295 + e 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 + 1299 + Il tipo di dato ``local_t``, la funzione :c:func:`cpu_local_inc()` e tutte 1300 + le altre funzioni associate, sono di particolare utilità per semplici contatori 1301 + per-processore; su alcune architetture sono anche più efficienti 1302 + (``include/asm/local.h``). 1303 + 1304 + Da notare che non esiste un modo facile ed affidabile per ottenere il valore 1305 + di un simile contatore senza introdurre altri *lock*. In alcuni casi questo 1306 + non è un problema. 1307 + 1308 + Dati che sono usati prevalentemente dai gestori d'interruzioni 1309 + -------------------------------------------------------------- 1310 + 1311 + Se i dati vengono utilizzati sempre dallo stesso gestore d'interruzioni, 1312 + allora i *lock* non vi servono per niente: il kernel già vi garantisce che 1313 + il gestore d'interruzione non verrà eseguito in contemporanea su diversi 1314 + processori. 1315 + 1316 + Manfred Spraul fa notare che potreste comunque comportarvi così anche 1317 + se i dati vengono occasionalmente utilizzati da un contesto utente o 1318 + da 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 + 1327 + La funzione :c:func:`disable_irq()` impedisce al gestore d'interruzioni 1328 + d'essere eseguito (e aspetta che finisca nel caso fosse in esecuzione su 1329 + un altro processore). Lo spinlock, invece, previene accessi simultanei. 1330 + Naturalmente, 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 + 1336 + Quali funzioni possono essere chiamate in modo sicuro dalle interruzioni? 1337 + ========================================================================= 1338 + 1339 + Molte funzioni del kernel dormono (in sostanza, chiamano ``schedule()``) 1340 + direttamente od indirettamente: non potete chiamarle se trattenere uno 1341 + spinlock o avete la prelazione disabilitata, mai. Questo significa che 1342 + dovete necessariamente essere nel contesto utente: chiamarle da un 1343 + contesto d'interruzione è illegale. 1344 + 1345 + Alcune funzioni che dormono 1346 + --------------------------- 1347 + 1348 + Le più comuni sono elencate qui di seguito, ma solitamente dovete leggere 1349 + il codice per scoprire se altre chiamate sono sicure. Se chiunque altro 1350 + le chiami dorme, allora dovreste poter dormire anche voi. In particolar 1351 + modo, le funzioni di registrazione e deregistrazione solitamente si 1352 + aspettano d'essere chiamante da un contesto utente e quindi che possono 1353 + dormire. 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 + 1377 + Alcune funzioni che non dormono 1378 + ------------------------------- 1379 + 1380 + Alcune funzioni possono essere chiamate tranquillamente da qualsiasi 1381 + contesto, 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 + 1389 + Riferimento 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 + 1398 + Riferimento per l'API dei Futex 1399 + =============================== 1400 + 1401 + .. kernel-doc:: kernel/futex.c 1402 + :internal: 1403 + 1404 + Approfondimenti 1405 + =============== 1406 + 1407 + - ``Documentation/locking/spinlocks.txt``: 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 + 1419 + Ringraziamenti 1420 + ============== 1421 + 1422 + Grazie a Telsa Gwynne per aver formattato questa guida in DocBook, averla 1423 + pulita e aggiunto un po' di stile. 1424 + 1425 + Grazie a Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul Mackerras, 1426 + Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim Waugh, Pete Zaitcev, 1427 + James Morris, Robert Love, Paul McKenney, John Ashby per aver revisionato, 1428 + corretto, maledetto e commentato. 1429 + 1430 + Grazie alla congrega per non aver avuto alcuna influenza su questo documento. 1431 + 1432 + Glossario 1433 + ========= 1434 + 1435 + prelazione 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 + 1444 + bh 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 + 1452 + contesto 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 + 1456 + contesto 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 + 1463 + interruzione hardware 1464 + Richiesta di interruzione hardware. :c:func:`in_irq()` ritorna vero in un 1465 + gestore d'interruzioni hardware. 1466 + 1467 + interruzione 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 + 1476 + monoprocessore / UP 1477 + (Uni-Processor) un solo processore, ovvero non è SMP. (``CONFIG_SMP=n``). 1478 + 1479 + multi-processore / SMP 1480 + (Symmetric Multi-Processor) kernel compilati per sistemi multi-processore 1481 + (``CONFIG_SMP=y``). 1482 + 1483 + spazio utente 1484 + Un processo che esegue il proprio codice fuori dal kernel. 1485 + 1486 + tasklet 1487 + Un'interruzione software registrabile dinamicamente che ha la garanzia 1488 + d'essere eseguita solo su un processore alla volta. 1489 + 1490 + timer 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``).