[질문] page fault

hultul의 이미지

PPC/kernel-2.4.18 임베디드 환경에서 개발을 하고 있습니다.

POSIX 의 sem_wait() 같은 함수가 분명히 카운트가 0보다 큰데도 이상하게 blocking이 되는 등 이상한 현상이 발생하여 getrusage()로 현재 리소스를 검사했습니다.

그랬더니 rusage struct의 ru_minflt / ru_majflt 가 다음과 같이 나옵니다.
Process A: 82/83
Process B: 85/85
Process C: 84/85

특정 프로세스의 전역 배열로 잡은 버퍼의 크기를 5MB->1MB로 줄여 테스트를 하면 위 값이 약간씩 달라집니다.
man page 를 보면 ru_minflt / ru_majflt 의 의미가 page reclaim / page fault 갯수라고 나오는데 잘 이해가 안됩니다.

고수님들 ru_minflt / ru_majflt 의 의미를 가르쳐 주세염 ㅜㅜ

ssehoony의 이미지

http://doc.kldp.org/Translations/html/The_Linux_Kernel-KLDP/The_Linux_Kernel-KLDP.html

이 문서의 메모리 관련 내용을 보시면 도움이 되실듯 하네요.

mach의 이미지

* 참고로 보시기 바랍니다.
ru_minflt
the number of page faults serviced without any I/O activity;
here I/O activity is avoided by "reclaiming" a page frame from
the list of pages awaiting reallocation.
ru_majflt
the number of page faults serviced that required I/O activity.

참고 :
페이지폴트는 유닉스 계열의 메모리 관리 메카니즘입니다.
먼저 폴트의 원리를 이해해야 합니다.
유닉스는 메모리할당요청이 들어오면 그 즉시 메모리를 할당하지 않습니다.
메모리를 할당하는 시점은 해당 메모리번지가 레퍼런스(액세스)되었을때,
할당을 하게됩니다.
이 말을 잘 생각해보면, 메모리가 실제 할당이 안되었는데, 메모리를 액세스한다?
라는 의문점이 생기겠지요? 당연히, 할당이 안되어 있는 메모리를 액세스했으니,
exception이 발생하지요. 이 경우 exception의 3가지중 하나인 fault가 발생합니다.
가상메모리 메카니즘과 연동하여 의미를 확장하면, 메모리가 디스크로 swap되었다라고
가정해보세요. 그런데, 해당 메모리 번지를 액세스한다면, 이때도 exception이
발생하겠지요? 이때는 해당 메모리 페이지를 주기억장치로 swap해야하겠지요.
그런데, 주기억장치에 비어있는(사용하지 않는) 페이지가 있다면 단순히 해당페이지를 reclaim하면
되겠지만, 비어있는 페이지가 없다면 이때는 가장 덜 사용된 페이지를 디스크등으로
swap 시킨후에 그곳에 원하는 페이지(fault가 난 페이지)를 올려야겠지요?
제가 보기에는 이 두가지를 의미하는 것으로 보입니다.(음... 이 구조체 변수를
실제 사용해본적이 없어서 단지 추측일뿐입니다.)

* 참고 : Fault handler
exception의 3가지 중 하나인 fault는 handler를 달 수 있는 메카니즘을
제공합니다. 즉, recovery루틴을 달 수 있다고 생각하십시요. 또는, 시그널 핸들러와
유사한 루틴을 달수 있다고 보셔도 되고요. 콜백루틴을 달았다고 보셔도 유사합니다.
이러한 루틴을 fault handler라고 부릅니다. 이 폴트핸들러내에서 swap이나
메모리 할당등을 수행하게 됩니다.
다음 시나리오를 예로 들수있겠지요.
1) str = (char *)malloc(100); // 에러검사 안해요. 왜냐면 여기선 귀찮아서....--;
2) *(str +5) = 'a';
3) fault발생
4) 운영체제는 적절한 알고리즘으로 해당 폴트에 대한 핸들링을 수행
5) 다시 2)라인을 재수행하게 함; 이때는 정상적으로 해당 번지에 값을 넣을 수 있음
위에서 3,4,5는 폴트핸들링의 기본 루틴(골격)입니다. 사용자 프로그램은 감지 못합니다.
참 그리고, 이러한 핸들러를 작성할 수 있는 메카니즘제공은 CPU가해주는게 보통이며,
핸들러(소프트웨어)는 운영체제 제작자가 짜는겁니다요. kernel소스에 있겠지요?!

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

