커널이 바라보는 가상 메모리 영역
글쓴이: totohero / 작성시간: 금, 2004/10/15 - 12:29오전
어떤 유저 프로세스가 시스템콜을 호출하면, 그 시스템콜은 커널 모드에서 수행되잖습니까? 그렇다면 해당 시스템콜이 수행되는 동안 커널이 바라보는 가상 메모리는 시스템콜을 호출한 프로세스의 가상 메모리와는 다르겠지요? 각 프로세스의 가상 메모리에 대한 내용 (페이지 테이블의 베이스 주소 등등)은 current 포인터(process control block이던가요?)를 따라가다보면 있을 것 같은데, 커널 자체에 대한 가상 메모리 맵핑 상황은 어떻게 알 수 있나요?
Forums:
같습니다.
같습니다.
[quote="hb_kim"]같습니다.[/quote]같다구요? 프로세
같다구요? 프로세스의 가상 메모리와 시스템콜 처리시의 가상 메모리가 같다는 말인가요? 그렇다면 서로 다른 프로세스가 호출하는 시스템콜의 처리시의 가상 메모리는 다르겠네요? 그런데 제가 디바이스 드라이버를 만들때의 경험으로는 장치 발견시, 장치에 대한 정보를 가진 커널 글로벌 객체를 할당 받고, ioctl에서 이 글로벌 객체에 접근하는 식으로 코딩했던것 같은데요?
여기에 설명이 잘 되어 있네요.http://www.csn.ul.i
여기에 설명이 잘 되어 있네요.
http://www.csn.ul.ie/~mel/projects/vm/guide/html/understand/node30.html
처음 세 문장과 맨 마지막 문장 사이의 연결관계가 명확하지가 않군요.
맨 마지막 문장의 의미는, 서로 다른 프로세스가 호출한 시스템콜이 완전히
맨 마지막 문장의 의미는, 서로 다른 프로세스가 호출한 시스템콜이 완전히 서로 다른 메모리 영역을 보게되면, 각 시스템콜(예를 들어 장ㄷ치 드라이버의 ioctl 같은...)이 어떻게 하나의 커널 글로벌 객체(장치를 나타내는 하나의 객체)를 공유할 수 있겠느냐의 의미였는데, 말씀하신 문서를 읽어보니 설명이 되는 듯하군요. 커널 영역으로 할당된 1G 영역은 서로 다른 프로세스 사이에도 변하지 않으니까요. 답변 감사합니다.
다시 궁금증이... ^^; 그렇다면 시스템콜로 user 영역 메모리에 대
다시 궁금증이... ^^; 그렇다면 시스템콜로 user 영역 메모리에 대한 포인터를 넘겨주고 시스템콜이 이 영역을 수정하게 할때, 굳이 커널에, 같은 크기 메모리를 할당하고 copy_from_user/copy_to_user를 할 필요는 없는 것 아닌가요?
시스템 콜에서 복귀했을때는 사용자 모드인데 사용자모드에서는 커널공간의 데
시스템 콜에서 복귀했을때는 사용자 모드인데 사용자모드에서는 커널공간의 데이터를 접근할수 없지 않나요? 그러므로 사용자모드에서 접근가능할수 있게 커널공간의 데이터를 사용자공간의 데이터로 복사해야 할것 같은데요..
커널 공간으로 사용자 메모리를 복사하지 않고, 시스템콜이 사용자 영역을
커널 공간으로 사용자 메모리를 복사하지 않고, 시스템콜이 사용자 영역을 바로 수정하는 식으로 하면 안되냐는 것인데요. 그 경우 사용자 모드에서 커널 공간을 액세스할 일이 없겠죠.
이것은 zero-copy 라고 일컬어지는데, 말로는 일견 간단하게 들리지
이것은 zero-copy 라고 일컬어지는데, 말로는 일견 간단하게 들리지만 실제로 성능/효율등을 감안해서 구현하려면 아주 만만한것은 아니거든요?
"만만치 않다"는 것은 해당 영역을 DMA 버퍼로 쓴다든지, 네트워크 패
"만만치 않다"는 것은 해당 영역을 DMA 버퍼로 쓴다든지, 네트워크 패킷의 일부여서 얼라인먼트 문제가 걸린다든지 하는 걸 말씀하시는지요? 아무튼, 그런 문제가 없이, 크기를 확실히 아는 (예를 들어) 어떤 구조체를 넘겨준다든지 할때에는 굳이 copy_from/to_user로 복사할 필요는 아닌 것이지요? (저는 여태, 같은 물리 메모리를 커널과 사용자 모드에서 바라보는 가상 주소가 다를거라고 생각해서 그 변환이 일어나는 것이리라 생각했는데 말이죠)
Data copy 가 문제가 되는 경우는 소량의 구조체를 복사하는 때가
Data copy 가 문제가 되는 경우는 소량의 구조체를 복사하는 때가 아니고 대량의 블록 데이터등을 복사하는게 더 크겠죠? 보통 패킷 방식의 DMA 를 사용하는 디바이스 드라이버에서 zero-copy 가 고려됩니다. 디바이스가 어짜피 DMA 를 사용해서 데이터 전송을 하는데 이를 다시 CPU 사이클 낭비해 가면서 복사해가면 좀 아깝다는 생각도 들고요. 그런데 보통 블록 데이터라면 I/O 성능 향상을 위해서 블록 캐시를 쓰고 prefetch 등도 하게 되니까, 아무래도 유저 영역의 메모리를 직접 scatter-gather DMA 로 액세스 한다는 컨셉과 잘 안맞게 되구요.
구조체등 소량의 데이터를 주고 받는데는 data copy는 별 문제가 되지 않습니다만, 많은 커널 프로그래밍 초보분들이 실제 설계 밸런스에 대한 감이 없어서 이를 순순히 받아들이지 못하고, 아무래도 효율적으로 하기 위해서 본인의 드라이버에는 mmap() 을 써야 되는것 아닌가 하는 의구심을 떨치지 못하죠.
뭐 사실 그렇게 어려운것 까지는 아니지만 mmap 은 고사하고 패킷 방식의 DMA 을 쓰는 디바이스 드라이버를 설계해서 제품 품질까지 구현해서 내놓을 정도의 실력을 가진 분이면, 이 바닥에서는 "만만치 않은' 실력을 가지신 분이라고 해야겠죠.
[quote="totohero"]다시 궁금증이... ^^; 그렇다면 시스
google에서는 다음과 같은 답변을 들었습니다.
http://groups.google.com/groups?hl=ko&lr=&threadm=ac9276f6.0410201547.35d95ee3%40posting.google.com&rnum=3&prev=/groups%3Fq%3Dtotohero%2540empal.com%26hl%3Dko%26lr%3D%26selm%3Dac9276f6.0410201547.35d95ee3%2540posting.google.com%26rnum%3D3
리눅스 계열 nerd 들은 별별 변명을 다 생각해낼수 있겠지만 사실 그중
리눅스 계열 nerd 들은 별별 변명을 다 생각해낼수 있겠지만 사실 그중 정당한 이유라고 할수 있는것은 제가 볼땐 없습니다.
제가 보기엔 '아직 못했다' 가 정답입니다.
윈도우즈의 IO manager에는 direct IO 라고 유저 모드 액세스에 zero copy 로 DMA 데이터를 쓸수 있도록 해주는 모드가 오래전부터 있어왔습니다.
리눅스에서도 할수 있습니다. 누군가 분명 이미 해놓았을겁니다 - 그것도 여러 군데에서. 다만 아직 아무도 커널 메인트리에 들어가도록 공개하지 않았을 뿐이겠죠. 리눅스 배포판 회사가 아니면서, 리눅스 관련 커널 해킹을 하는 회사에서 흔히 있는 일입니다.
댓글 달기