리눅스 시스템에서 페이지 오류 시간을 계산하는 프로그램을 작성했습니다. 보다 정확하게, 커널이 함수 __do_page_fault
을 실행합니다.
그리고 어쨌든 pfcount_at_beg
및 pfcount_at_end
이라는 두 개의 전역 변수를 작성했습니다.이 변수는 함수의 다른 위치에서 __do_page_fault
함수가 실행될 때 한 번 증가합니다. I는 pfcount_at_end의 값 pfcount_at_beg 값보다 작을 것으로 예상리눅스에서 페이지 오류를 계산하는 데 혼란스러운 결과가 있습니다.
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++
(모든 기능이 코드의 맨 처음부터 시작됨)을 실행해야합니다.
한편,이 두 줄의 코드 사이에는 많은 조건부 return
이 있습니다.
그러나 결과는 반대로 나타납니다. pfcount_at_end
값은 pfcount_at_beg
값보다 큽니다.
printk
을 사용하여이 커널 변수를 자체 정의 된 syscall
을 통해 인쇄합니다. 그리고 system call
으로 전화를 걸기 위해 사용자 레벨 프로그램을 작성했습니다. 정확히이 기간 동안 무슨 일이 있었는지 아는 사람이
// 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;
}
있습니까 : 여기
내 간단한 syscall
및 사용자 수준의 프로그램입니다?
이제 코드를 수정하여 pfcount_at_beg
및 pfcount_at_end
static
으로 만들었습니다. 그러나 결과는 변하지 않았고, 즉 pfcount_at_end
의 값은 pfcount_at_beg
의 값보다 큽니다. 아마도 원자 단위 증가 연산에 의해 발생할 수 있습니다. 읽기 - 쓰기 잠금을 사용하면 더 좋을까요?
내가 생각하기에 가장 가능성있는 것은 당신이'syscall' 또는 사용자 레벨 프로그램에 버그가 있고 거기에 변수가 섞여 있다는 것입니다. 고려해야 할 또 하나의 사항은 두 변수를 원자 적으로 액세스하는지 여부와 그렇지 않은 경우 중간에 페이지 오류가 발생할 가능성이 있는지 여부입니다. – Graeme
@Graeme 질문에'syscall' 프로그램과 사용자 레벨 프로그램을 추가했습니다. 그것들은'syscall'이 어떻게 구현되는지를 경험하기위한 연습 이었기 때문에 상대적으로 간단합니다. –
이것이 실제 시스템 코드입니까? 인쇄물에 실제 값이 누락되었습니다. –