리눅스 커널의 spin lock 구현에 대한 의문점
글쓴이: gurugio / 작성시간: 화, 2009/04/28 - 12:34오전
블로그에 도배해서 죄송합니다~~ ;-)
리눅스 커널의 spinlock 구현을 분석하다보니
최근 커널일 수록 코드가 길어지고
대략 적으로 이런 흐름을 가지고 있는것 같았습니다.
spin_lock()
{
preempt_disable()
if (!_spin_trylock()) _spin_lock()
preempt_enable()
}
의문이 드는 것은 왜 코어부분을 _spin_trylock()과 _spin_lock(), 2개의 매크로 함수로
만들었는가 하는 것입니다.
코드를 보면 중복되는 부분도 있는것 같은데
어떤 의미가 있는지 모르겠습니다.
UP 환경의 구현을 보면 매우 간단하게 값만 읽고 쓰는 것으로 구현되어 있는데
SMP와 어떤 차이로 인해 이렇게 복잡해지는지 궁금합니다.
저는 간단하게 아래처럼 만들어서 실험해봤는데
아직 문제점을 찾지 못했습니다.
왜 굳이 spin_trylock() -> spin_lock 이 필요할까요?
int main(void) { int inc = 1; int unlock = 0; printf("inc=%d unlock=%d\n", lock, unlock); asm volatile ( "1:\n\t" "lock;xchg %0, %1\n\t" "cmpw %w0, %w0\n\t" "jne 1b\n\t" : "+a"(inc), "+m"(lock) : : "memory"); printf("inc=%d unlock=%d\n", lock, unlock); return 0; }
File attachments:
첨부 | 파일 크기 |
---|---|
2cpu.jpg | 43.38 KB |
댓글
이중 검사 잠금이 떠오르는군요.
만일 try lock이 lock보다 비용이 저렴하다면 try lock을 먼저 시도할 수도 있겠지요. spin을 두번 돌리고 싶었는지도...
spinlock 이
spinlock 이 필요이상으로 길어지는 걸 방지하기 위한 거 아닌가요? spinlock 이 길어지는건 리소스의 낭비니까요.
----
Let's shut up and code.
----
Let's shut up and code.
스핀락이 한번
스핀락이 한번 스핀을 하면 그 프로세서는 헤어나지를 못하게 되니까, 아주 최고로 급한 일이라면 모를까 아니라면 다른 모든 작업의 발목을 잡게 되는 일입니다.
대개의 경우에 한번 락을 보고나서 이미 락이 걸려있는 상태라면 티켓만 받고 대기하고 있는게 다수 프로세서 시스템에서 performance scalability 를 최적화 하는 좋은 방법이겠지요.
특정한 코드에서, 처음부터 스핀을 할지 아니면 한번 시도후에 스핀할지의 여부는, 그 코드와 다른 코드에서 스핀락을 잡고 있는 시간을 생각해보면 답이 나오겠지요?
댓글
댓글 감사합니다.
새로운 것을 많이 배웠습니다.
trylock이 필요하다는 것을 알고 CaOS에 들어갈 spinlock을 이렇게 만들어봤습니다.
----
섬기며 사랑하면 더 행복해집니다.
개인 홈페이지가 생겼습니다 http://caoskernel.org
어셈러브를 개편중입니다 http://www.asmlove.co.kr
preempt_disable() 이 아마
preempt_disable() 이 아마 인터럽트를 마스킹하는것으로 보이는데, 주석 처리되었군요?
스핀락을 잡는 과정에서 인터럽트를 마스킹하지 않으면 스핀락을 잡고 나서 인터럽트가 들어오는 경우가 발생을 합니다. 스핀락을 잡고 나서 인터럽트 서비스를 하게 되면 스핀락을 잡고 있는 시간이 매우 길어질 가능성도 있습니다. CPU 가 많은 SMP 환경에서는 락을 세심하게 처리할수록 performance scalability 가 좋아집니다.
조언
조언 감사합니다.
사실 아직 프로세스 관리 부분을 만들지 못해서 커널 선점에 대해 고민만 하고 있었습니다.
제가 알기로는 커널 선점의 금지를 선점 카운터로 관리할 수도 있고 인터럽트 금지로 관리할 수도 있다고
알고 있었습니다. 그래서 리눅스 커널 2.6.29를 보니 선점 카운터로 관리를 하고 있어서
저도 그렇게 만들어볼까 생각하고 있었습니다.
리눅스에서도 인터럽트를 금지시키나요? 제가 커널 소스를 잘못 이해한건지 모르겠습니다.
인터럽트를 금지시키면 스핀락 시간이 짧아지겠지만
인터럽트 응답 시간이 늦어질 것 같습니다.
어떤 trade-off가 있을지 모르겠습니다.
조금더 자세한 조언 부탁드립니다.
----
섬기며 사랑하면 더 행복해집니다.
개인 홈페이지가 생겼습니다 http://caoskernel.org
어셈러브를 개편중입니다 http://www.asmlove.co.kr
선점 금지와
선점 금지와 인터럽트 금지는 구별되어야 할 것 같습니다.
일단 리눅스 내의 구현을 보면 spin_lock도 종류가 여러가지인데 내부적으로 interrupt 금지하는게 있고 안 하는게 있습니다.
별도의 커널을 구현중이고 preemption이 구현되어 있다면 spin_lock 구현 내에서 선점 금지는 하도록 하는게
정신 건강에 좋지 않을까 하네요.
Wrox 에서 Professional
Wrox 에서 Professional Linux kernel Architecture 라고 나왔습니다.
나온지 좀 되었는데 근래에 나온 커널 관련 책 중에서는 제일 자세하게 나온
것 같습니다. 원서라 가격이 좀 비싸기는 한데 책 두께나 내용에 비하면
사서 볼만합니다. 직접 OS 구현까지 하신다면 좋은 참고가 될 것 같네요.
댓글 달기