요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-ita.rst
=============================================
Le operazioni RCU per le verifiche *torture*
=============================================
CONFIG_RCU_TORTURE_TEST
=======================
L'opzione CONFIG_RCU_TORTURE_TEST è disponibile per tutte le implementazione di
RCU. L'opzione creerà un modulo rcutorture che potrete caricare per avviare le
verifiche. La verifica userà printk() per riportare lo stato, dunque potrete
visualizzarlo con dmesg (magari usate grep per filtrare "torture"). Le verifiche
inizieranno al caricamento, e si fermeranno alla sua rimozione.
I parametri di modulo hanno tutti il prefisso "rcutortute.", vedere
Documentation/admin-guide/kernel-parameters.txt.
Rapporto
========
Il rapporto sulle verifiche si presenta nel seguente modo::
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
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
rcu-torture: Reader Pipe: 727860534 34213 0 0 0 0 0 0 0 0 0
rcu-torture: Reader Batch: 727877838 17003 0 0 0 0 0 0 0 0 0
rcu-torture: Free-Block Circulation: 155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0
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
Sulla maggior parte dei sistemi questo rapporto si produce col comando "dmesg |
grep torture:". Su configurazioni più esoteriche potrebbe essere necessario
usare altri comandi per visualizzare i messaggi di printk(). La funzione
printk() usa KERN_ALERT, dunque i messaggi dovrebbero essere ben visibili. ;-)
La prima e l'ultima riga mostrano i parametri di module di rcutorture, e solo
sull'ultima riga abbiamo il risultato finale delle verifiche effettuate che può
essere "SUCCESS" (successo) or "FAILURE" (insuccesso).
Le voci sono le seguenti:
* "rtc": L'indirizzo in esadecimale della struttura attualmente visibile dai
lettori.
* "ver": Il numero di volte dall'avvio che il processo scrittore di RCU ha
cambiato la struttura visible ai lettori.
* "tfle": se non è zero, indica la lista di strutture "torture freelist" da
mettere in "rtc" è vuota. Questa condizione è importante perché potrebbe
illuderti che RCU stia funzionando mentre invece non è il caso. :-/
* "rta": numero di strutture allocate dalla lista "torture freelist".
* "rtaf": il numero di allocazioni fallite dalla lista "torture freelist" a
causa del fatto che fosse vuota. Non è inusuale che sia diverso da zero, ma è
un brutto segno se questo numero rappresenta una frazione troppo alta di
"rta".
* "rtf": il numero di rilasci nella lista "torture freelist"
* "rtmbe": Un valore diverso da zero indica che rcutorture crede che
rcu_assign_pointer() e rcu_dereference() non funzionino correttamente. Il
valore dovrebbe essere zero.
* "rtbe": un valore diverso da zero indica che le funzioni della famiglia
rcu_barrier() non funzionano correttamente.
* "rtbke": rcutorture è stato capace di creare dei kthread real-time per forzare
l'inversione di priorità di RCU. Il valore dovrebbe essere zero.
* "rtbre": sebbene rcutorture sia riuscito a creare dei kthread capaci di
forzare l'inversione di priorità, non è riuscito però ad impostarne la
priorità real-time al livello 1. Il valore dovrebbe essere zero.
* "rtbf": Il numero di volte che è fallita la promozione della priorità per
risolvere un'inversione.
* "rtb": Il numero di volte che rcutorture ha provato a forzare l'inversione di
priorità. Il valore dovrebbe essere diverso da zero Se state verificando la
promozione della priorità col parametro "test_bootst".
* "nt": il numero di volte che rcutorture ha eseguito codice lato lettura
all'interno di un gestore di *timer*. Questo valore dovrebbe essere diverso da
zero se avete specificato il parametro "irqreader".
* "Reader Pipe": un istogramma dell'età delle strutture viste dai lettori. RCU
non funziona correttamente se una qualunque voce, dalla terza in poi, ha un
valore diverso da zero. Se dovesse succedere, rcutorture stampa la stringa
"!!!" per renderlo ben visibile. L'età di una struttura appena creata è zero,
diventerà uno quando sparisce dalla visibilità di un lettore, e incrementata
successivamente per ogni periodo di grazia; infine rilasciata dopo essere
passata per (RCU_TORTURE_PIPE_LEN-2) periodi di grazia.
L'istantanea qui sopra è stata presa da una corretta implementazione di RCU.
Se volete vedere come appare quando non funziona, sbizzarritevi nel romperla.
;-)
* "Reader Batch": un istogramma di età di strutture viste dai lettori, ma
conteggiata in termini di lotti piuttosto che periodi. Anche qui dalla terza
voce in poi devono essere zero. La ragione d'esistere di questo rapporto è che
a volte è più facile scatenare un terzo valore diverso da zero qui piuttosto
che nella lista "Reader Pipe".
* "Free-Block Circulation": il numero di strutture *torture* che hanno raggiunto
un certo punto nella catena. Il primo numero dovrebbe corrispondere
strettamente al numero di strutture allocate; il secondo conta quelle rimosse
dalla vista dei lettori. Ad eccezione dell'ultimo valore, gli altri
corrispondono al numero di passaggi attraverso il periodo di grazia. L'ultimo
valore dovrebbe essere zero, perché viene incrementato solo se il contatore
della struttura torture viene in un qualche modo incrementato oltre il
normale.
Una diversa implementazione di RCU potrebbe fornire informazioni aggiuntive. Per
esempio, *Tree SRCU* fornisce anche la seguente riga::
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)
Questa riga mostra lo stato dei contatori per processore, in questo caso per
*Tree SRCU*, usando un'allocazione dinamica di srcu_struct (dunque "srcud-"
piuttosto che "srcu-"). I numeri fra parentesi sono i valori del "vecchio"
contatore e di quello "corrente" per ogni processore. Il valore "idx" mappa
questi due valori nell'array, ed è utile per il *debug*. La "T" finale contiene
il valore totale dei contatori.
Uso su specifici kernel
=======================
A volte può essere utile eseguire RCU torture su un kernel già compilato, ad
esempio quando lo si sta per mettere in proeduzione. In questo caso, il kernel
dev'essere compilato con CONFIG_RCU_TORTURE_TEST=m, cosicché le verifiche possano
essere avviate usano modprobe e terminate con rmmod.
Per esempio, potreste usare questo script::
#!/bin/sh
modprobe rcutorture
sleep 3600
rmmod rcutorture
dmesg | grep torture:
Potete controllare il rapporto verificando manualmente la presenza del marcatore
di errore "!!!". Ovviamente, siete liberi di scriverne uno più elaborato che
identifichi automaticamente gli errori. Il comando "rmmod" forza la stampa di
"SUCCESS" (successo), "FAILURE" (fallimento), o "RCU_HOTPLUG". I primi due sono
autoesplicativi; invece, l'ultimo indica che non son stati trovati problemi in
RCU, tuttavia ci sono stati problemi con CPU-hotplug.
Uso sul kernel di riferimento
=============================
Quando si usa rcutorture per verificare modifiche ad RCU stesso, spesso è
necessario compilare un certo numero di kernel usando configurazioni diverse e
con parametri d'avvio diversi. In questi casi, usare modprobe ed rmmod potrebbe
richiedere molto tempo ed il processo essere suscettibile ad errori.
Dunque, viene messo a disposizione il programma
tools/testing/selftests/rcutorture/bin/kvm.sh per le architetture x86, arm64 e
powerpc. Di base, eseguirà la serie di verifiche elencate in
tools/testing/selftests/rcutorture/configs/rcu/CFLIST. Ognuna di queste verrà
eseguita per 30 minuti in una macchina virtuale con uno spazio utente minimale
fornito da un initrd generato automaticamente. Al completamento, gli artefatti
prodotti e i messaggi vengono analizzati alla ricerca di errori, ed i risultati
delle esecuzioni riassunti in un rapporto.
Su grandi sistemi, le verifiche di rcutorture posso essere velocizzare passano a
kvm.sh l'argomento --cpus. Per esempio, su un sistema a 64 processori, "--cpus
43" userà fino a 43 processori per eseguire contemporaneamente le verifiche. Su
un kernel v5.4 per eseguire tutti gli scenari in due serie, riduce il tempo
d'esecuzione da otto ore a un'ora (senza contare il tempo per compilare sedici
kernel). L'argomento "--dryrun sched" non eseguirà verifiche, piuttosto vi
informerà su come queste verranno organizzate in serie. Questo può essere utile
per capire quanti processori riservare per le verifiche in --cpus.
Non serve eseguire tutti gli scenari di verifica per ogni modifica. Per esempio,
per una modifica a Tree SRCU potete eseguire gli scenari SRCU-N e SRCU-P. Per
farlo usate l'argomento --configs di kvm.sh in questo modo: "--configs 'SRCU-N
SRCU-P'". Su grandi sistemi si possono eseguire più copie degli stessi scenari,
per esempio, un hardware che permette di eseguire 448 thread, può eseguire 5
istanze complete contemporaneamente. Per farlo::
kvm.sh --cpus 448 --configs '5*CFLIST'
Oppure, lo stesso sistema, può eseguire contemporaneamente 56 istanze dello
scenario su otto processori::
kvm.sh --cpus 448 --configs '56*TREE04'
O ancora 28 istanze per ogni scenario su otto processori::
kvm.sh --cpus 448 --configs '28*TREE03 28*TREE04'
Ovviamente, ogni esecuzione utilizzerà della memoria. Potete limitarne l'uso con
l'argomento --memory, che di base assume il valore 512M. Per poter usare valori
piccoli dovrete disabilitare le verifiche *callback-flooding* usando il
parametro --bootargs che vedremo in seguito.
A volte è utile avere informazioni aggiuntive di debug, in questo caso potete
usare il parametro --kconfig, per esempio, ``--kconfig
'CONFIG_RCU_EQS_DEBUG=y'``. In aggiunta, ci sono i parametri --gdb, --kasan, and
kcsan. Da notare che --gdb vi limiterà all'uso di un solo scenario per
esecuzione di kvm.sh e richiede di avere anche un'altra finestra aperta dalla
quale eseguire ``gdb`` come viene spiegato dal programma.
Potete passare anche i parametri d'avvio del kernel, per esempio, per
controllare i parametri del modulo rcutorture. Per esempio, per verificare
modifiche del codice RCU CPU stall-warning, usate ``bootargs
'rcutorture.stall_cpu=30``. Il programma riporterà un fallimento, ossia il
risultato della verifica. Come visto in precedenza, ridurre la memoria richiede
la disabilitazione delle verifiche *callback-flooding*::
kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \
--bootargs 'rcutorture.fwd_progress=0'
A volte tutto quello che serve è una serie completa di compilazioni del kernel.
Questo si ottiene col parametro --buildonly.
Il parametro --duration sovrascrive quello di base di 30 minuti. Per esempio,
con ``--duration 2d`` l'esecuzione sarà di due giorni, ``--duraction 5min`` di
cinque minuti, e ``--duration 45s`` di 45 secondi. L'ultimo può essere utile per
scovare rari errori nella sequenza d'avvio.
Infine, il parametro --trust-make permette ad ogni nuova compilazione del kernel
di riutilizzare tutto il possibile da quelle precedenti. Da notare che senza il
parametro --trust-make, i vostri file di *tag* potrebbero essere distrutti.
Ci sono altri parametri più misteriosi che sono documentati nel codice sorgente
dello programma kvm.sh.
Se un'esecuzione contiene degli errori, il loro numero durante la compilazione e
all'esecuzione verranno elencati alla fine fra i risultati di kvm.sh (che vi
consigliamo caldamente di reindirizzare verso un file). I file prodotti dalla
compilazione ed i risultati stampati vengono salvati, usando un riferimento
temporale, nelle cartella tools/testing/selftests/rcutorture/res. Una cartella
di queste cartelle può essere fornita a kvm-find-errors.sh per estrarne gli
errori. Per esempio::
tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh \
tools/testing/selftests/rcutorture/res/2020.01.20-15.54.23
Tuttavia, molto spesso è più conveniente aprire i file direttamente. I file
riguardanti tutti gli scenari di un'esecuzione di trovano nella cartella
principale (2020.01.20-15.54.23 nell'esempio precedente), mentre quelli
specifici per scenario si trovano in sotto cartelle che prendono il nome dello
scenario stesso (per esempio, "TREE04"). Se un dato scenario viene eseguito più
di una volta (come abbiamo visto con "--configs '56*TREE04'"), allora dalla
seconda esecuzione in poi le sottocartelle includeranno un numero di
progressione, per esempio "TREE04.2", "TREE04.3", e via dicendo.
Il file solitamente più usato nella cartella principale è testid.txt. Se la
verifica viene eseguita in un repositorio git, allora questo file conterrà il
*commit* sul quale si basano le verifiche, mentre tutte le modifiche non
registrare verranno mostrate in formato diff.
I file solitamente più usati nelle cartelle di scenario sono:
.config
Questo file contiene le opzioni di Kconfig
Make.out
Questo file contiene il risultato di compilazione per uno specifico scenario
console.log
Questo file contiene il risultato d'esecuzione per uno specifico scenario.
Questo file può essere esaminato una volta che il kernel è stato avviato,
ma potrebbe non esistere se l'avvia non è fallito.
vmlinux
Questo file contiene il kernel, e potrebbe essere utile da esaminare con
programmi come pbjdump e gdb
Ci sono altri file, ma vengono usati meno. Molti sono utili all'analisi di
rcutorture stesso o dei suoi programmi.
Nel kernel v5.4, su un sistema a 12 processori, un'esecuzione senza errori
usando gli scenari di base produce il seguente risultato::
SRCU-N ------- 804233 GPs (148.932/s) [srcu: g10008272 f0x0 ]
SRCU-P ------- 202320 GPs (37.4667/s) [srcud: g1809476 f0x0 ]
SRCU-t ------- 1122086 GPs (207.794/s) [srcu: g0 f0x0 ]
SRCU-u ------- 1111285 GPs (205.794/s) [srcud: g1 f0x0 ]
TASKS01 ------- 19666 GPs (3.64185/s) [tasks: g0 f0x0 ]
TASKS02 ------- 20541 GPs (3.80389/s) [tasks: g0 f0x0 ]
TASKS03 ------- 19416 GPs (3.59556/s) [tasks: g0 f0x0 ]
TINY01 ------- 836134 GPs (154.84/s) [rcu: g0 f0x0 ] n_max_cbs: 34198
TINY02 ------- 850371 GPs (157.476/s) [rcu: g0 f0x0 ] n_max_cbs: 2631
TREE01 ------- 162625 GPs (30.1157/s) [rcu: g1124169 f0x0 ]
TREE02 ------- 333003 GPs (61.6672/s) [rcu: g2647753 f0x0 ] n_max_cbs: 35844
TREE03 ------- 306623 GPs (56.782/s) [rcu: g2975325 f0x0 ] n_max_cbs: 1496497
CPU count limited from 16 to 12
TREE04 ------- 246149 GPs (45.5831/s) [rcu: g1695737 f0x0 ] n_max_cbs: 434961
TREE05 ------- 314603 GPs (58.2598/s) [rcu: g2257741 f0x2 ] n_max_cbs: 193997
TREE07 ------- 167347 GPs (30.9902/s) [rcu: g1079021 f0x0 ] n_max_cbs: 478732
CPU count limited from 16 to 12
TREE09 ------- 752238 GPs (139.303/s) [rcu: g13075057 f0x0 ] n_max_cbs: 99011
Ripetizioni
===========
Immaginate di essere alla caccia di un raro problema che si verifica all'avvio.
Potreste usare kvm.sh, tuttavia questo ricompilerebbe il kernel ad ogni
esecuzione. Se avete bisogno di (diciamo) 1000 esecuzioni per essere sicuri di
aver risolto il problema, allora queste inutili ricompilazioni possono diventare
estremamente fastidiose.
Per questo motivo esiste kvm-again.sh.
Immaginate che un'esecuzione precedente di kvm.sh abbia lasciato i suoi
artefatti nella cartella::
tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28
Questa esecuzione può essere rieseguita senza ricompilazioni::
kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28
Alcuni dei parametri originali di kvm.sh possono essere sovrascritti, in
particolare --duration e --bootargs. Per esempio::
kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 \
--duration 45s
rieseguirebbe il test precedente, ma solo per 45 secondi, e quindi aiutando a
trovare quel raro problema all'avvio sopracitato.
Esecuzioni distribuite
======================
Sebbene kvm.sh sia utile, le sue verifiche sono limitate ad un singolo sistema.
Non è poi così difficile usare un qualsiasi ambiente di sviluppo per eseguire
(diciamo) 5 istanze di kvm.sh su altrettanti sistemi, ma questo avvierebbe
inutili ricompilazioni del kernel. In aggiunta, il processo di distribuzione
degli scenari di verifica per rcutorture sui sistemi disponibili richiede
scrupolo perché soggetto ad errori.
Per questo esiste kvm-remote.sh.
Se il seguente comando funziona::
ssh system0 date
e funziona anche per system1, system2, system3, system4, e system5, e tutti
questi sistemi hanno 64 CPU, allora potere eseguire::
kvm-remote.sh "system0 system1 system2 system3 system4 system5" \
--cpus 64 --duration 8h --configs "5*CFLIST"
Questo compilerà lo scenario di base sul sistema locale, poi lo distribuirà agli
altri cinque sistemi elencati fra i parametri, ed eseguirà ogni scenario per
otto ore. Alla fine delle esecuzioni, i risultati verranno raccolti, registrati,
e stampati. La maggior parte dei parametri di kvm.sh possono essere usati con
kvm-remote.sh, tuttavia la lista dei sistemi deve venire sempre per prima.
L'argomento di kvm.sh ``--dryrun scenarios`` può essere utile per scoprire
quanti scenari potrebbero essere eseguiti in gruppo di sistemi.
Potete rieseguire anche una precedente esecuzione remota come abbiamo già fatto
per kvm.sh::
kvm-remote.sh "system0 system1 system2 system3 system4 system5" \
tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28-remote \
--duration 24h
In questo caso, la maggior parte dei parametri di kvm-again.sh possono essere
usati dopo il percorso alla cartella contenente gli artefatti dell'esecuzione da
ripetere.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
CONFIG_RCU_TORTURE_TEST와 module 실행
1-20`CONFIG_RCU_TORTURE_TEST` 옵션은 모든 RCU 구현에서 사용할 수 있습니다. 이 옵션은 load하면 검증을 시작하고 제거하면 검증을 중지하는 `rcutorture` module을 만듭니다.
검증 상태는 `printk()`로 보고되므로 `dmesg`에서 확인할 수 있으며, 필요하면 `torture` 문자열로 걸러냅니다. 원문은 module parameter가 `rcutortute.` 접두사를 가진다고 적지만 실제 참조 위치는 `Documentation/admin-guide/kernel-parameters.txt`이며, 이 오래된 표기는 원문 블록에 그대로 보존합니다.
module의 load와 unload가 검증 시작과 종료를 결정합니다.
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-ita.rst
=============================================
Le operazioni RCU per le verifiche *torture*
=============================================
CONFIG_RCU_TORTURE_TEST
=======================
L'opzione CONFIG_RCU_TORTURE_TEST è disponibile per tutte le implementazione di
RCU. L'opzione creerà un modulo rcutorture che potrete caricare per avviare le
verifiche. La verifica userà printk() per riportare lo stato, dunque potrete
visualizzarlo con dmesg (magari usate grep per filtrare "torture"). Le verifiche
inizieranno al caricamento, e si fermeranno alla sua rimozione.
I parametri di modulo hanno tutti il prefisso "rcutortute.", vedere
Documentation/admin-guide/kernel-parameters.txt.
검증 보고서와 통계 필드
21-126검증 보고서는 시작 parameter, 현재 통계, reader histogram, free-block 순환 상태와 최종 판정으로 구성됩니다. 다음은 원문이 제시하는 실제 출력 형식입니다.
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
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
rcu-torture: Reader Pipe: 727860534 34213 0 0 0 0 0 0 0 0 0
rcu-torture: Reader Batch: 727877838 17003 0 0 0 0 0 0 0 0 0
rcu-torture: Free-Block Circulation: 155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0
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
대부분의 system에서는 `dmesg | grep torture:`로 이 보고서를 얻습니다. 특수한 구성에서는 다른 `printk()` 표시 방법이 필요할 수 있습니다. `printk()`가 `KERN_ALERT`를 사용하므로 메시지는 눈에 잘 띄어야 합니다.
첫 줄과 마지막 줄은 `rcutorture` module parameter를 표시합니다. 마지막 줄에만 최종 결과인 `SUCCESS` 또는 `FAILURE`가 포함됩니다.
- `rtc`: 현재 reader에게 보이는 구조체의 16진수 주소입니다.
- `ver`: 시작 이후 RCU writer thread가 reader에게 보이는 구조체를 바꾼 횟수입니다.
- `tfle`: 0이 아니면 `rtc`에 넣을 torture freelist 구조체가 고갈되었다는 뜻입니다. 이런 상태는 RCU가 실제로 동작하지 않는데도 정상처럼 보이게 할 수 있으므로 중요합니다.
- `rta`: torture freelist에서 할당한 구조체 수입니다.
- `rtaf`: freelist가 비어 있어 실패한 할당 수입니다. 0이 아닌 것 자체는 드물지 않지만 `rta`에서 차지하는 비율이 지나치게 높으면 좋지 않은 징후입니다.
- `rtf`: torture freelist로 반환한 횟수입니다.
- `rtmbe`: 0이 아니면 `rcu_assign_pointer()`와 `rcu_dereference()`가 올바르게 동작하지 않는다고 rcutorture가 판단한 것입니다. 0이어야 합니다.
- `rtbe`: 0이 아니면 `rcu_barrier()` 계열 함수가 올바르게 동작하지 않는다는 뜻입니다.
- `rtbke`: priority inversion을 강제로 만들 realtime kthread를 생성하지 못한 횟수입니다. 0이어야 합니다.
- `rtbre`: inversion 유도 kthread는 만들었지만 realtime priority를 level 1로 설정하지 못한 횟수입니다. 0이어야 합니다.
- `rtbf`: priority inversion을 해결하기 위한 priority boost가 실패한 횟수입니다.
- `rtb`: rcutorture가 priority inversion을 유도하려 시도한 횟수입니다. 원문의 `test_bootst` parameter로 boost를 검증하는 경우에는 0이 아니어야 합니다.
- `nt`: timer handler 안에서 rcutorture가 RCU read-side code를 실행한 횟수입니다. `irqreader` parameter를 지정했다면 0이 아니어야 합니다.
`Reader Pipe`는 reader가 본 구조체 나이의 histogram입니다. 새 구조체의 나이는 0이고 reader 가시성에서 사라지면 1이 되며, 이후 grace period마다 증가하다가 `RCU_TORTURE_PIPE_LEN-2`개의 grace period를 지난 뒤 해제됩니다. 세 번째 항목 이후가 하나라도 0이 아니면 RCU가 올바르게 동작하지 않는 것이며 rcutorture는 `!!!`를 출력합니다.
원문의 snapshot은 정상 RCU 구현에서 얻은 것입니다. 고장난 출력이 어떤 모습인지 확인하려면 시험 구현을 의도적으로 손상해 볼 수 있다고 덧붙입니다.
`Reader Batch`도 reader가 본 구조체 나이의 histogram이지만 grace period가 아니라 batch 단위로 셉니다. 여기서도 세 번째 항목 이후는 모두 0이어야 합니다. 일부 오류는 `Reader Pipe`보다 이 지표의 세 번째 값에서 더 쉽게 드러납니다.
`Free-Block Circulation`은 torture 구조체가 pipeline의 각 지점에 도달한 횟수입니다. 첫 값은 할당 수와 거의 같아야 하고 둘째 값은 reader 가시성에서 제거된 수를 셉니다. 마지막 값을 제외한 나머지는 grace period 통과 횟수에 대응하며, 마지막 값은 구조체 counter가 정상 범위를 넘어 증가할 때만 오르므로 0이어야 합니다.
RCU 구현은 추가 정보를 제공할 수 있습니다. 예를 들어 동적 `srcu_struct`를 사용하는 Tree SRCU는 `srcud-` 접두사의 CPU별 counter 줄을 출력합니다.
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)
괄호 안 숫자는 각 CPU의 old counter와 current counter 값입니다. `idx`는 두 값을 배열의 위치에 대응시키며 debug에 유용하고, 마지막 `T`는 counter 총합을 담습니다.
정상 실행에서 먼저 확인할 필드와 기대값입니다.
Rapporto
========
Il rapporto sulle verifiche si presenta nel seguente modo::
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
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
rcu-torture: Reader Pipe: 727860534 34213 0 0 0 0 0 0 0 0 0
rcu-torture: Reader Batch: 727877838 17003 0 0 0 0 0 0 0 0 0
rcu-torture: Free-Block Circulation: 155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0
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
Sulla maggior parte dei sistemi questo rapporto si produce col comando "dmesg |
grep torture:". Su configurazioni più esoteriche potrebbe essere necessario
usare altri comandi per visualizzare i messaggi di printk(). La funzione
printk() usa KERN_ALERT, dunque i messaggi dovrebbero essere ben visibili. ;-)
La prima e l'ultima riga mostrano i parametri di module di rcutorture, e solo
sull'ultima riga abbiamo il risultato finale delle verifiche effettuate che può
essere "SUCCESS" (successo) or "FAILURE" (insuccesso).
Le voci sono le seguenti:
* "rtc": L'indirizzo in esadecimale della struttura attualmente visibile dai
lettori.
* "ver": Il numero di volte dall'avvio che il processo scrittore di RCU ha
cambiato la struttura visible ai lettori.
* "tfle": se non è zero, indica la lista di strutture "torture freelist" da
mettere in "rtc" è vuota. Questa condizione è importante perché potrebbe
illuderti che RCU stia funzionando mentre invece non è il caso. :-/
* "rta": numero di strutture allocate dalla lista "torture freelist".
* "rtaf": il numero di allocazioni fallite dalla lista "torture freelist" a
causa del fatto che fosse vuota. Non è inusuale che sia diverso da zero, ma è
un brutto segno se questo numero rappresenta una frazione troppo alta di
"rta".
* "rtf": il numero di rilasci nella lista "torture freelist"
* "rtmbe": Un valore diverso da zero indica che rcutorture crede che
rcu_assign_pointer() e rcu_dereference() non funzionino correttamente. Il
valore dovrebbe essere zero.
* "rtbe": un valore diverso da zero indica che le funzioni della famiglia
rcu_barrier() non funzionano correttamente.
* "rtbke": rcutorture è stato capace di creare dei kthread real-time per forzare
l'inversione di priorità di RCU. Il valore dovrebbe essere zero.
* "rtbre": sebbene rcutorture sia riuscito a creare dei kthread capaci di
forzare l'inversione di priorità, non è riuscito però ad impostarne la
priorità real-time al livello 1. Il valore dovrebbe essere zero.
* "rtbf": Il numero di volte che è fallita la promozione della priorità per
risolvere un'inversione.
* "rtb": Il numero di volte che rcutorture ha provato a forzare l'inversione di
priorità. Il valore dovrebbe essere diverso da zero Se state verificando la
promozione della priorità col parametro "test_bootst".
* "nt": il numero di volte che rcutorture ha eseguito codice lato lettura
all'interno di un gestore di *timer*. Questo valore dovrebbe essere diverso da
zero se avete specificato il parametro "irqreader".
* "Reader Pipe": un istogramma dell'età delle strutture viste dai lettori. RCU
non funziona correttamente se una qualunque voce, dalla terza in poi, ha un
valore diverso da zero. Se dovesse succedere, rcutorture stampa la stringa
"!!!" per renderlo ben visibile. L'età di una struttura appena creata è zero,
diventerà uno quando sparisce dalla visibilità di un lettore, e incrementata
successivamente per ogni periodo di grazia; infine rilasciata dopo essere
passata per (RCU_TORTURE_PIPE_LEN-2) periodi di grazia.
L'istantanea qui sopra è stata presa da una corretta implementazione di RCU.
Se volete vedere come appare quando non funziona, sbizzarritevi nel romperla.
;-)
* "Reader Batch": un istogramma di età di strutture viste dai lettori, ma
conteggiata in termini di lotti piuttosto che periodi. Anche qui dalla terza
voce in poi devono essere zero. La ragione d'esistere di questo rapporto è che
a volte è più facile scatenare un terzo valore diverso da zero qui piuttosto
che nella lista "Reader Pipe".
* "Free-Block Circulation": il numero di strutture *torture* che hanno raggiunto
un certo punto nella catena. Il primo numero dovrebbe corrispondere
strettamente al numero di strutture allocate; il secondo conta quelle rimosse
dalla vista dei lettori. Ad eccezione dell'ultimo valore, gli altri
corrispondono al numero di passaggi attraverso il periodo di grazia. L'ultimo
valore dovrebbe essere zero, perché viene incrementato solo se il contatore
della struttura torture viene in un qualche modo incrementato oltre il
normale.
Una diversa implementazione di RCU potrebbe fornire informazioni aggiuntive. Per
esempio, *Tree SRCU* fornisce anche la seguente riga::
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)
Questa riga mostra lo stato dei contatori per processore, in questo caso per
*Tree SRCU*, usando un'allocazione dinamica di srcu_struct (dunque "srcud-"
piuttosto che "srcu-"). I numeri fra parentesi sono i valori del "vecchio"
contatore e di quello "corrente" per ogni processore. Il valore "idx" mappa
questi due valori nell'array, ed è utile per il *debug*. La "T" finale contiene
il valore totale dei contatori.
특정 kernel build에서 실행
127-151제품 투입 직전처럼 이미 build한 특정 kernel에서 RCU torture를 실행하려면 `CONFIG_RCU_TORTURE_TEST=m`으로 compile합니다. 그러면 `modprobe`로 검증을 시작하고 `rmmod`로 끝낼 수 있습니다.
다음 script는 `rcutorture`를 load하고 한 시간 동안 실행한 뒤 unload하여 `dmesg`의 torture 메시지를 표시합니다.
#!/bin/sh
modprobe rcutorture
sleep 3600
rmmod rcutorture
dmesg | grep torture:
보고서에서 `!!!` 오류 표식을 수동으로 찾거나 자동 검사 script를 작성할 수 있습니다. `rmmod`는 `SUCCESS`, `FAILURE`, `RCU_HOTPLUG` 가운데 하나를 출력하게 합니다. 앞의 두 값은 성공과 실패이고, `RCU_HOTPLUG`는 RCU 자체 문제는 없었지만 CPU hotplug 문제가 발생했다는 뜻입니다.
module 수명과 검증 수명이 일치합니다.
Uso su specifici kernel
=======================
A volte può essere utile eseguire RCU torture su un kernel già compilato, ad
esempio quando lo si sta per mettere in proeduzione. In questo caso, il kernel
dev'essere compilato con CONFIG_RCU_TORTURE_TEST=m, cosicché le verifiche possano
essere avviate usano modprobe e terminate con rmmod.
Per esempio, potreste usare questo script::
#!/bin/sh
modprobe rcutorture
sleep 3600
rmmod rcutorture
dmesg | grep torture:
Potete controllare il rapporto verificando manualmente la presenza del marcatore
di errore "!!!". Ovviamente, siete liberi di scriverne uno più elaborato che
identifichi automaticamente gli errori. Il comando "rmmod" forza la stampa di
"SUCCESS" (successo), "FAILURE" (fallimento), o "RCU_HOTPLUG". I primi due sono
autoesplicativi; invece, l'ultimo indica che non son stati trovati problemi in
RCU, tuttavia ci sono stati problemi con CPU-hotplug.
기준 kernel의 kvm.sh 검증 구성
152-231RCU 자체 변경을 검증할 때는 여러 configuration과 boot parameter로 여러 kernel을 build해야 하는 경우가 많습니다. 이때 `modprobe`와 `rmmod`를 수동 반복하면 오래 걸리고 실수하기 쉽습니다.
x86, arm64, powerpc용 `tools/testing/selftests/rcutorture/bin/kvm.sh`가 이 과정을 자동화합니다. 기본 실행은 `tools/testing/selftests/rcutorture/configs/rcu/CFLIST`에 나열된 각 시나리오를 자동 생성한 최소 userspace initrd가 있는 VM에서 30분씩 실행합니다. 완료 뒤 build 산출물과 메시지를 분석해 오류를 찾고 결과를 요약합니다.
큰 system에서는 `--cpus`로 여러 검증을 병렬화할 수 있습니다. 64-CPU system에서 `--cpus 43`은 최대 43개 CPU를 동시 검증에 사용합니다. 원문이 예로 드는 v5.4에서는 16개 kernel의 build 시간을 제외하고 전체 시나리오 실행이 약 8시간에서 1시간으로 줄었습니다. `--dryrun sched`는 실제 실행 없이 batch 배치를 보여 주므로 `--cpus`에 예약할 CPU 수를 정할 때 유용합니다.
모든 변경에 모든 시나리오가 필요한 것은 아닙니다. Tree SRCU 변경은 `--configs 'SRCU-N SRCU-P'`처럼 필요한 시나리오만 선택할 수 있습니다. 큰 system에서는 같은 시나리오를 여러 복제로 실행할 수 있습니다.
istanze complete contemporaneamente. Per farlo::
kvm.sh --cpus 448 --configs '5*CFLIST'
Oppure, lo stesso sistema, può eseguire contemporaneamente 56 istanze dello
scenario su otto processori::
kvm.sh --cpus 448 --configs '56*TREE04'
O ancora 28 istanze per ogni scenario su otto processori::
kvm.sh --cpus 448 --configs '28*TREE03 28*TREE04'
각 동시 실행은 memory를 소비합니다. `--memory`의 기본값은 512M이며, 더 작은 값을 사용하려면 뒤에서 설명하는 `--bootargs`로 callback-flooding 검증을 disable해야 합니다.
추가 debug 정보에는 `--kconfig 'CONFIG_RCU_EQS_DEBUG=y'`를 사용할 수 있습니다. `--gdb`, `--kasan`, `--kcsan`도 제공됩니다. `--gdb`를 사용하면 한 번의 `kvm.sh` 실행에서 시나리오 하나만 선택할 수 있고, 도구가 안내하는 대로 별도 창에서 `gdb`를 실행해야 합니다.
`--bootargs`로 `rcutorture.stall_cpu=30` 같은 kernel boot parameter를 전달해 CPU stall-warning code 변경을 검증할 수 있습니다. 이 경우 도구가 failure를 보고하는 것이 의도한 시험 결과일 수 있습니다. memory를 줄일 때 callback-flooding을 끄는 예는 다음과 같습니다.
kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \
--bootargs 'rcutorture.fwd_progress=0'
kernel build 전체만 필요하면 `--buildonly`를 사용합니다. `--duration`은 기본 30분을 덮어쓰며 `2d`는 이틀, 원문의 `5min`은 5분, `45s`는 45초 실행을 뜻합니다. 짧은 실행은 드문 boot sequence 오류를 찾는 데 유용할 수 있습니다.
`--trust-make`는 새 kernel build가 이전 build에서 재사용할 수 있는 것을 최대한 활용하게 합니다. 이 옵션을 주지 않으면 tag 파일이 제거될 수 있습니다. 더 특수한 option은 `kvm.sh` source code에 문서화되어 있습니다.
범위, 병렬도, 자원과 debug 기능을 독립적으로 조정합니다.
Uso sul kernel di riferimento
=============================
Quando si usa rcutorture per verificare modifiche ad RCU stesso, spesso è
necessario compilare un certo numero di kernel usando configurazioni diverse e
con parametri d'avvio diversi. In questi casi, usare modprobe ed rmmod potrebbe
richiedere molto tempo ed il processo essere suscettibile ad errori.
Dunque, viene messo a disposizione il programma
tools/testing/selftests/rcutorture/bin/kvm.sh per le architetture x86, arm64 e
powerpc. Di base, eseguirà la serie di verifiche elencate in
tools/testing/selftests/rcutorture/configs/rcu/CFLIST. Ognuna di queste verrà
eseguita per 30 minuti in una macchina virtuale con uno spazio utente minimale
fornito da un initrd generato automaticamente. Al completamento, gli artefatti
prodotti e i messaggi vengono analizzati alla ricerca di errori, ed i risultati
delle esecuzioni riassunti in un rapporto.
Su grandi sistemi, le verifiche di rcutorture posso essere velocizzare passano a
kvm.sh l'argomento --cpus. Per esempio, su un sistema a 64 processori, "--cpus
43" userà fino a 43 processori per eseguire contemporaneamente le verifiche. Su
un kernel v5.4 per eseguire tutti gli scenari in due serie, riduce il tempo
d'esecuzione da otto ore a un'ora (senza contare il tempo per compilare sedici
kernel). L'argomento "--dryrun sched" non eseguirà verifiche, piuttosto vi
informerà su come queste verranno organizzate in serie. Questo può essere utile
per capire quanti processori riservare per le verifiche in --cpus.
Non serve eseguire tutti gli scenari di verifica per ogni modifica. Per esempio,
per una modifica a Tree SRCU potete eseguire gli scenari SRCU-N e SRCU-P. Per
farlo usate l'argomento --configs di kvm.sh in questo modo: "--configs 'SRCU-N
SRCU-P'". Su grandi sistemi si possono eseguire più copie degli stessi scenari,
per esempio, un hardware che permette di eseguire 448 thread, può eseguire 5
istanze complete contemporaneamente. Per farlo::
kvm.sh --cpus 448 --configs '5*CFLIST'
Oppure, lo stesso sistema, può eseguire contemporaneamente 56 istanze dello
scenario su otto processori::
kvm.sh --cpus 448 --configs '56*TREE04'
O ancora 28 istanze per ogni scenario su otto processori::
kvm.sh --cpus 448 --configs '28*TREE03 28*TREE04'
Ovviamente, ogni esecuzione utilizzerà della memoria. Potete limitarne l'uso con
l'argomento --memory, che di base assume il valore 512M. Per poter usare valori
piccoli dovrete disabilitare le verifiche *callback-flooding* usando il
parametro --bootargs che vedremo in seguito.
A volte è utile avere informazioni aggiuntive di debug, in questo caso potete
usare il parametro --kconfig, per esempio, ``--kconfig
'CONFIG_RCU_EQS_DEBUG=y'``. In aggiunta, ci sono i parametri --gdb, --kasan, and
kcsan. Da notare che --gdb vi limiterà all'uso di un solo scenario per
esecuzione di kvm.sh e richiede di avere anche un'altra finestra aperta dalla
quale eseguire ``gdb`` come viene spiegato dal programma.
Potete passare anche i parametri d'avvio del kernel, per esempio, per
controllare i parametri del modulo rcutorture. Per esempio, per verificare
modifiche del codice RCU CPU stall-warning, usate ``bootargs
'rcutorture.stall_cpu=30``. Il programma riporterà un fallimento, ossia il
risultato della verifica. Come visto in precedenza, ridurre la memoria richiede
la disabilitazione delle verifiche *callback-flooding*::
kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \
--bootargs 'rcutorture.fwd_progress=0'
A volte tutto quello che serve è una serie completa di compilazioni del kernel.
Questo si ottiene col parametro --buildonly.
Il parametro --duration sovrascrive quello di base di 30 minuti. Per esempio,
con ``--duration 2d`` l'esecuzione sarà di due giorni, ``--duraction 5min`` di
cinque minuti, e ``--duration 45s`` di 45 secondi. L'ultimo può essere utile per
scovare rari errori nella sequenza d'avvio.
Infine, il parametro --trust-make permette ad ogni nuova compilazione del kernel
di riutilizzare tutto il possibile da quelle precedenti. Da notare che senza il
parametro --trust-make, i vostri file di *tag* potrebbero essere distrutti.
Ci sono altri parametri più misteriosi che sono documentati nel codice sorgente
dello programma kvm.sh.
결과 디렉터리와 성공 요약
232-299실행에 오류가 있으면 `kvm.sh` 결과 끝에 build-time 오류와 runtime 오류 수가 나옵니다. 전체 출력을 파일로 redirect하는 것이 좋습니다. build 산출물과 출력은 `tools/testing/selftests/rcutorture/res` 아래 timestamp 이름의 디렉터리에 저장됩니다.
timestamp 결과 디렉터리를 `kvm-find-errors.sh`에 넘기면 오류를 추출할 수 있습니다.
tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh \
tools/testing/selftests/rcutorture/res/2020.01.20-15.54.23
대개는 파일을 직접 여는 편이 더 편리합니다. 모든 시나리오에 공통인 파일은 timestamp 최상위 디렉터리에 있고, 시나리오별 파일은 `TREE04` 같은 이름의 하위 디렉터리에 있습니다. 같은 시나리오를 여러 번 실행하면 두 번째부터 `TREE04.2`, `TREE04.3`처럼 순번이 붙습니다.
최상위에서 자주 보는 `testid.txt`는 git repository에서 실행했을 때 검증 기준 commit을 기록하고, commit하지 않은 모든 변경은 diff 형식으로 포함합니다.
- `.config`: 해당 시나리오의 Kconfig option을 담습니다.
- `Make.out`: 특정 시나리오의 build 출력을 담습니다.
- `console.log`: 특정 시나리오의 실행 출력을 담습니다. kernel boot 이후 조사할 수 있지만 boot가 실패하면 존재하지 않을 수 있습니다.
- `vmlinux`: kernel image이며 `objdump`와 `gdb` 같은 도구로 분석할 때 유용합니다.
그 밖에도 여러 파일이 있지만 사용 빈도는 낮습니다. 다수는 rcutorture 자체나 관련 도구의 동작을 분석하는 데 쓰입니다.
원문은 v5.4 kernel과 12-CPU system에서 기본 시나리오가 오류 없이 끝난 예를 다음과 같이 제시합니다.
SRCU-N ------- 804233 GPs (148.932/s) [srcu: g10008272 f0x0 ]
SRCU-P ------- 202320 GPs (37.4667/s) [srcud: g1809476 f0x0 ]
SRCU-t ------- 1122086 GPs (207.794/s) [srcu: g0 f0x0 ]
SRCU-u ------- 1111285 GPs (205.794/s) [srcud: g1 f0x0 ]
TASKS01 ------- 19666 GPs (3.64185/s) [tasks: g0 f0x0 ]
TASKS02 ------- 20541 GPs (3.80389/s) [tasks: g0 f0x0 ]
TASKS03 ------- 19416 GPs (3.59556/s) [tasks: g0 f0x0 ]
TINY01 ------- 836134 GPs (154.84/s) [rcu: g0 f0x0 ] n_max_cbs: 34198
TINY02 ------- 850371 GPs (157.476/s) [rcu: g0 f0x0 ] n_max_cbs: 2631
TREE01 ------- 162625 GPs (30.1157/s) [rcu: g1124169 f0x0 ]
TREE02 ------- 333003 GPs (61.6672/s) [rcu: g2647753 f0x0 ] n_max_cbs: 35844
TREE03 ------- 306623 GPs (56.782/s) [rcu: g2975325 f0x0 ] n_max_cbs: 1496497
CPU count limited from 16 to 12
TREE04 ------- 246149 GPs (45.5831/s) [rcu: g1695737 f0x0 ] n_max_cbs: 434961
TREE05 ------- 314603 GPs (58.2598/s) [rcu: g2257741 f0x2 ] n_max_cbs: 193997
TREE07 ------- 167347 GPs (30.9902/s) [rcu: g1079021 f0x0 ] n_max_cbs: 478732
CPU count limited from 16 to 12
TREE09 ------- 752238 GPs (139.303/s) [rcu: g13075057 f0x0 ] n_max_cbs: 99011
각 줄은 시나리오별 완료 grace period 수와 초당 처리율, RCU flavor 상태와 최대 callback 수 등을 보여 줍니다. `CPU count limited`는 시나리오의 CPU 수가 host 한도에 맞게 줄었다는 뜻입니다.
오류 분석 때 구성, build, console과 image를 함께 확인합니다.
Se un'esecuzione contiene degli errori, il loro numero durante la compilazione e
all'esecuzione verranno elencati alla fine fra i risultati di kvm.sh (che vi
consigliamo caldamente di reindirizzare verso un file). I file prodotti dalla
compilazione ed i risultati stampati vengono salvati, usando un riferimento
temporale, nelle cartella tools/testing/selftests/rcutorture/res. Una cartella
di queste cartelle può essere fornita a kvm-find-errors.sh per estrarne gli
errori. Per esempio::
tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh \
tools/testing/selftests/rcutorture/res/2020.01.20-15.54.23
Tuttavia, molto spesso è più conveniente aprire i file direttamente. I file
riguardanti tutti gli scenari di un'esecuzione di trovano nella cartella
principale (2020.01.20-15.54.23 nell'esempio precedente), mentre quelli
specifici per scenario si trovano in sotto cartelle che prendono il nome dello
scenario stesso (per esempio, "TREE04"). Se un dato scenario viene eseguito più
di una volta (come abbiamo visto con "--configs '56*TREE04'"), allora dalla
seconda esecuzione in poi le sottocartelle includeranno un numero di
progressione, per esempio "TREE04.2", "TREE04.3", e via dicendo.
Il file solitamente più usato nella cartella principale è testid.txt. Se la
verifica viene eseguita in un repositorio git, allora questo file conterrà il
*commit* sul quale si basano le verifiche, mentre tutte le modifiche non
registrare verranno mostrate in formato diff.
I file solitamente più usati nelle cartelle di scenario sono:
.config
Questo file contiene le opzioni di Kconfig
Make.out
Questo file contiene il risultato di compilazione per uno specifico scenario
console.log
Questo file contiene il risultato d'esecuzione per uno specifico scenario.
Questo file può essere esaminato una volta che il kernel è stato avviato,
ma potrebbe non esistere se l'avvia non è fallito.
vmlinux
Questo file contiene il kernel, e potrebbe essere utile da esaminare con
programmi come pbjdump e gdb
Ci sono altri file, ma vengono usati meno. Molti sono utili all'analisi di
rcutorture stesso o dei suoi programmi.
Nel kernel v5.4, su un sistema a 12 processori, un'esecuzione senza errori
usando gli scenari di base produce il seguente risultato::
SRCU-N ------- 804233 GPs (148.932/s) [srcu: g10008272 f0x0 ]
SRCU-P ------- 202320 GPs (37.4667/s) [srcud: g1809476 f0x0 ]
SRCU-t ------- 1122086 GPs (207.794/s) [srcu: g0 f0x0 ]
SRCU-u ------- 1111285 GPs (205.794/s) [srcud: g1 f0x0 ]
TASKS01 ------- 19666 GPs (3.64185/s) [tasks: g0 f0x0 ]
TASKS02 ------- 20541 GPs (3.80389/s) [tasks: g0 f0x0 ]
TASKS03 ------- 19416 GPs (3.59556/s) [tasks: g0 f0x0 ]
TINY01 ------- 836134 GPs (154.84/s) [rcu: g0 f0x0 ] n_max_cbs: 34198
TINY02 ------- 850371 GPs (157.476/s) [rcu: g0 f0x0 ] n_max_cbs: 2631
TREE01 ------- 162625 GPs (30.1157/s) [rcu: g1124169 f0x0 ]
TREE02 ------- 333003 GPs (61.6672/s) [rcu: g2647753 f0x0 ] n_max_cbs: 35844
TREE03 ------- 306623 GPs (56.782/s) [rcu: g2975325 f0x0 ] n_max_cbs: 1496497
CPU count limited from 16 to 12
TREE04 ------- 246149 GPs (45.5831/s) [rcu: g1695737 f0x0 ] n_max_cbs: 434961
TREE05 ------- 314603 GPs (58.2598/s) [rcu: g2257741 f0x2 ] n_max_cbs: 193997
TREE07 ------- 167347 GPs (30.9902/s) [rcu: g1079021 f0x0 ] n_max_cbs: 478732
CPU count limited from 16 to 12
TREE09 ------- 752238 GPs (139.303/s) [rcu: g13075057 f0x0 ] n_max_cbs: 99011
kvm-again.sh로 build 재사용
300-328boot 때 드물게 발생하는 문제를 추적한다고 가정합니다. `kvm.sh`를 그대로 반복하면 매번 kernel을 다시 build합니다. 문제 해결을 확신하기 위해 1,000번쯤 실행해야 한다면 이런 불필요한 rebuild는 매우 번거롭습니다.
이 목적을 위해 `kvm-again.sh`가 제공됩니다. 이전 `kvm.sh` 실행이 다음 결과 디렉터리를 남겼다고 가정합니다.
tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28
이 실행은 kernel을 다시 build하지 않고 다음처럼 반복할 수 있습니다.
kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28
원래 `kvm.sh` option 중 일부, 특히 `--duration`과 `--bootargs`를 덮어쓸 수 있습니다.
kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 \
--duration 45s
이 예는 이전 검증을 같은 build로 다시 실행하되 45초만 수행하므로 앞서 언급한 드문 boot 문제를 찾는 데 도움이 됩니다.
검증한 build를 고정하고 runtime 조건만 반복합니다.
Ripetizioni
===========
Immaginate di essere alla caccia di un raro problema che si verifica all'avvio.
Potreste usare kvm.sh, tuttavia questo ricompilerebbe il kernel ad ogni
esecuzione. Se avete bisogno di (diciamo) 1000 esecuzioni per essere sicuri di
aver risolto il problema, allora queste inutili ricompilazioni possono diventare
estremamente fastidiose.
Per questo motivo esiste kvm-again.sh.
Immaginate che un'esecuzione precedente di kvm.sh abbia lasciato i suoi
artefatti nella cartella::
tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28
Questa esecuzione può essere rieseguita senza ricompilazioni::
kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28
Alcuni dei parametri originali di kvm.sh possono essere sovrascritti, in
particolare --duration e --bootargs. Per esempio::
kvm-again.sh tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28 \
--duration 45s
rieseguirebbe il test precedente, ma solo per 45 secondi, e quindi aiutando a
trovare quel raro problema all'avvio sopracitato.
kvm-remote.sh 분산 실행
329-369`kvm.sh`는 한 system에서만 검증합니다. 여러 system에서 각각 실행하면 kernel을 불필요하게 중복 build하고, 사용 가능한 system에 rcutorture 시나리오를 수동 배분하는 과정도 세심한 주의가 필요해 오류가 생기기 쉽습니다.
이를 위해 `kvm-remote.sh`가 제공됩니다. 먼저 대상 system마다 SSH가 동작하는지 확인합니다.
ssh system0 date
같은 명령이 `system1`부터 `system5`까지에서도 동작하고 각 system이 64 CPU를 갖는다면 다음처럼 실행할 수 있습니다.
kvm-remote.sh "system0 system1 system2 system3 system4 system5" \
--cpus 64 --duration 8h --configs "5*CFLIST"
이 명령은 기본 시나리오를 local system에서 build한 뒤 인수에 나열한 다른 다섯 system에 배포하고 각 시나리오를 8시간 실행합니다. 완료되면 결과를 회수하고 기록한 뒤 출력합니다. `kvm.sh` option 대부분을 사용할 수 있지만 system 목록은 언제나 첫 번째 인수여야 합니다.
`kvm.sh --dryrun scenarios`는 system group에서 동시에 실행할 수 있는 시나리오 수를 알아보는 데 유용합니다.
이전 remote 실행도 `kvm.sh` 결과를 반복한 방식과 마찬가지로 다시 실행할 수 있습니다.
kvm-remote.sh "system0 system1 system2 system3 system4 system5" \
tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28-remote \
--duration 24h
이 경우 반복할 실행의 산출물 디렉터리 경로 뒤에 `kvm-again.sh` option 대부분을 사용할 수 있습니다.
kernel은 한 번 build하고 여러 host에 시나리오를 배포합니다.
Esecuzioni distribuite
======================
Sebbene kvm.sh sia utile, le sue verifiche sono limitate ad un singolo sistema.
Non è poi così difficile usare un qualsiasi ambiente di sviluppo per eseguire
(diciamo) 5 istanze di kvm.sh su altrettanti sistemi, ma questo avvierebbe
inutili ricompilazioni del kernel. In aggiunta, il processo di distribuzione
degli scenari di verifica per rcutorture sui sistemi disponibili richiede
scrupolo perché soggetto ad errori.
Per questo esiste kvm-remote.sh.
Se il seguente comando funziona::
ssh system0 date
e funziona anche per system1, system2, system3, system4, e system5, e tutti
questi sistemi hanno 64 CPU, allora potere eseguire::
kvm-remote.sh "system0 system1 system2 system3 system4 system5" \
--cpus 64 --duration 8h --configs "5*CFLIST"
Questo compilerà lo scenario di base sul sistema locale, poi lo distribuirà agli
altri cinque sistemi elencati fra i parametri, ed eseguirà ogni scenario per
otto ore. Alla fine delle esecuzioni, i risultati verranno raccolti, registrati,
e stampati. La maggior parte dei parametri di kvm.sh possono essere usati con
kvm-remote.sh, tuttavia la lista dei sistemi deve venire sempre per prima.
L'argomento di kvm.sh ``--dryrun scenarios`` può essere utile per scoprire
quanti scenari potrebbero essere eseguiti in gruppo di sistemi.
Potete rieseguire anche una precedente esecuzione remota come abbiamo già fatto
per kvm.sh::
kvm-remote.sh "system0 system1 system2 system3 system4 system5" \
tools/testing/selftests/rcutorture/res/2022.11.03-11.26.28-remote \
--duration 24h
In questo caso, la maggior parte dei parametri di kvm-again.sh possono essere
usati dopo il percorso alla cartella contenente gli artefatti dell'esecuzione da
ripetere.
요약·해설
torture.rst:1-369이 문서는 rcutorture module의 보고서 필드와 정상 기대값, 특정 kernel build에서의 실행법, 기준 kernel용 VM 자동화와 결과 분석, build 재사용 및 여러 host 분산 실행을 다룹니다.
로컬 이탈리아어판에는 `rcutortute.`, `test_bootst`, `--duraction`처럼 현재 영어판과 다른 오래된 표기가 있습니다. 원문과 줄 좌표에는 그대로 보존하고 한국어 해설에서는 실제 의미와 문맥을 함께 밝혔습니다.