1 .. SPDX-License-Identifier: GPL-2.0 2 3 .. include:: ../disclaimer-ita.rst 4 5 ============================================= 6 Le operazioni RCU per le verifiche *torture* 7 ============================================= 8 9 CONFIG_RCU_TORTURE_TEST 10 ======================= 11 12 L'opzione CONFIG_RCU_TORTURE_TEST è disponibile per tutte le implementazione di 13 RCU. L'opzione creerà un modulo rcutorture che potrete caricare per avviare le 14 verifiche. La verifica userà printk() per riportare lo stato, dunque potrete 15 visualizzarlo con dmesg (magari usate grep per filtrare "torture"). Le verifiche 16 inizieranno al caricamento, e si fermeranno alla sua rimozione. 17 18 I parametri di modulo hanno tutti il prefisso "rcutortute.", vedere 19 Documentation/admin-guide/kernel-parameters.txt. 20 21 Rapporto 22 ======== 23 24 Il rapporto sulle verifiche si presenta nel seguente modo:: 25 26 rcu-torture:--- Start of test: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4 27 rcu-torture: rtc: (null) ver: 155441 tfle: 0 rta: 155441 rtaf: 8884 rtf: 155440 rtmbe: 0 rtbe: 0 rtbke: 0 rtbre: 0 rtbf: 0 rtb: 0 nt: 3055767 28 rcu-torture: Reader Pipe: 727860534 34213 0 0 0 0 0 0 0 0 0 29 rcu-torture: Reader Batch: 727877838 17003 0 0 0 0 0 0 0 0 0 30 rcu-torture: Free-Block Circulation: 155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0 31 rcu-torture:--- End of test: SUCCESS: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4 32 33 Sulla maggior parte dei sistemi questo rapporto si produce col comando "dmesg | 34 grep torture:". Su configurazioni più esoteriche potrebbe essere necessario 35 usare altri comandi per visualizzare i messaggi di printk(). La funzione 36 printk() usa KERN_ALERT, dunque i messaggi dovrebbero essere ben visibili. ;-) 37 38 La prima e l'ultima riga mostrano i parametri di module di rcutorture, e solo 39 sull'ultima riga abbiamo il risultato finale delle verifiche effettuate che può 40 essere "SUCCESS" (successo) or "FAILURE" (insuccesso). 41 42 Le voci sono le seguenti: 43 44 * "rtc": L'indirizzo in esadecimale della struttura attualmente visibile dai 45 lettori. 46 47 * "ver": Il numero di volte dall'avvio che il processo scrittore di RCU ha 48 cambiato la struttura visible ai lettori. 49 50 * "tfle": se non è zero, indica la lista di strutture "torture freelist" da 51 mettere in "rtc" è vuota. Questa condizione è importante perché potrebbe 52 illuderti che RCU stia funzionando mentre invece non è il caso. :-/ 53 54 * "rta": numero di strutture allocate dalla lista "torture freelist". 55 56 * "rtaf": il numero di allocazioni fallite dalla lista "torture freelist" a 57 causa del fatto che fosse vuota. Non è inusuale che sia diverso da zero, ma è 58 un brutto segno se questo numero rappresenta una frazione troppo alta di 59 "rta". 60 61 * "rtf": il numero di rilasci nella lista "torture freelist" 62 63 * "rtmbe": Un valore diverso da zero indica che rcutorture crede che 64 rcu_assign_pointer() e rcu_dereference() non funzionino correttamente. Il 65 valore dovrebbe essere zero. 66 67 * "rtbe": un valore diverso da zero indica che le funzioni della famiglia 68 rcu_barrier() non funzionano correttamente. 69 70 * "rtbke": rcutorture è stato capace di creare dei kthread real-time per forzare 71 l'inversione di priorità di RCU. Il valore dovrebbe essere zero. 72 73 * "rtbre": sebbene rcutorture sia riuscito a creare dei kthread capaci di 74 forzare l'inversione di priorità, non è riuscito però ad impostarne la 75 priorità real-time al livello 1. Il valore dovrebbe essere zero. 76 77 * "rtbf": Il numero di volte che è fallita la promozione della priorità per 78 risolvere un'inversione. 79 80 * "rtb": Il numero di volte che rcutorture ha provato a forzare l'inversione di 81 priorità. Il valore dovrebbe essere diverso da zero Se state verificando la 82 promozione della priorità col parametro "test_bootst". 83 84 * "nt": il numero di volte che rcutorture ha eseguito codice lato lettura 85 all'interno di un gestore di *timer*. Questo valore dovrebbe essere diverso da 86 zero se avete specificato il parametro "irqreader". 87 88 * "Reader Pipe": un istogramma dell'età delle strutture viste dai lettori. RCU 89 non funziona correttamente se una qualunque voce, dalla terza in poi, ha un 90 valore diverso da zero. Se dovesse succedere, rcutorture stampa la stringa 91 "!!!" per renderlo ben visibile. L'età di una struttura appena creata è zero, 92 diventerà uno quando sparisce dalla visibilità di un lettore, e incrementata 93 successivamente per ogni periodo di grazia; infine rilasciata dopo essere 94 passata per (RCU_TORTURE_PIPE_LEN-2) periodi di grazia. 95 96 L'istantanea qui sopra è stata presa da una corretta implementazione di RCU. 97 Se volete vedere come appare quando non funziona, sbizzarritevi nel romperla. 98 ;-) 99 100 * "Reader Batch": un istogramma di età di strutture viste dai lettori, ma 101 conteggiata in termini di lotti piuttosto che periodi. Anche qui dalla terza 102 voce in poi devono essere zero. La ragione d'esistere di questo rapporto è che 103 a volte è più facile scatenare un terzo valore diverso da zero qui piuttosto 104 che nella lista "Reader Pipe". 105 106 * "Free-Block Circulation": il numero di strutture *torture* che hanno raggiunto 107 un certo punto nella catena. Il primo numero dovrebbe corrispondere 108 strettamente al numero di strutture allocate; il secondo conta quelle rimosse 109 dalla vista dei lettori. Ad eccezione dell'ultimo valore, gli altri 110 corrispondono al numero di passaggi attraverso il periodo di grazia. L'ultimo 111 valore dovrebbe essere zero, perché viene incrementato solo se il contatore 112 della struttura torture viene in un qualche modo incrementato oltre il 113 normale. 114 115 Una diversa implementazione di RCU potrebbe fornire informazioni aggiuntive. Per 116 esempio, *Tree SRCU* fornisce anche la seguente riga:: 117 118 srcud-torture: Tree SRCU per-CPU(idx=0): 0(35,-21) 1(-4,24) 2(1,1) 3(-26,20) 4(28,-47) 5(-9,4) 6(-10,14) 7(-14,11) T(1,6) 119 120 Questa riga mostra lo stato dei contatori per processore, in questo caso per 121 *Tree SRCU*, usando un'allocazione dinamica di srcu_struct (dunque "srcud-" 122 piuttosto che "srcu-"). I numeri fra parentesi sono i valori del "vecchio" 123 contatore e di quello "corrente" per ogni processore. Il valore "idx" mappa 124 questi due valori nell'array, ed è utile per il *debug*. La "T" finale contiene 125 il valore totale dei contatori. 126 127 Uso su specifici kernel 128 ======================= 129 130 A volte può essere utile eseguire RCU torture su un kernel già compilato, ad 131 esempio quando lo si sta per mettere in proeduzione. In questo caso, il kernel 132 dev'essere compilato con CONFIG_RCU_TORTURE_TEST=m, cosicché le verifiche possano 133 essere avviate usano modprobe e terminate con rmmod. 134 135 Per esempio, potreste usare questo script:: 136 137 #!/bin/sh 138 139 modprobe rcutorture 140 sleep 3600 141 rmmod rcutorture 142 dmesg | grep torture: 143 144 Potete controllare il rapporto verificando manualmente la presenza del marcatore 145 di errore "!!!". Ovviamente, siete liberi di scriverne uno più elaborato che 146 identifichi automaticamente gli errori. Il comando "rmmod" forza la stampa di 147 "SUCCESS" (successo), "FAILURE" (fallimento), o "RCU_HOTPLUG". I primi due sono 148 autoesplicativi; invece, l'ultimo indica che non son stati trovati problemi in 149 RCU, tuttavia ci sono stati problemi con CPU-hotplug. 150 151 152 Uso sul kernel di riferimento 153 ============================= 154 155 Quando si usa rcutorture per verificare modifiche ad RCU stesso, spesso è 156 necessario compilare un certo numero di kernel usando configurazioni diverse e 157 con parametri d'avvio diversi. In questi casi, usare modprobe ed rmmod potrebbe 158 richiedere molto tempo ed il processo essere suscettibile ad errori. 159 160 Dunque, viene messo a disposizione il programma 161 tools/testing/selftests/rcutorture/bin/kvm.sh per le architetture x86, arm64 e 162 powerpc. Di base, eseguirà la serie di verifiche elencate in 163 tools/testing/selftests/rcutorture/configs/rcu/CFLIST. Ognuna di queste verrà 164 eseguita per 30 minuti in una macchina virtuale con uno spazio utente minimale 165 fornito da un initrd generato automaticamente. Al completamento, gli artefatti 166 prodotti e i messaggi vengono analizzati alla ricerca di errori, ed i risultati 167 delle esecuzioni riassunti in un rapporto. 168 169 Su grandi sistemi, le verifiche di rcutorture posso essere velocizzare passano a 170 kvm.sh l'argomento --cpus. Per esempio, su un sistema a 64 processori, "--cpus 171 43" userà fino a 43 processori per eseguire contemporaneamente le verifiche. Su 172 un kernel v5.4 per eseguire tutti gli scenari in due serie, riduce il tempo 173 d'esecuzione da otto ore a un'ora (senza contare il tempo per compilare sedici 174 kernel). L'argomento "--dryrun sched" non eseguirà verifiche, piuttosto vi 175 informerà su come queste verranno organizzate in serie. Questo può essere utile 176 per capire quanti processori riservare per le verifiche in --cpus. 177 178 Non serve eseguire tutti gli scenari di verifica per ogni modifica. Per esempio, 179 per una modifica a Tree SRCU potete eseguire gli scenari SRCU-N e SRCU-P. Per 180 farlo usate l'argomento --configs di kvm.sh in questo modo: "--configs 'SRCU-N 181 SRCU-P'". Su grandi sistemi si possono eseguire più copie degli stessi scenari, 182 per esempio, un hardware che permette di eseguire 448 thread, può eseguire 5 183 istanze complete contemporaneamente. Per farlo:: 184 185 kvm.sh --cpus 448 --configs '5*CFLIST' 186 187 Oppure, lo stesso sistema, può eseguire contemporaneamente 56 istanze dello 188 scenario su otto processori:: 189 190 kvm.sh --cpus 448 --configs '56*TREE04' 191 192 O ancora 28 istanze per ogni scenario su otto processori:: 193 194 kvm.sh --cpus 448 --configs '28*TREE03 28*TREE04' 195 196 Ovviamente, ogni esecuzione utilizzerà della memoria. Potete limitarne l'uso con 197 l'argomento --memory, che di base assume il valore 512M. Per poter usare valori 198 piccoli dovrete disabilitare le verifiche *callback-flooding* usando il 199 parametro --bootargs che vedremo in seguito. 200 201 A volte è utile avere informazioni aggiuntive di debug, in questo caso potete 202 usare il parametro --kconfig, per esempio, ``--kconfig 203 'CONFIG_RCU_EQS_DEBUG=y'``. In aggiunta, ci sono i parametri --gdb, --kasan, and 204 kcsan. Da notare che --gdb vi limiterà all'uso di un solo scenario per 205 esecuzione di kvm.sh e richiede di avere anche un'altra finestra aperta dalla 206 quale eseguire ``gdb`` come viene spiegato dal programma. 207 208 Potete passare anche i parametri d'avvio del kernel, per esempio, per 209 controllare i parametri del modulo rcutorture. Per esempio, per verificare 210 modifiche del codice RCU CPU stall-warning, usate ``bootargs 211 'rcutorture.stall_cpu=30``. Il programma riporterà un fallimento, ossia il 212 risultato della verifica. Come visto in precedenza, ridurre la memoria richiede 213 la disabilitazione delle verifiche *callback-flooding*:: 214 215 kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \ 216 --bootargs 'rcutorture.fwd_progress=0' 217 218 A volte tutto quello che serve è una serie completa di compilazioni del kernel. 219 Questo si ottiene col parametro --buildonly. 220 221 Il parametro --duration sovrascrive quello di base di 30 minuti. Per esempio, 222 con ``--duration 2d`` l'esecuzione sarà di due giorni, ``--duraction 5min`` di 223 cinque minuti, e ``--duration 45s`` di 45 secondi. L'ultimo può essere utile per 224 scovare rari errori nella sequenza d'avvio. 225 226 Infine, il parametro --trust-make permette ad ogni nuova compilazione del kernel 227 di riutilizzare tutto il possibile da quelle precedenti. Da notare che senza il 228 parametro --trust-make, i vostri file di *tag* potrebbero essere distrutti. 229 230 Ci sono altri parametri più misteriosi che sono documentati nel codice sorgente 231 dello programma kvm.sh. 232 233 Se un'esecuzione contiene degli errori, il loro numero durante la compilazione e 234 all'esecuzione verranno elencati alla fine fra i risultati di kvm.sh (che vi 235 consigliamo caldamente di reindirizzare verso un file). I file prodotti dalla 236 compilazione ed i risultati stampati vengono salvati, usando un riferimento 237 temporale, nelle cartella tools/testing/selftests/rcutorture/res. Una cartella 238 di queste cartelle può essere fornita a kvm-find-errors.sh per estrarne gli 239 errori. Per esempio:: 240 241 tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh \ 242 tools/testing/selftests/rcutorture/res/2020.01.20-15.54.23 243 244 Tuttavia, molto spesso è più conveniente aprire i file direttamente. I file 245 riguardanti tutti gli scenari di un'esecuzione di trovano nella cartella 246 principale (2020.01.20-15.54.23 nell'esempio precedente), mentre quelli 247 specifici per scenario si trovano in sotto cartelle che prendono il nome dello 248 scenario stesso (per esempio, "TREE04"). Se un dato scenario viene eseguito più 249 di una volta (come abbiamo visto con "--configs '56*TREE04'"), allora dalla 250 seconda esecuzione in poi le sottocartelle includeranno un numero di 251 progressione, per esempio "TREE04.2", "TREE04.3", e via dicendo. 252 253 Il file solitamente più usato nella cartella principale è testid.txt. Se la 254 verifica viene eseguita in un repositorio git, allora questo file conterrà il 255 *commit* sul quale si basano le verifiche, mentre tutte le modifiche non 256 registrare verranno mostrate in formato diff. 257 258 I file solitamente più usati nelle cartelle di scenario sono: 259 260 .config 261 Questo file contiene le opzioni di Kconfig 262 263 Make.out 264 Questo file contiene il risultato di compilazione per uno specifico scenario 265 266 console.log 267 Questo file contiene il risultato d'esecuzione per uno specifico scenario. 268 Questo file può essere esaminato una volta che il kernel è stato avviato, 269 ma potrebbe non esistere se l'avvia non è fallito. 270 271 vmlinux 272 Questo file contiene il kernel, e potrebbe essere utile da esaminare con 273 programmi come pbjdump e gdb 274 275 Ci sono altri file, ma vengono usati meno. Molti sono utili all'analisi di 276 rcutorture stesso o dei suoi programmi. 277 278 Nel kernel v5.4, su un sistema a 12 processori, un'esecuzione senza errori 279 usando gli scenari di base produce il seguente risultato:: 280 281 SRCU-N ------- 804233 GPs (148.932/s) [srcu: g10008272 f0x0 ] 282 SRCU-P ------- 202320 GPs (37.4667/s) [srcud: g1809476 f0x0 ] 283 SRCU-t ------- 1122086 GPs (207.794/s) [srcu: g0 f0x0 ] 284 SRCU-u ------- 1111285 GPs (205.794/s) [srcud: g1 f0x0 ] 285 TASKS01 ------- 19666 GPs (3.64185/s) [tasks: g0 f0x0 ] 286 TASKS02 ------- 20541 GPs (3.80389/s) [tasks: g0 f0x0 ] 287 TASKS03 ------- 19416 GPs (3.59556/s) [tasks: g0 f0x0 ] 288 TINY01 ------- 836134 GPs (154.84/s) [rcu: g0 f0x0 ] n_max_cbs: 34198 289 TINY02 ------- 850371 GPs (157.476/s) [rcu: g0 f0x0 ] n_max_cbs: 2631 290 TREE01 ------- 162625 GPs (30.1157/s) [rcu: g1124169 f0x0 ] 291 TREE02 ------- 333003 GPs (61.6672/s) [rcu: g2647753 f0x0 ] n_max_cbs: 35844 292 TREE03 ------- 306623 GPs (56.782/s) [rcu: g2975325 f0x0 ] n_max_cbs: 1496497 293 CPU count limited from 16 to 12 294 TREE04 ------- 246149 GPs (45.5831/s) [rcu: g1695737 f0x0 ] n_max_cbs: 434961 295 TREE05 ------- 314603 GPs (58.2598/s) [rcu: g2257741 f0x2 ] n_max_cbs: 193997 296 TREE07 ------- 167347 GPs (30.9902/s) [rcu: g1079021 f0x0 ] n_max_cbs: 478732 297 CPU count limited from 16 to 12 298 TREE09 ------- 752238 GPs (139.303/s) [rcu: g13075057 f0x0 ] n_max_cbs: 99011 299 300 Ripetizioni 301 =========== 302 303 Immaginate di essere alla caccia di un raro problema che si verifica all'avvio. 304 Potreste usare kvm.sh, tuttavia questo ricompilerebbe il kernel ad ogni 305 esecuzione. Se avete bisogno di (diciamo) 1000 esecuzioni per essere sicuri di 306 aver risolto il problema, allora queste inutili ricompilazioni possono diventare 307 estremamente fastidiose. 308 309 Per questo motivo esiste kvm-again.sh. 310 311 Immaginate che un'esecuzione precedente di kvm.sh abbia lasciato i suoi 312 artefatti nella cartella:: 313 314 tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 315 316 Questa esecuzione può essere rieseguita senza ricompilazioni:: 317 318 kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 319 320 Alcuni dei parametri originali di kvm.sh possono essere sovrascritti, in 321 particolare --duration e --bootargs. Per esempio:: 322 323 kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 \ 324 --duration 45s 325 326 rieseguirebbe il test precedente, ma solo per 45 secondi, e quindi aiutando a 327 trovare quel raro problema all'avvio sopracitato. 328 329 Esecuzioni distribuite 330 ====================== 331 332 Sebbene kvm.sh sia utile, le sue verifiche sono limitate ad un singolo sistema. 333 Non è poi così difficile usare un qualsiasi ambiente di sviluppo per eseguire 334 (diciamo) 5 istanze di kvm.sh su altrettanti sistemi, ma questo avvierebbe 335 inutili ricompilazioni del kernel. In aggiunta, il processo di distribuzione 336 degli scenari di verifica per rcutorture sui sistemi disponibili richiede 337 scrupolo perché soggetto ad errori. 338 339 Per questo esiste kvm-remote.sh. 340 341 Se il seguente comando funziona:: 342 343 ssh system0 date 344 345 e funziona anche per system1, system2, system3, system4, e system5, e tutti 346 questi sistemi hanno 64 CPU, allora potere eseguire:: 347 348 kvm-remote.sh "system0 system1 system2 system3 system4 system5" \ 349 --cpus 64 --duration 8h --configs "5*CFLIST" 350 351 Questo compilerà lo scenario di base sul sistema locale, poi lo distribuirà agli 352 altri cinque sistemi elencati fra i parametri, ed eseguirà ogni scenario per 353 otto ore. Alla fine delle esecuzioni, i risultati verranno raccolti, registrati, 354 e stampati. La maggior parte dei parametri di kvm.sh possono essere usati con 355 kvm-remote.sh, tuttavia la lista dei sistemi deve venire sempre per prima. 356 357 L'argomento di kvm.sh ``--dryrun scenarios`` può essere utile per scoprire 358 quanti scenari potrebbero essere eseguiti in gruppo di sistemi. 359 360 Potete rieseguire anche una precedente esecuzione remota come abbiamo già fatto 361 per kvm.sh:: 362 363 kvm-remote.sh "system0 system1 system2 system3 system4 system5" \ 364 tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28-remote \ 365 --duration 24h 366 367 In questo caso, la maggior parte dei parametri di kvm-again.sh possono essere 368 usati dopo il percorso alla cartella contenente gli artefatti dell'esecuzione da 369 ripetere.
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.