리눅스 커널의 spin lock

totohero의 이미지

spin lock은 lock을 얻지 못하였을 때 re-schedule하는 오버헤드보다

잠시 busy waiting하는 것이 더 낫다고 예측 가능한 경우에만

사용하는 것입니까? 그렇다면 lock을 얻지 못하였을 때 re-schedule하는

mutex를 대신 사용해도 behavior는 변함이 없는지요?

sliver의 이미지

인터럽트 핸들러가 사용하는 데이터를 보호할 때는 인터럽트 disable + spinlock를 사용해야 합니다.
인터럽트 핸들러가 수행되는 도중 rescheduling이 일어나면 안되기 때문이죠..
이 외의 경우에는 mutex를 써도 될 것 같은데 확실히는 모르겠네요.

darkblue99의 이미지

흠. spinlock을 쓸때 궁금한게 있어서요.
문서를 보면 spin lock은 multiprocessor일때 사용한다고 되어 있는 경우를 봤구요.. semaphore를 uni/multi P일경우 다 써도 된다고 되어 있더군요.
그런데 define되어 있는거보면
그게 아니라 그냥 interrupt lock이거든요..

또 semaphore란게 분명 resource 와 관련있는것이지 critical section과는 분명 별로 상관없는 것으로 알고 있고 또.. 그래서 semaphore와 mutex란게 분명히 다른것인데.. semaphore를 kernel에서 쓸때는 DECLARE_MUTEX()란 macro로 쓰고요..
그러다 보니 용어에 좀 혼선이 와서그런데
고수님이 정리를 해주시져.

1. critical section보호를 위해서 spin lock을 그냥 써도 되는 것인지..
아님 multiprocessor일때만 쓰는게 좋은 것인지..
2. cli() sti()말고 spin lock을 써야할 경우가 어떨때인지.. (이론적으로는 이해합니다만.. 과연 차이가 있나요?)
3. DECLARE_MUTEX()로 선언한 semaphore는
critical section을 보호하기 위한 것인지? 아님 resource 와 관련 있는 것인지..
이게.. atomic하게 실행되는지 .. 아님 resheduling되는 것인지?(resource를 점유할때까지)

헛.. OS 공부할때랑.. (벌써 엄청오래네여 ㅠ_ㅠ)
커널 볼때랑 용어상 차이가 좀 있는듯해서.. 아님 제가 혼동하는 거겠죠 :-)

Be Postive!

hb_kim의 이미지

darkblue99 wrote:
흠. spinlock을 쓸때 궁금한게 있어서요.
문서를 보면 spin lock은 multiprocessor일때 사용한다고 되어 있는 경우를 봤구요.. semaphore를 uni/multi P일경우 다 써도 된다고 되어 있더군요.
그런데 define되어 있는거보면
그게 아니라 그냥 interrupt lock이거든요..

또 semaphore란게 분명 resource 와 관련있는것이지 critical section과는 분명 별로 상관없는 것으로 알고 있고 또.. 그래서 semaphore와 mutex란게 분명히 다른것인데.. semaphore를 kernel에서 쓸때는 DECLARE_MUTEX()란 macro로 쓰고요..
그러다 보니 용어에 좀 혼선이 와서그런데
고수님이 정리를 해주시져.

1. critical section보호를 위해서 spin lock을 그냥 써도 되는 것인지..
아님 multiprocessor일때만 쓰는게 좋은 것인지..
2. cli() sti()말고 spin lock을 써야할 경우가 어떨때인지.. (이론적으로는 이해합니다만.. 과연 차이가 있나요?)
3. DECLARE_MUTEX()로 선언한 semaphore는
critical section을 보호하기 위한 것인지? 아님 resource 와 관련 있는 것인지..
이게.. atomic하게 실행되는지 .. 아님 resheduling되는 것인지?(resource를 점유할때까지)

헛.. OS 공부할때랑.. (벌써 엄청오래네여 ㅠ_ㅠ)
커널 볼때랑 용어상 차이가 좀 있는듯해서.. 아님 제가 혼동하는 거겠죠 :-)

질문 3:
혹 "mutex 는 깊이가 1인 semaphore" 라는 문구를 들어보셨습니까? include/asm/semaphore.h 에 가면 DECLARE_MUTEX 정의가 나오는데 깊이가 1인 semaphore 로 정의 합니다.

