올바로 이해 하고 있는지 확인 탁

익명 사용자의 이미지

understanding the linux kernel 의 7장 처음을 보면...
연속된 페이지를 할당 받을 때는 __get_free_page()를. --> 버디 시스템
객체에 대한 메모리를 얻기 위해서는 kmem_cache_alloc(), kmalloc()을, -
-> slab
연속적이지 않아도 되는 메모리를 위해서는 vmalloc()을, 사용한다고 되
어 있습니다.

버디 시스템이나, slab 등 알고리즘은 이해 했는데요.. 문제는 전체적인
그림이 머릿속에 그려지지 않는다는 것입니다. 배문철 님이 분명 모든 메
모리는 버디시스템으로 할당 해제하고 슬랩을 사용해서 관리된다고 하셨는
데 위의 말에 따르면 어떤 것은 버디로 어떤 것은 slab로.. 따로따로 관
리 되는 다는 말처럼 여겨집니다. (책을 왜 이렇게 썼는지.. 아니면 제가
머리가 나쁜 것인지... 아마 후자 이겠죠...)

그래서 소스를 보았습니다. 소스를 보니 kmalloc()도 ,kmem_cache_alloc
() 도 결국에는 __get_free_page() 를 쓰고 있었습니다. 즉
__get_free_page()는 메모리를 할당하는 가장 밑바닥 함수라는 뜻이 되겠
죠.(버디 시스템을 사용해서..)

또 메모리 해제를 담당하는 free_page()도 __free_page_ok()(버디시스템
을 사용하여 메모리를 해제하는 함수)를 사용하고 있으니 __free_page_ok
() 함수도 메모리를 해제하는 가장 밑바닥 함수라는 뜻이죠...

따라서 버디 시스템은 메모리를 할당 해제하는 가장 근본적인 알고리즘이
다.... 이것이 되겠죠..
아직 사용자 프로세스에서 메모리를 할당 할 때도 버디 시스템을 사용하는
지 확인은 안했지만 배문철 님에 의하면 사용하는 것이라 볼 수 있겠네
요....

그렇게 되면 __get_free_page()가 호출하는 --> alloc_page() -->
__alloc_page() 함수에서 실행되는 kswapd 데몬을 깨우는 부분도 이해가
되네요...

아, 아직 문제가 남아 있는데요... 커널에서 할당하는 메모리 영역은 스왑
핑이 안되지 않나요? 그런데 어떻게 __get_free_page() 호출시 kswapd 를
깨어나도록 소스를 짠걸 까요?

커널 내 메모리 할당에서도 스왑이 일어날 수 있다는 말인가요? 혹 스왑
말고 다른 일로 kswapd를 호출한 것은 아니겠지요?(kswapd가 스왑 말고 다
른 일도 하나요?????전혀 모름)

익명 사용자의 이미지

앗, 배성남님...
이런 이름을 잘 못 적다니 대단히 죄송합니다.
항상 도움을 주셔서 매우 고맙게 생각하고 있습니다.
다음 부턴 실수 안하도록 하지요...

그런데 답변을 읽다가 또 질문이 있습니다.(아직 스왑 부분은 읽지 않았
기 때문에 나중에 생각하고...)

책에 보면 선형 주소 공간을 합치는 부분이 나옵니다.(메모리 요청이 끝나
고 마지막에...) 그런데 굳이 합치는 이유가 무엇인지 모르겠습니다. 어차
피 리스트로 연결 되는데요..
(혹 선형 주소 공간에서도 외부 단편화 문제가 있는 것인지....선형 주소
도 외부 단편화가 생기나요?? 이것도 확실히 모르겠네...혹 디스크립터 용
량을 줄이려는 것인지...)
A와 B의 선형 주소 공간이 같은 영역을 가질 수 있다는 예를 들어 주셨는
데요.. 만일 같을 수 있다면 외부단편화 문제도 없을 것이라는 생각이 듭
니다....
왜 굳이 합치려 노력할까요?(꼭 버디 시스템을 이용하는 것 같다는 생각
이 드네요)

p.s
아이고~~~ 아직도 질문은 산더미 만큼 많고.. 메모리는 그저 멀게만 느껴
지는군요...나머지는 조금 더 공부하고 내일 올리겠습니다....이번주 내
로 개략적인 이해를 끝내고 다음주 부터 스왑 공부하려 하는데 가능할지
모르겠습니다...

익명 사용자의 이미지

질문이 명확하지 않아서 이해를 도울만한 몇가지 글을 써볼려고 합니다.

우선 슬랩할당자로 관리하는 자원은 아래와 같습니다.
주로 커널에서 많이 사용하는 자료구조들이지요..
또, 커스텀 사이즈도 존재합니다. 2의 배수들...

