리눅스 커널의 spin lock 구현에 대한 의문점

gurugio의 이미지

블로그에 도배해서 죄송합니다~~ ;-)

리눅스 커널의 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: 
첨부파일 크기
Image icon 2cpu.jpg43.38 KB

댓글

winner의 이미지

만일 try lock이 lock보다 비용이 저렴하다면 try lock을 먼저 시도할 수도 있겠지요. spin을 두번 돌리고 싶었는지도...

sangwoo의 이미지

spinlock 이 필요이상으로 길어지는 걸 방지하기 위한 거 아닌가요? spinlock 이 길어지는건 리소스의 낭비니까요.
----
Let's shut up and code.

----
Let's shut up and code.

hb_kim의 이미지

스핀락이 한번 스핀을 하면 그 프로세서는 헤어나지를 못하게 되니까, 아주 최고로 급한 일이라면 모를까 아니라면 다른 모든 작업의 발목을 잡게 되는 일입니다.

대개의 경우에 한번 락을 보고나서 이미 락이 걸려있는 상태라면 티켓만 받고 대기하고 있는게 다수 프로세서 시스템에서 performance scalability 를 최적화 하는 좋은 방법이겠지요.

특정한 코드에서, 처음부터 스핀을 할지 아니면 한번 시도후에 스핀할지의 여부는, 그 코드와 다른 코드에서 스핀락을 잡고 있는 시간을 생각해보면 답이 나오겠지요?

gurugio의 이미지

댓글 감사합니다.
새로운 것을 많이 배웠습니다.

trylock이 필요하다는 것을 알고 CaOS에 들어갈 spinlock을 이렇게 만들어봤습니다.

//
// If spin-lock is free, it locks spin-lock and returns 1.
// If spin-lock is locked, it returns 0.
//
size_t raw_spin_trylock(spinlock_t *lock)
{
	size_t tmp = 0;
 
 
	asm volatile (
		"movb $0, %b0\n\t"
		"lock;xchgb %b0, %1\n\t"
		: "=&a" (tmp), "+m" (lock->slock)
		:
		: "memory");
 
 
	return tmp;
}
 
 
 
 
 
void spin_lock(spinlock_t *lock)
{
 
	//preempt_disable();
 
	while (!raw_spin_trylock(lock)) {
		//preempt_enable();
		while (spin_is_locked(lock))
			cpu_relax();
		//preempt_disable();
	}
 
 
}

----
섬기며 사랑하면 더 행복해집니다.
개인 홈페이지가 생겼습니다 http://caoskernel.org
어셈러브를 개편중입니다 http://www.asmlove.co.kr
hb_kim의 이미지

preempt_disable() 이 아마 인터럽트를 마스킹하는것으로 보이는데, 주석 처리되었군요?

스핀락을 잡는 과정에서 인터럽트를 마스킹하지 않으면 스핀락을 잡고 나서 인터럽트가 들어오는 경우가 발생을 합니다. 스핀락을 잡고 나서 인터럽트 서비스를 하게 되면 스핀락을 잡고 있는 시간이 매우 길어질 가능성도 있습니다. CPU 가 많은 SMP 환경에서는 락을 세심하게 처리할수록 performance scalability 가 좋아집니다.

gurugio의 이미지


조언 감사합니다.
사실 아직 프로세스 관리 부분을 만들지 못해서 커널 선점에 대해 고민만 하고 있었습니다.

제가 알기로는 커널 선점의 금지를 선점 카운터로 관리할 수도 있고 인터럽트 금지로 관리할 수도 있다고
알고 있었습니다. 그래서 리눅스 커널 2.6.29를 보니 선점 카운터로 관리를 하고 있어서
저도 그렇게 만들어볼까 생각하고 있었습니다.
리눅스에서도 인터럽트를 금지시키나요? 제가 커널 소스를 잘못 이해한건지 모르겠습니다.

인터럽트를 금지시키면 스핀락 시간이 짧아지겠지만
인터럽트 응답 시간이 늦어질 것 같습니다.
어떤 trade-off가 있을지 모르겠습니다.
조금더 자세한 조언 부탁드립니다.

----
섬기며 사랑하면 더 행복해집니다.
개인 홈페이지가 생겼습니다 http://caoskernel.org
어셈러브를 개편중입니다 http://www.asmlove.co.kr

dorado2의 이미지


선점 금지와 인터럽트 금지는 구별되어야 할 것 같습니다.

일단 리눅스 내의 구현을 보면 spin_lock도 종류가 여러가지인데 내부적으로 interrupt 금지하는게 있고 안 하는게 있습니다.

별도의 커널을 구현중이고 preemption이 구현되어 있다면 spin_lock 구현 내에서 선점 금지는 하도록 하는게
정신 건강에 좋지 않을까 하네요.

asiawide의 이미지


Wrox 에서 Professional Linux kernel Architecture 라고 나왔습니다.

나온지 좀 되었는데 근래에 나온 커널 관련 책 중에서는 제일 자세하게 나온

것 같습니다. 원서라 가격이 좀 비싸기는 한데 책 두께나 내용에 비하면

사서 볼만합니다. 직접 OS 구현까지 하신다면 좋은 참고가 될 것 같네요.

댓글 달기

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