在linux中计算页面错误导致混淆结果

我正在编写程序来计算Linux系统中页面错误的时间。 更准确地说,内核执行函数__do_page_fault
不知何故,我写了两个全局variables,名为pfcount_at_begpfcount_at_end ,当函数__do_page_fault在函数的不同位置执行时会增加一次。

为了说明,修改的函数如下所示:

 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 } 

我期望pfcount_at_end的值小于pfcount_at_beg的值。

因为我认为,每次内核执行代码pfcount_at_end++的指令时,它都必须执行pfcount_at_beg++ (每个函数都从代码的最开始)。
另一方面,这两行代码之间有很多条件return

但结果却相反。 pfcount_at_end的值大于pfcount_at_end的值。
我使用printk通过自定义的syscall来打印这些内核variables。 我写了用户级别的程序来调用system call

这是我简单的syscall和用户级程序:

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

有没有人知道在这个过程中究竟发生了什么?

刚才我修改了代码,使pfcount_at_begpfcount_at_end static 。 但是结果并没有改变,即pfcount_at_end的值大于pfcount_at_end的值。 所以可能是由primefaces内增量操作引起的。 如果我使用读写锁,会更好吗?

++运算符不保证是原子的,所以你的计数器可能会遇到并发访问并且有不正确的值。 你应该保护你的增量作为临界区,或使用<asm/atomic.h>定义的atomic_t类型及其相关的atomic_set()atomic_add()函数(以及更多)。

不直接连接到你的问题,但使用特定的系统调用是矫枉过正(但也许这是一个练习)。 更轻的解决方案可能是使用/proc条目(也是一个有趣的练习)。