질문 1 과 질문 2:
이것은 기술적인 문제라기보다는 coding practice 에 관한 문제입니다.

spinlock 대신에 cli, sti 를 사용해서 Single processor 에서만 돌수 있는 디바이스 드라이버를 만들어 놓고, 나중에 SMP 에서 사용하게 되면 전부 고치시겠습니까?

아니면 그냥 spinlock을 써서 어떠한 플랫폼에서도 돌아갈수 있는 드라이버를 만드시겠습니까?

xfree의 이미지

"spinlock은 어떨때 사용한다"는 것을 익히는것 보다는 spinlock이라는게 나오게 된 배경을 이해하시면 어떤 상황에서 spinlock을 써야 되는지 이해하게 됩니다.

spinlock의 배경 설명은 os책에 자세히 나와있습니다. 제가 본책은 modern operating system 입니다.

kyong의 이미지

totohero wrote:
spin lock은 lock을 얻지 못하였을 때 re-schedule하는 오버헤드보다

잠시 busy waiting하는 것이 더 낫다고 예측 가능한 경우에만

사용하는 것입니까?



Quote:

그렇다면 lock을 얻지 못하였을 때 re-schedule하는
mutex를 대신 사용해도 behavior는 변함이 없는지요?

spin lock 은 sleep 할 수 없고 semaphore는 sleep 할 수 있습니다. 그리니까
semaphore는 process context에서만 lock을 얻을 수 있습니다.
interrupt context에서는 사용할 수가 없습니다.
kyong의 이미지

darkblue99 wrote:
흠. spinlock을 쓸때 궁금한게 있어서요.
문서를 보면 spin lock은 multiprocessor일때 사용한다고 되어 있는 경우를 봤구요.. semaphore를 uni/multi P일경우 다 써도 된다고 되어 있더군요.
그런데 define되어 있는거보면
그게 아니라 그냥 interrupt lock이거든요..

UP환경에서spin lock은 kernel preemption을 위한 marker역할만 합니다.
kernel preemption을 안 쓴다면 진짜 아무 일도 안하죠.
쓰면 안 되는 것은 아니죠.

Quote:

또 semaphore란게 분명 resource 와 관련있는것이지 critical section과는 분명 별로 상관없는 것으로 알고 있고 또.. 그래서 semaphore와 mutex란게 분명히 다른것인데.. semaphore를 kernel에서 쓸때는 DECLARE_MUTEX()란 macro로 쓰고요..
그러다 보니 용어에 좀 혼선이 와서그런데
고수님이 정리를 해주시져.

Revert Love가 쓴 책이 분명 도움이 될 껍니다.
kyong의 이미지

kyong wrote:
totohero wrote:
spin lock은 lock을 얻지 못하였을 때 re-schedule하는 오버헤드보다

잠시 busy waiting하는 것이 더 낫다고 예측 가능한 경우에만

사용하는 것입니까?




busy waiting은 피해야 합니다. 아주 빨리 처리할 수 있도록 간단해야 합니다.
darkblue99의 이미지

Quote:
Revert Love가 쓴 책이 분명 도움이 될 껍니다.

흠.. 전 Silberschatz 와 Galvin이 함께쓴 Opereration System Concepts라는 소위 공룡책으로 공부한 세대이고..
( 공룡책은 bible이죠~ ^^)
그이후론 딱히 OS에 대해 심층적으로 판 책을 본적이 없네요..
험.. 제가 놓친걸수도 있지만..
공룡책에서는 불행히도 spin lock에 대해 자세히 나와있지 않은걸로 기억합니다.
(워낙 오래전이라 -.-?)

생각난 김에 좋은 OS책좀 추천좀 해주시져..

p.s 공룡책은 상당히 추상화 되어 설명이 되어있어서..
가끔 용어의 혼란이나.. 개념과 구현이 다소 다른 경우가 있습니다.
예를들어 공룡책에서는 semaphore가 atomic operation을 보호한다고 하지만 실상은 resource lock이지 atomic operation하고는 좀 차이가 있거든요..
즉, rescheduling관점에서 보면 좀 다른 이야기인데 공룡책에서의 설명만 보면 좀 헷갈릴 가능성이 있지여 :-)
(제가 모르는 것일수도 :-) )

Be Postive!

kyong의 이미지

Quote:

생각난 김에 좋은 OS책좀 추천좀 해주시져..