#cat /proc/slabinfo
slabinfo - version 1.1 (SMP)
kmem_cache 64 64 244 4 4 1 252 126
tcp_tw_bucket 120 120 96 3 3 1 252 126
tcp_bind_bucket 226 226 32 2 2 1 252 126
tcp_open_request 177 177 64 3 3 1 252 126
inet_peer_cache 118 118 64 2 2 1 252 126
ip_fib_hash 226 226 32 2 2 1 252 126
ip_dst_cache 288 288 160 12 12 1 252 126
arp_cache 60 60 128 2 2 1 252 126
blkdev_requests 680 680 96 17 17 1 252 126
dnotify cache 0 0 20 0 0 1 252 126
file lock cache 294 294 92 7 7 1 252 126
fasync cache 0 0 16 0 0 1 252 126
uid_cache 226 226 32 2 2 1 252 126
skbuff_head_cache 564 816 160 29 34 1 252 126
sock 234 234 832 26 26 2 124 62
sigqueue 261 261 132 9 9 1 252 126
cdev_cache 1947 1947 64 33 33 1 252 126
bdev_cache 118 118 64 2 2 1 252 126
mnt_cache 118 118 64 2 2 1 252 126
inode_cache 148022 148208 480 18526 18526 1 124 62
dentry_cache 164490 164490 128 5483 5483 1 252 126
filp 960 960 128 32 32 1 252 126
names_cache 23 23 4096 23 23 1 60 30
buffer_head 211288 215320 96 5363 5383 1 252 126
mm_struct 336 336 160 14 14 1 252 126
vm_area_struct 1788 2040 96 51 51 1 252 126
fs_cache 354 354 64 6 6 1 252 126
files_cache 216 216 416 24 24 1 124 62
signal_act 153 153 1312 51 51 1 60 30
size-131072(DMA) 0 0 131072 0 0 32 0 0
size-131072 0 0 131072 0 0 32 0 0
size-65536(DMA) 0 0 65536 0 0 16 0 0
size-65536 0 0 65536 0 0 16 0 0
size-32768(DMA) 0 0 32768 0 0 8 0 0
size-32768 0 1 32768 0 1 8 0 0
size-16384(DMA) 0 0 16384 0 0 4 0 0
size-16384 3 6 16384 3 6 4 0 0
size-8192(DMA) 0 0 8192 0 0 2 0 0
size-8192 2 6 8192 2 6 2 0 0
size-4096(DMA) 0 0 4096 0 0 1 60 30
size-4096 140 140 4096 140 140 1 60 30
size-2048(DMA) 0 0 2048 0 0 1 60 30
size-2048 158 398 2048 92 199 1 60 30
size-1024(DMA) 0 0 1024 0 0 1 124 62
size-1024 240 240 1024 60 60 1 124 62
size-512(DMA) 0 0 512 0 0 1 124 62
size-512 190 376 512 28 47 1 124 62
size-256(DMA) 0 0 256 0 0 1 252 126
size-256 219 345 256 21 23 1 252 126
size-128(DMA) 0 0 128 0 0 1 252 126
size-128 810 810 128 27 27 1 252 126
size-64(DMA) 0 0 64 0 0 1 252 126
size-64 1062 1062 64 18 18 1 252 126
size-32(DMA) 0 0 32 0 0 1 252 126
size-32 17967 17967 32 159 159 1 252 126

슬랩할당자가 이후에 만들어 진것이니..
여전히 버디시스템에 의해서 할당되는
메모리도 있을테죠..

하지만 많은 부분들이 슬랩으로 대체되어서,
void * kmalloc (size_t size, int flags)
{
cache_sizes_t *csizep = cache_sizes;

for (; csizep->cs_size; csizep++) {
if (size > csizep->cs_size)
continue;
return __kmem_cache_alloc(flags & GFP_DMA ?
csizep->cs_dmacachep csizep->cs_cachep,
flags);
}
return NULL;
}
이런식으로 임의적인 사이즈를 슬랩 사이즈로 맞게 변경해서
할당을 합니다.

help me님께서 이해를 더 하셔야할 부분이 바로
메모리 디스크립터란 것입니다.

바로 선형주소에 대한 정보와 페이지디렉토리, 페이지테이블..
등등해서 많은 메모리 관련된 정보를 가지고 있는 커널 자료
구조입니다.

즉 a란 프로세스와 b란 프로세서의 선형주소공간은
같아도.. 저 메모리 디스크립터에 들어있는 페이지디렉토리와
페이지테이블의 위치는 달라서 서로 다른 물리적인 메모리로
맵핑이 되는 것이죠...

