xref: /openbmc/linux/Documentation/translations/it_IT/process/volatile-considered-harmful.rst (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1edba5eecSFederico Vaga.. include:: ../disclaimer-ita.rst
2edba5eecSFederico Vaga
3edba5eecSFederico Vaga:Original: :ref:`Documentation/process/volatile-considered-harmful.rst <volatile_considered_harmful>`
4edba5eecSFederico Vaga:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
5edba5eecSFederico Vaga
6edba5eecSFederico Vaga.. _it_volatile_considered_harmful:
7edba5eecSFederico Vaga
8edba5eecSFederico VagaPerché la parola chiave "volatile" non dovrebbe essere usata
9edba5eecSFederico Vaga------------------------------------------------------------
10edba5eecSFederico Vaga
11edba5eecSFederico VagaSpesso i programmatori C considerano volatili quelle variabili che potrebbero
12edba5eecSFederico Vagaessere cambiate al di fuori dal thread di esecuzione corrente; come risultato,
13edba5eecSFederico Vagaa volte saranno tentati dall'utilizzare *volatile* nel kernel per le
14edba5eecSFederico Vagastrutture dati condivise.  In altre parole, gli è stato insegnato ad usare
15edba5eecSFederico Vaga*volatile* come una variabile atomica di facile utilizzo, ma non è così.
16edba5eecSFederico VagaL'uso di *volatile* nel kernel non è quasi mai corretto; questo documento ne
17edba5eecSFederico Vagadescrive le ragioni.
18edba5eecSFederico Vaga
19edba5eecSFederico VagaIl punto chiave da capire su *volatile* è che il suo scopo è quello di
20edba5eecSFederico Vagasopprimere le ottimizzazioni, che non è quasi mai quello che si vuole.
21edba5eecSFederico VagaNel kernel si devono proteggere le strutture dati condivise contro accessi
22edba5eecSFederico Vagaconcorrenti e indesiderati: questa è un'attività completamente diversa.
23edba5eecSFederico VagaIl processo di protezione contro gli accessi concorrenti indesiderati eviterà
24edba5eecSFederico Vagaanche la maggior parte dei problemi relativi all'ottimizzazione in modo più
25edba5eecSFederico Vagaefficiente.
26edba5eecSFederico Vaga
27edba5eecSFederico VagaCome *volatile*, le primitive del kernel che rendono sicuro l'accesso ai dati
28edba5eecSFederico Vaga(spinlock, mutex, barriere di sincronizzazione, ecc) sono progettate per
29edba5eecSFederico Vagaprevenire le ottimizzazioni indesiderate.  Se vengono usate opportunamente,
30edba5eecSFederico Vaganon ci sarà bisogno di utilizzare *volatile*.  Se vi sembra che *volatile* sia
31edba5eecSFederico Vagacomunque necessario, ci dev'essere quasi sicuramente un baco da qualche parte.
32edba5eecSFederico VagaIn un pezzo di codice kernel scritto a dovere, *volatile* può solo servire a
33edba5eecSFederico Vagarallentare le cose.
34edba5eecSFederico Vaga
35edba5eecSFederico VagaConsiderate questo tipico blocco di codice kernel::
36edba5eecSFederico Vaga
37edba5eecSFederico Vaga    spin_lock(&the_lock);
38edba5eecSFederico Vaga    do_something_on(&shared_data);
39edba5eecSFederico Vaga    do_something_else_with(&shared_data);
40edba5eecSFederico Vaga    spin_unlock(&the_lock);
41edba5eecSFederico Vaga
42edba5eecSFederico VagaSe tutto il codice seguisse le regole di sincronizzazione, il valore di un
43edba5eecSFederico Vagadato condiviso non potrebbe cambiare inaspettatamente mentre si trattiene un
44edba5eecSFederico Vagalock.  Un qualsiasi altro blocco di codice che vorrà usare quel dato rimarrà
45edba5eecSFederico Vagain attesa del lock.  Gli spinlock agiscono come barriere di sincronizzazione
46edba5eecSFederico Vaga- sono stati esplicitamente scritti per agire così - il che significa che gli
47edba5eecSFederico Vagaaccessi al dato condiviso non saranno ottimizzati.  Quindi il compilatore
48edba5eecSFederico Vagapotrebbe pensare di sapere cosa ci sarà nel dato condiviso ma la chiamata
49edba5eecSFederico Vagaspin_lock(), che agisce come una barriera di sincronizzazione, gli imporrà di
50edba5eecSFederico Vagadimenticarsi tutto ciò che sapeva su di esso.
51edba5eecSFederico Vaga
52edba5eecSFederico VagaSe il dato condiviso fosse stato dichiarato come *volatile*, la
53edba5eecSFederico Vagasincronizzazione rimarrebbe comunque necessaria.  Ma verrà impedito al
54edba5eecSFederico Vagacompilatore di ottimizzare gli accessi al dato anche _dentro_ alla sezione
55edba5eecSFederico Vagacritica, dove sappiamo che in realtà nessun altro può accedervi.  Mentre si
56edba5eecSFederico Vagatrattiene un lock, il dato condiviso non è *volatile*.  Quando si ha a che
57edba5eecSFederico Vagafare con dei dati condivisi, un'opportuna sincronizzazione rende inutile
58edba5eecSFederico Vagal'uso di *volatile* - anzi potenzialmente dannoso.
59edba5eecSFederico Vaga
60edba5eecSFederico VagaL'uso di *volatile* fu originalmente pensato per l'accesso ai registri di I/O
61edba5eecSFederico Vagamappati in memoria.  All'interno del kernel, l'accesso ai registri, dovrebbe
62edba5eecSFederico Vagaessere protetto dai lock, ma si potrebbe anche desiderare che il compilatore
63edba5eecSFederico Vaganon "ottimizzi" l'accesso ai registri all'interno di una sezione critica.
64edba5eecSFederico VagaMa, all'interno del kernel, l'accesso alla memoria di I/O viene sempre fatto
65edba5eecSFederico Vagaattraverso funzioni d'accesso; accedere alla memoria di I/O direttamente
66edba5eecSFederico Vagacon i puntatori è sconsigliato e non funziona su tutte le architetture.
67edba5eecSFederico VagaQueste funzioni d'accesso sono scritte per evitare ottimizzazioni indesiderate,
68edba5eecSFederico Vagaquindi, di nuovo, *volatile* è inutile.
69edba5eecSFederico Vaga
70edba5eecSFederico VagaUn'altra situazione dove qualcuno potrebbe essere tentato dall'uso di
71edba5eecSFederico Vaga*volatile*, è nel caso in cui il processore è in un'attesa attiva sul valore
72edba5eecSFederico Vagadi una variabile.  Il modo giusto di fare questo tipo di attesa è il seguente::
73edba5eecSFederico Vaga
74edba5eecSFederico Vaga    while (my_variable != what_i_want)
75edba5eecSFederico Vaga        cpu_relax();
76edba5eecSFederico Vaga
77edba5eecSFederico VagaLa chiamata cpu_relax() può ridurre il consumo di energia del processore
78edba5eecSFederico Vagao cedere il passo ad un processore hyperthreaded gemello; funziona anche come
79edba5eecSFederico Vagauna barriera per il compilatore, quindi, ancora una volta, *volatile* non è
80edba5eecSFederico Vaganecessario.  Ovviamente, tanto per puntualizzare, le attese attive sono
81edba5eecSFederico Vagageneralmente un atto antisociale.
82edba5eecSFederico Vaga
83edba5eecSFederico VagaCi sono comunque alcune rare situazioni dove l'uso di *volatile* nel kernel
84edba5eecSFederico Vagaha senso:
85edba5eecSFederico Vaga
86edba5eecSFederico Vaga  - Le funzioni d'accesso sopracitate potrebbero usare *volatile* su quelle
87edba5eecSFederico Vaga    architetture che supportano l'accesso diretto alla memoria di I/O.
88edba5eecSFederico Vaga    In pratica, ogni chiamata ad una funzione d'accesso diventa una piccola
89edba5eecSFederico Vaga    sezione critica a se stante, e garantisce che l'accesso avvenga secondo
90edba5eecSFederico Vaga    le aspettative del programmatore.
91edba5eecSFederico Vaga
92edba5eecSFederico Vaga  - I codice *inline assembly* che fa cambiamenti nella memoria, ma che non
93edba5eecSFederico Vaga    ha altri effetti espliciti, rischia di essere rimosso da GCC.  Aggiungere
94edba5eecSFederico Vaga    la parola chiave *volatile* a questo codice ne previene la rimozione.
95edba5eecSFederico Vaga
96edba5eecSFederico Vaga  - La variabile jiffies è speciale in quanto assume un valore diverso ogni
97edba5eecSFederico Vaga    volta che viene letta ma può essere lette senza alcuna sincronizzazione.
98edba5eecSFederico Vaga    Quindi jiffies può essere *volatile*, ma l'aggiunta ad altre variabili di
99edba5eecSFederico Vaga    questo è sconsigliata.  Jiffies è considerata uno "stupido retaggio"
100edba5eecSFederico Vaga    (parole di Linus) in questo contesto; correggerla non ne varrebbe la pena e
101edba5eecSFederico Vaga    causerebbe più problemi.
102edba5eecSFederico Vaga
103edba5eecSFederico Vaga  - I puntatori a delle strutture dati in una memoria coerente che potrebbe
104edba5eecSFederico Vaga    essere modificata da dispositivi di I/O può, a volte, essere legittimamente
105edba5eecSFederico Vaga    *volatile*.  Un esempio pratico può essere quello di un adattatore di rete
106edba5eecSFederico Vaga    che utilizza un puntatore ad un buffer circolare, questo viene cambiato
107edba5eecSFederico Vaga    dall'adattatore per indicare quali descrittori sono stati processati.
108edba5eecSFederico Vaga
109edba5eecSFederico VagaPer la maggior parte del codice, nessuna delle giustificazioni sopracitate può
110edba5eecSFederico Vagaessere considerata.  Di conseguenza, l'uso di *volatile* è probabile che venga
111edba5eecSFederico Vagavisto come un baco e porterà a verifiche aggiuntive.  Gli sviluppatori tentati
112edba5eecSFederico Vagadall'uso di *volatile* dovrebbero fermarsi e pensare a cosa vogliono davvero
113edba5eecSFederico Vagaottenere.
114edba5eecSFederico Vaga
115edba5eecSFederico VagaLe modifiche che rimuovono variabili *volatile* sono generalmente ben accette
116edba5eecSFederico Vaga- purché accompagnate da una giustificazione che dimostri che i problemi di
117edba5eecSFederico Vagaconcorrenza siano stati opportunamente considerati.
118edba5eecSFederico Vaga
119edba5eecSFederico VagaRiferimenti
120edba5eecSFederico Vaga===========
121edba5eecSFederico Vaga
122*1d6f52a7SFederico Vaga[1] https://lwn.net/Articles/233481/
123edba5eecSFederico Vaga
124*1d6f52a7SFederico Vaga[2] https://lwn.net/Articles/233482/
125edba5eecSFederico Vaga
126edba5eecSFederico VagaCrediti
127edba5eecSFederico Vaga=======
128edba5eecSFederico Vaga
129edba5eecSFederico VagaImpulso e ricerca originale di Randy Dunlap
130edba5eecSFederico Vaga
131edba5eecSFederico VagaScritto da Jonathan Corbet
132edba5eecSFederico Vaga
133edba5eecSFederico VagaMigliorato dai commenti di Satyam Sharma, Johannes Stezenbach, Jesper
134edba5eecSFederico VagaJuhl, Heikki Orsila, H. Peter Anvin, Philipp Hahn, e Stefan Richter.
135