Alan cox는 Andy Tanenbaum의 Operating Systems를 권하네요.
http://www.ussg.iu.edu/hypermail/linux/kernel/0210.2/1721.html

전 그냥 lkml를 자주 보는 편입니다.

totohero의 이미지

kyong wrote:
spin lock 은 sleep 할 수 없고 semaphore는 sleep 할 수 있습니다. 그리니까
semaphore는 process context에서만 lock을 얻을 수 있습니다.
interrupt context에서는 사용할 수가 없습니다.

솔라리스의 경우엔 interrupt handler에서 (re-schedule되는) mutex를 쓰던데, interrupt context에서 re-schedule하면 안된다는 것은 단지 리눅스 구현에 국한된 (성능 등을 이유로) 선택의 문제인가요?
sliver의 이미지

totohero wrote:
kyong wrote:
spin lock 은 sleep 할 수 없고 semaphore는 sleep 할 수 있습니다. 그리니까
semaphore는 process context에서만 lock을 얻을 수 있습니다.
interrupt context에서는 사용할 수가 없습니다.

솔라리스의 경우엔 interrupt handler에서 (re-schedule되는) mutex를 쓰던데, interrupt context에서 re-schedule하면 안된다는 것은 단지 리눅스 구현에 국한된 (성능 등을 이유로) 선택의 문제인가요?

리눅스의 경우는 interrupt는 interrupt context에서 처리됩니다. 현재 process가 하던 일이 잠시 중단되고 interrupt가 처리되는 것이죠.
하지만 솔라리스에서는 그렇지 않고 interrupt handling을 위해 또 다른 thread를 사용합니다. 각 interrupt마다 thread를 새로 만든다면 overhead가 매우 클 것이기 때문에 그렇게 하지 않고 interrupt threads pool을 관리하여 interrupt가 발생할 때마다 이 pool에서 thread를 하나 선택하여 그 thread가 해당 interrupt를 처리하게끔 합니다. 따라서 interrupt 처리시에 일반적인 동기화 방법(semaphore, mutex 등등 blocking가능한 것들)을 사용할 수 있습니다.
sliver의 이미지

참고로 리눅스에서 interrupt 처리시에 blocking되는 mutex같은 것을 사용하면 안되는 이유 중 하나는,
리눅스 커널은 커널 모드에서 preemptable하지 않기 때문입니다. 즉 schedule()을 호출하기 전까지는 context switch가 발생하지 않는 다는 것을 가정하고 커널이 작성되어 있기 때문에, interrupt handling시에 blocking됨에 따라 context switch가 발생해 버리면 문제가 생기게 됩니다. (이 가정은preemption이 disable된 경우에 해당하는데 enable된 경우에는 잘 모르겠습니다..)

kyong의 이미지

sliver wrote:
참고로 리눅스에서 interrupt 처리시에 blocking되는 mutex같은 것을 사용하면 안되는 이유 중 하나는,
리눅스 커널은 커널 모드에서 preemptable하지 않기 때문입니다.

interrupt context에서 sleep할 수 없다는 것으로 preemptable의 기준으로
삼는 것은 적절하지 않다고 생각됩니다. Solaris에서도 높은 우선 순위를 가진
interrupt thread에 의해서만 preempt되니까요.
익명 사용자의 이미지

위 댓글들의 잘못된 점을 바로잡습니다

일단 spinlock 은 interrupt context 에서만 사용되는게 아닙니다
user context (system call)에서도 많이 사용됩니다.
단지 user context 에서 spin_lock 을 사용할 때, 스케쥴링이 발생하면 곤란하다던가 하면

spin_lock() 대신
spin_lock_bh() 나 spin_lock_irq() 등을 사용해서 softirq 나 irq 를 막습니다.

spin_lock 자체는 인터럽트 상태라든가 스케쥴링과는 전혀 무관한 녀석입니다.

그리고 인터럽트상태에서 커널코드에서 mutex 를 쓸 수 있습니다.
mutex 라는건 sleep 이 발생할 수도 있고, 안 할 수도 있습니다.
단지 인터럽트상태에서 mutex 를 써서 sleep 이 발생하면
스케쥴링이 실행될때.. 즉
schedule() 함수가 자체적으로 패닉을 발생시킵니다.
그래서 안 쓰는 것이죠

댓글 달기

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