Stavo scrivendo programmi per contare il tempo di errori di pagina in un sistema Linux. Più precisamente, il kernel del tempo esegue la funzione __do_page_fault
.
E in qualche modo ho scritto due variabili globali, denominate pfcount_at_beg
e pfcount_at_end
, che aumentano una volta quando viene eseguita la funzione __do_page_fault
in diverse posizioni della funzione.Confusione del risultato del conteggio di errori di pagina in linux
Per illustrare la funzione modificata va come:
unsigned long pfcount_at_beg = 0;
unsigned long pfcount_at_end = 0;
static void __kprobes
__do_page_fault(...)
{
struct vm_area_sruct *vma;
... // VARIABLES DEFINITION
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
pfcount_at_beg++; // I add THIS
...
...
// ORIGINAL CODE OF THE FUNCTION
...
pfcount_at_end++; // I add THIS
}
ho aspettato che il valore di pfcount_at_end è inferiore al valore di pfcount_at_beg.
Perché, penso, ogni volta che il kernel esegue le istruzioni del codice pfcount_at_end++
, deve aver eseguito pfcount_at_beg++
(Ogni funzione inizia proprio all'inizio del codice).
D'altra parte, poiché ci sono molti condizionali return
tra queste due righe di codice.
Tuttavia, il risultato risulta opposto. Il valore di pfcount_at_end
è maggiore del valore di pfcount_at_beg
.
Io uso printk
per stampare queste variabili del kernel attraverso un auto-definito syscall
. E ho scritto il programma a livello utente per chiamare lo system call
.
Qui è la mia semplice programma syscall
e a livello utente:
// syscall
asmlinkage int sys_mysyscall(void)
{
printk(KERN_INFO "total pf_at_beg%lu\ntotal pf_at_end%lu\n", pfcount_at_beg, pfcount_at_end)
return 0;
}
// user-level program
#include<linux/unistd.h>
#include<sys/syscall.h>
#define __NR_mysyscall 223
int main()
{
syscall(__NR_mysyscall);
return 0;
}
C'è qualcuno che sa cosa esattamente è accaduto durante questo?
Proprio ora ho modificato il codice, per rendere pfcount_at_beg
e pfcount_at_end
static
. Tuttavia, il risultato non è cambiato, ad esempio il valore di pfcount_at_end
è maggiore del valore di pfcount_at_beg
. Probabilmente potrebbe essere causato dall'operazione di incremento in-atomico. Sarebbe meglio se usassi il blocco di lettura-scrittura?
Penso che la possibilità più probabile sia che tu abbia un bug nel tuo 'syscall' o programma a livello utente e che le variabili siano mescolate lassù. Anche se un'altra cosa da considerare è se si sta accedendo alle due variabili atomicamente e, in caso contrario, se è probabile che vi siano errori di pagina nel frattempo. – Graeme
@Graeme Ho aggiunto il mio programma 'syscall' e il programma a livello utente nella domanda. Sono relativamente semplici perché è stato un esercizio per sperimentare come 'syscall' è implementato. –
È questo il vero codice syscall? Alla stampante mancano i valori effettivi da stampare. –