preisner의 이미지

mach님 이 말씀하신 내용이 맞습니다만,
제가 이해하고 있는 것과 조금 달라 덧붙입니다.
rusage struct의 ru_minflt, ru_majflt 는 보통 major fault, minor fault
라고 하는데요,
fault라는게 어떤 건지는 mach님이 잘 설명 하셨구요,
그럼 major fault 와 minor fault의 차이는 무엇이냐..
시스템 모니터링 유틸인 sar의 man 페이지를 보면

Quote:

minflt/s
Total number of minor faults the process has
made per second, those which have not
required loading a memory page from disk.

majflt/s
Total number of major faults the process has
made per second, those which have required
loading a memory page from disk.


아마 sar도 getrusage()함수를 호출할것 같습니다.

위의 내용은 disk I/O가 필요한가 아닌가 로 구별하고 있는데요,
disk I/O가 필요한 경우는

Quote:

그런데, 해당 메모리 번지를 액세스한다면, 이때도 exception이
발생하겠지요? 이때는 해당 메모리 페이지를 주기억장치로 swap해야하겠지요.
그런데, 주기억장치에 비어있는(사용하지 않는) 페이지가 있다면 단순히 해당페이지를 reclaim하면
되겠지만, 비어있는 페이지가 없다면 이때는 가장 덜 사용된 페이지를 디스크등으로
swap 시킨후에 그곳에 원하는 페이지(fault가 난 페이지)를 올려야겠지요?

mach님이 이야기하신 내용뿐 아니라 좀더 넓은 의미가 아닐까 생각됩니다.
예를 들어 cache memory에 필요한 내용이 있다면 minor fault가 생기는게 아니겠습니까?
(이 경우 memory를 reallocation할 필요가 없겠구요.)
또한 swap memory의 내용을 가져 온다고 할때 도 major fault가 생기는 것일 테구요.
다시 말해 major, minor fault의 차이는 fault가 발생 했을때 여러 이유로 disk I/O가 생긴다면 major, 안생긴다면 minor로 구별 하는게 아닌가 싶습니다.

disk I/O가 너무 느리기 때문에 나온 구별이 아닌가 생각도 되고요.
좀 더 정확하게 설명을 해 주실 수 있는 분이 있다면 설명해 주시면 감사하겠습니다.
그럼..

pastime의 이미지

int getrusage(struct task_struct *p, int who, struct rusage *ru)
{
    struct rusage r;

    switch(who) {
         case RUSAGE_SELF:
               r.ru_minflt = p->minflt;
               r.ru_majflt = p->majflt;

                         ...
}

majflt 와 minflt 는 프로세스 별로 page fault 예외를 처리하는 횟수를 기록해두는 필드입니다.

리눅스에서는 프로세스가 요청한 페이지를 바로바로 할당해 주지 않고
프로세스가 그 페이지를 실제로 사용하는 시점까지 할당을 미루게 됩니다.
이것은 프로세스가 처음부터 자신의 주소 공간에 들어있는 모든 주소에 접근하지는 않는다는
관찰 결과에서 비롯된 것입니다... (라고 책에 나와있군요.. ^^; )

암튼 그래서 해당하는 페이지가 프로세스가 사용하기로 한 주소공간에는 들어있지만 실제로 할당받지 않은 경우에
페이지 폴트가 일어나게 되고
이때는 단순히? 페이지를 요청(reclaim) 하여 새로 할당받기 때문에
디스크에는 접근할 필요가 없게 됩니다.
이것을 minor page fault 라고 하며 이때 프로세스의 minflt 값을 증가시킵니다.

하지만 이미 할당받은 페이지가 스왑 아웃되어 디스크 상에 저장되어 있을 때
이 페이지에 대한 접근이 일어나게 되면
역시 페이지 폴트가 일어나게 되고
이때는 디스크 상의 페이지를 메모리로 스왑 인 하게 됩니다.
이것을 major page fault 라고 하며 이때는 프로세스의 majflt 값과 mm->rss 값을 증가시킵니다.

hultul의 이미지

정말로 감사합니다 여러분들 흑흑

코더에서 프로그래머까지

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.