1.. SPDX-License-Identifier: GPL-2.0 2 3.. include:: ../disclaimer-ita.rst 4 5============================================= 6Le operazioni RCU per le verifiche *torture* 7============================================= 8 9CONFIG_RCU_TORTURE_TEST 10======================= 11 12L'opzione CONFIG_RCU_TORTURE_TEST è disponibile per tutte le implementazione di 13RCU. L'opzione creerà un modulo rcutorture che potrete caricare per avviare le 14verifiche. La verifica userà printk() per riportare lo stato, dunque potrete 15visualizzarlo con dmesg (magari usate grep per filtrare "torture"). Le verifiche 16inizieranno al caricamento, e si fermeranno alla sua rimozione. 17 18I parametri di modulo hanno tutti il prefisso "rcutortute.", vedere 19Documentation/admin-guide/kernel-parameters.txt. 20 21Rapporto 22======== 23 24Il 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 33Sulla maggior parte dei sistemi questo rapporto si produce col comando "dmesg | 34grep torture:". Su configurazioni più esoteriche potrebbe essere necessario 35usare altri comandi per visualizzare i messaggi di printk(). La funzione 36printk() usa KERN_ALERT, dunque i messaggi dovrebbero essere ben visibili. ;-) 37 38La prima e l'ultima riga mostrano i parametri di module di rcutorture, e solo 39sull'ultima riga abbiamo il risultato finale delle verifiche effettuate che può 40essere "SUCCESS" (successo) or "FAILURE" (insuccesso). 41 42Le 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 115Una diversa implementazione di RCU potrebbe fornire informazioni aggiuntive. Per 116esempio, *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 120Questa riga mostra lo stato dei contatori per processore, in questo caso per 121*Tree SRCU*, usando un'allocazione dinamica di srcu_struct (dunque "srcud-" 122piuttosto che "srcu-"). I numeri fra parentesi sono i valori del "vecchio" 123contatore e di quello "corrente" per ogni processore. Il valore "idx" mappa 124questi due valori nell'array, ed è utile per il *debug*. La "T" finale contiene 125il valore totale dei contatori. 126 127Uso su specifici kernel 128======================= 129 130A volte può essere utile eseguire RCU torture su un kernel già compilato, ad 131esempio quando lo si sta per mettere in proeduzione. In questo caso, il kernel 132dev'essere compilato con CONFIG_RCU_TORTURE_TEST=m, cosicché le verifiche possano 133essere avviate usano modprobe e terminate con rmmod. 134 135Per esempio, potreste usare questo script:: 136 137 #!/bin/sh 138 139 modprobe rcutorture 140 sleep 3600 141 rmmod rcutorture 142 dmesg | grep torture: 143 144Potete controllare il rapporto verificando manualmente la presenza del marcatore 145di errore "!!!". Ovviamente, siete liberi di scriverne uno più elaborato che 146identifichi automaticamente gli errori. Il comando "rmmod" forza la stampa di 147"SUCCESS" (successo), "FAILURE" (fallimento), o "RCU_HOTPLUG". I primi due sono 148autoesplicativi; invece, l'ultimo indica che non son stati trovati problemi in 149RCU, tuttavia ci sono stati problemi con CPU-hotplug. 150 151 152Uso sul kernel di riferimento 153============================= 154 155Quando si usa rcutorture per verificare modifiche ad RCU stesso, spesso è 156necessario compilare un certo numero di kernel usando configurazioni diverse e 157con parametri d'avvio diversi. In questi casi, usare modprobe ed rmmod potrebbe 158richiedere molto tempo ed il processo essere suscettibile ad errori. 159 160Dunque, viene messo a disposizione il programma 161tools/testing/selftests/rcutorture/bin/kvm.sh per le architetture x86, arm64 e 162powerpc. Di base, eseguirà la serie di verifiche elencate in 163tools/testing/selftests/rcutorture/configs/rcu/CFLIST. Ognuna di queste verrà 164eseguita per 30 minuti in una macchina virtuale con uno spazio utente minimale 165fornito da un initrd generato automaticamente. Al completamento, gli artefatti 166prodotti e i messaggi vengono analizzati alla ricerca di errori, ed i risultati 167delle esecuzioni riassunti in un rapporto. 168 169Su grandi sistemi, le verifiche di rcutorture posso essere velocizzare passano a 170kvm.sh l'argomento --cpus. Per esempio, su un sistema a 64 processori, "--cpus 17143" userà fino a 43 processori per eseguire contemporaneamente le verifiche. Su 172un kernel v5.4 per eseguire tutti gli scenari in due serie, riduce il tempo 173d'esecuzione da otto ore a un'ora (senza contare il tempo per compilare sedici 174kernel). L'argomento "--dryrun sched" non eseguirà verifiche, piuttosto vi 175informerà su come queste verranno organizzate in serie. Questo può essere utile 176per capire quanti processori riservare per le verifiche in --cpus. 177 178Non serve eseguire tutti gli scenari di verifica per ogni modifica. Per esempio, 179per una modifica a Tree SRCU potete eseguire gli scenari SRCU-N e SRCU-P. Per 180farlo usate l'argomento --configs di kvm.sh in questo modo: "--configs 'SRCU-N 181SRCU-P'". Su grandi sistemi si possono eseguire più copie degli stessi scenari, 182per esempio, un hardware che permette di eseguire 448 thread, può eseguire 5 183istanze complete contemporaneamente. Per farlo:: 184 185 kvm.sh --cpus 448 --configs '5*CFLIST' 186 187Oppure, lo stesso sistema, può eseguire contemporaneamente 56 istanze dello 188scenario su otto processori:: 189 190 kvm.sh --cpus 448 --configs '56*TREE04' 191 192O ancora 28 istanze per ogni scenario su otto processori:: 193 194 kvm.sh --cpus 448 --configs '28*TREE03 28*TREE04' 195 196Ovviamente, ogni esecuzione utilizzerà della memoria. Potete limitarne l'uso con 197l'argomento --memory, che di base assume il valore 512M. Per poter usare valori 198piccoli dovrete disabilitare le verifiche *callback-flooding* usando il 199parametro --bootargs che vedremo in seguito. 200 201A volte è utile avere informazioni aggiuntive di debug, in questo caso potete 202usare il parametro --kconfig, per esempio, ``--kconfig 203'CONFIG_RCU_EQS_DEBUG=y'``. In aggiunta, ci sono i parametri --gdb, --kasan, and 204kcsan. Da notare che --gdb vi limiterà all'uso di un solo scenario per 205esecuzione di kvm.sh e richiede di avere anche un'altra finestra aperta dalla 206quale eseguire ``gdb`` come viene spiegato dal programma. 207 208Potete passare anche i parametri d'avvio del kernel, per esempio, per 209controllare i parametri del modulo rcutorture. Per esempio, per verificare 210modifiche del codice RCU CPU stall-warning, usate ``bootargs 211'rcutorture.stall_cpu=30``. Il programma riporterà un fallimento, ossia il 212risultato della verifica. Come visto in precedenza, ridurre la memoria richiede 213la disabilitazione delle verifiche *callback-flooding*:: 214 215 kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \ 216 --bootargs 'rcutorture.fwd_progress=0' 217 218A volte tutto quello che serve è una serie completa di compilazioni del kernel. 219Questo si ottiene col parametro --buildonly. 220 221Il parametro --duration sovrascrive quello di base di 30 minuti. Per esempio, 222con ``--duration 2d`` l'esecuzione sarà di due giorni, ``--duraction 5min`` di 223cinque minuti, e ``--duration 45s`` di 45 secondi. L'ultimo può essere utile per 224scovare rari errori nella sequenza d'avvio. 225 226Infine, il parametro --trust-make permette ad ogni nuova compilazione del kernel 227di riutilizzare tutto il possibile da quelle precedenti. Da notare che senza il 228parametro --trust-make, i vostri file di *tag* potrebbero essere distrutti. 229 230Ci sono altri parametri più misteriosi che sono documentati nel codice sorgente 231dello programma kvm.sh. 232 233Se un'esecuzione contiene degli errori, il loro numero durante la compilazione e 234all'esecuzione verranno elencati alla fine fra i risultati di kvm.sh (che vi 235consigliamo caldamente di reindirizzare verso un file). I file prodotti dalla 236compilazione ed i risultati stampati vengono salvati, usando un riferimento 237temporale, nelle cartella tools/testing/selftests/rcutorture/res. Una cartella 238di queste cartelle può essere fornita a kvm-find-errors.sh per estrarne gli 239errori. 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 244Tuttavia, molto spesso è più conveniente aprire i file direttamente. I file 245riguardanti tutti gli scenari di un'esecuzione di trovano nella cartella 246principale (2020.01.20-15.54.23 nell'esempio precedente), mentre quelli 247specifici per scenario si trovano in sotto cartelle che prendono il nome dello 248scenario stesso (per esempio, "TREE04"). Se un dato scenario viene eseguito più 249di una volta (come abbiamo visto con "--configs '56*TREE04'"), allora dalla 250seconda esecuzione in poi le sottocartelle includeranno un numero di 251progressione, per esempio "TREE04.2", "TREE04.3", e via dicendo. 252 253Il file solitamente più usato nella cartella principale è testid.txt. Se la 254verifica viene eseguita in un repositorio git, allora questo file conterrà il 255*commit* sul quale si basano le verifiche, mentre tutte le modifiche non 256registrare verranno mostrate in formato diff. 257 258I file solitamente più usati nelle cartelle di scenario sono: 259 260.config 261 Questo file contiene le opzioni di Kconfig 262 263Make.out 264 Questo file contiene il risultato di compilazione per uno specifico scenario 265 266console.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 271vmlinux 272 Questo file contiene il kernel, e potrebbe essere utile da esaminare con 273 programmi come pbjdump e gdb 274 275Ci sono altri file, ma vengono usati meno. Molti sono utili all'analisi di 276rcutorture stesso o dei suoi programmi. 277 278Nel kernel v5.4, su un sistema a 12 processori, un'esecuzione senza errori 279usando 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 300Ripetizioni 301=========== 302 303Immaginate di essere alla caccia di un raro problema che si verifica all'avvio. 304Potreste usare kvm.sh, tuttavia questo ricompilerebbe il kernel ad ogni 305esecuzione. Se avete bisogno di (diciamo) 1000 esecuzioni per essere sicuri di 306aver risolto il problema, allora queste inutili ricompilazioni possono diventare 307estremamente fastidiose. 308 309Per questo motivo esiste kvm-again.sh. 310 311Immaginate che un'esecuzione precedente di kvm.sh abbia lasciato i suoi 312artefatti nella cartella:: 313 314 tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 315 316Questa esecuzione può essere rieseguita senza ricompilazioni:: 317 318 kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 319 320Alcuni dei parametri originali di kvm.sh possono essere sovrascritti, in 321particolare --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 326rieseguirebbe il test precedente, ma solo per 45 secondi, e quindi aiutando a 327trovare quel raro problema all'avvio sopracitato. 328 329Esecuzioni distribuite 330====================== 331 332Sebbene kvm.sh sia utile, le sue verifiche sono limitate ad un singolo sistema. 333Non è poi così difficile usare un qualsiasi ambiente di sviluppo per eseguire 334(diciamo) 5 istanze di kvm.sh su altrettanti sistemi, ma questo avvierebbe 335inutili ricompilazioni del kernel. In aggiunta, il processo di distribuzione 336degli scenari di verifica per rcutorture sui sistemi disponibili richiede 337scrupolo perché soggetto ad errori. 338 339Per questo esiste kvm-remote.sh. 340 341Se il seguente comando funziona:: 342 343 ssh system0 date 344 345e funziona anche per system1, system2, system3, system4, e system5, e tutti 346questi 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 351Questo compilerà lo scenario di base sul sistema locale, poi lo distribuirà agli 352altri cinque sistemi elencati fra i parametri, ed eseguirà ogni scenario per 353otto ore. Alla fine delle esecuzioni, i risultati verranno raccolti, registrati, 354e stampati. La maggior parte dei parametri di kvm.sh possono essere usati con 355kvm-remote.sh, tuttavia la lista dei sistemi deve venire sempre per prima. 356 357L'argomento di kvm.sh ``--dryrun scenarios`` può essere utile per scoprire 358quanti scenari potrebbero essere eseguiti in gruppo di sistemi. 359 360Potete rieseguire anche una precedente esecuzione remota come abbiamo già fatto 361per 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 367In questo caso, la maggior parte dei parametri di kvm-again.sh possono essere 368usati dopo il percorso alla cartella contenente gli artefatti dell'esecuzione da 369ripetere. 370