Linki

2014-12-24 12 views
5

numaralı sayfa hatası sayısından kaynaklanan kafa karıştırıcı sonuç Bir linux sistemindeki sayfa hatalarının sayısını saymak için programlar yazıyordum. Daha kesin olarak, zaman çekirdeği işlevi __do_page_fault yürütür.
Ve her nasılsa pfcount_at_beg ve pfcount_at_end adında iki küresel değişken yazdım. Bu işlev, işlevin farklı konumlarında __do_page_fault işlevi yürütüldüğünde bir kez artar. I pfcount_at_end değeri pfcount_at_beg değerinden daha küçük olduğu tahminLinki

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 
} 

: olarak göstermek için

modifiye işlev gider.

Çünkü bence, çekirdek her zaman pfcount_at_end++ kodunun yönergelerini çalıştırıyorsa, pfcount_at_beg++ çalıştırılmış olmalıdır (Her işlev kodun en başında başlar).
Diğer yandan, bu iki kod satırı arasında çok sayıda koşullu return olduğu gibi. Bununla birlikte, sonuç ters yönde ortaya çıkıyor. pfcount_at_end değeri, pfcount_at_beg değerinden daha büyüktür.
Bu çekirdek değişkenlerini syscall aracılığıyla tanımlamak için printk kullanıyorum. Ve kullanıcı seviyesi programını system call'u aramak için yazdım. tam olarak bu yasananlar bilen herkes

// 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; 
} 

var mı: İşte

benim basit syscall ve kullanıcı düzeyinde programıdır?

Şimdi kodu değiştirdim, pfcount_at_beg ve pfcount_at_endstatic. Ancak sonuç değişmedi, yani pfcount_at_end'un değeri, pfcount_at_beg'un değerinden daha büyük. Bu yüzden muhtemelen atomik olmayan artış işleminden kaynaklanabilir. Okuma-yazma kilidini kullanırsam daha iyi olur mu?

+0

Burada en olası olasılığın, syscall 'veya kullanıcı seviyesi programınızda bir hataya sahip olduğunuzu ve değişkenleri oraya karıştırdığınızı düşünüyorum. Göz önünde bulundurulması gereken diğer bir şey de, iki değişkene atomik olarak erişip erişemeyeceğiniz ve eğer değilse de, ara sıra sayfa hataları oluşup oluşmayacağıdır. – Graeme

+0

@Graeme 'syscall' program ve kullanıcı seviyesi programımı soruya ekledim. Göreceli olarak basitler çünkü syscall'ın nasıl uygulandığını deneyimlemek için bir egzersizdi. –

+0

Gerçek sysmall kodu bu mu? Baskının yazdırılacak gerçek değerleri eksik. –

cevap

0

++ numaralı işleç, atomik olmak için garanti kapsamında değildir; bu nedenle, sayaçlarınız eşzamanlı erişimden etkilenebilir ve yanlış değerlere sahip olabilir. Artışınızı kritik bir bölüm olarak korumalı veya <asm/atomic.h>'da tanımlanan atomic_t türünü ve ilgili atomic_set() ve atomic_add() işlevlerini (ve çok daha fazlasını) kullanmalısınız.

Sorununuza doğrudan bağlı değil, ancak belirli bir sistem çağrısı kullanmak fazla sıkmıyor (ancak belki de bir alıştırmadır). Daha hafif bir çözüm, bir /proc girişini (ayrıca ilginç bir alıştırma) kullanmak olabilir.

İlgili konular