그러면 스왑핑과 버디시스템, 페이지를 연관시켜서 생각을해보죠..

커널은 기본적으로 사용자를 불신합니다.
그래서 사용자가 요청하는 메모리는 합당한 접근인지
체크하고 또 할당도, 최대한 늦추다가,
사용되는 시점에 하게됩니다.

하나의 시나리오를 만들어보죠..
프로세스가 0x40000000란 주소에 접근을 시작했습니다.
그러면 페이지 디렉토리와 페이지 테이블을 뒤지겠죠..
그러던중에, 페이지가 메모리내에 존재하지 않고,
스왑아웃 된 상태라면, 커널에서 page_fault가 발생해서
디스크로부터 메모리로 로드를 하겠지요
메모리에 있는 상황이라면, 페이지 테이블에 근거해서
제대로 접근을 할테구요..
이 페이지 테이블을 할당하고 해제하는데,
바로 버디알고리즘이 사용됩니다.

그리고 프로세스가 메모리 할당을 요청하면
아까 말씀드린 메모리 디스크립터가 가진 넘중에
vm_area_struct던가 하는 선형주소를 관리하는
구조체가 있는데, 이 녀석에 할당을 요청하고
실제적인 메모리는 이것이 사용될때 할당되어 사용됩니다.
이게 요구페이징입니다.

요것은 실험해볼 수 있는 방법이

for(;;i++){
pp = (char *)malloc(1024*1024);
printf("pp[%x] %d",pp, i);
}
하고
for(;;i++){
pp = (char *)malloc(1024*1024);
memset(pp, 0x33, 1024*1024);
printf("pp[%x] %d",pp, i);
}

소스의 결과가 서로 다를껍니다.
첫번째의 경우가 훨씬 더 많은 메모리를 할당하고
프로그램이 죽습니다 왜냐면 선형적인 주소 공간은
4기가 까지 할당이 가능하고 실제로 메모리에
접근을 해야 페이지가 할당이 되는데 첫번째의
것은 할당만하고 사용되지 않으니... 실제적인
메모리보다 훨씬 많은 할당이 가능하지요.

그러나 후자는 다릅니다.
할당하고 바로 사용되어서 페이지가 할당이 일어납니다.
이때 할당은 버디 알고리즘을 사용하게 되구요
메모리 할당이 점점 늘어감에 따라 버퍼캐쉬로 사용하던
공간도 끌어다 쓰고 스왑아웃도 하고 하다가 정말
더이상 페이지 할당을 할수 없을때 나는 더 이상 못하겠다 하고
종료가 되는 것이죠.
(저는 디스크버퍼나 리눅스를 부팅시 초기의 메모리 상태 즉
디스크 캐쉬를 지워버릴때 저 두번째 소스를 실행해 줍니다.
실행후에 free명령어를 비교해보세요 ^^);

스왑 아웃에 관한것은,
님이 보시는 책에 16장을 보시면 잘나옵니다
스왑 아웃에 선택되는 페이지가 정해져있습니다.
커널이 사용하는 페이지의 경우엔... 스왑 아웃 대상에서 제외됩니다.
스왑아웃이 된다면 페이지폴트처리나 이런것 때문에
구조가 복잡해 지기 때문에 그냥 커널이 사용하는 메모리는,
계속 메모리에 있다고 보시면 됩니다.

ps 혹시 배문철이란 분이 저를 말하는 것인지..--
그러면 실망입니다.. 전 배성남입니다 ^^

쩝.. 점심때 글을 작성을 하다가 밥먹으로 갔는데,
돌아와서 절전기능을 되돌린다고 esc키를 눌렀더니만,,
작성한 글이 홀라당 날아가 버려서
(폼에서 바로 작성하는 중이었습니다,)
다시 쓸래니까 힘들군요..

익명 사용자의 이미지

할당의 마지막에 인접한 메모리이 영역과 권한이 같다면
병합을 하게 되는데,

그것은 효율(속도, 관리용 자료구조에 할당된 메모리)
때문이겠죠.
영역을 할당하거나 할때 영역맵을 검색을 하는데,
갯수가 많아지면 아무래도 속도에 영향을 많이 미치겠죠..

이와 같은 맥락으로 한가지 알아 두셔야 할 사항이.
영역맵이 32개가 넘어가면 list구조에서 avl tree로
자료구조가 스르륵 바껴 버린답니다.
한번 바뀐 avl은 다시 32개의 영역보다 줄어들어도 계속
avl tree형태로 존재하게 되지요.

보너스; 세그멘테이션 vs 페이징
http//www.ezdoum.com/jsboard/read.php?table=fboard&no=197

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.