workqueue 가 동작하는 상황에서 schedule 이 될 수도 있나요?

rajakym의 이미지

리눅스 임베디드 프로그래밍 중입니다.

create_singlethread_workqueue() 함수를 통해서

first_wq, second_wq 라는 workqueue 두개를 생성합니다.

그리고 각각의 workqueue 를 queue_delayed_work() 함수를 통해 동작시킵니다.

first_wq 와 second_wq 에서 동작하는 work 는 device 의 레지스터에 접근하는 작업입니다.

first_wq {
read(reg1)
read(reg2)
write(reg1)
write(reg2)
}

second_wq {
read(reg1)
read(reg2)
write(reg2)
}

제가 우려하는 부분은 first_wq 의 work 동작중에 schedule() 이 되어 read(reg2) 까지만 동작하고
정상적인 값을 write 하지 못한 채 second_wq 의 work 가 동작하는 상황입니다.

create_singlethread_workqueue() 로 두개의 workqueue task 를 만들었기 때문에
위 상황이 실제로 발생 할 수 있는 건가요?

위 방법을 회피하기 위해서는
workqueue 를 하나만 쓰는 방법밖엔 없나요?

익명 사용자의 이미지

ISR 을 워크 큐로 돌리면 irq disable 같은거 써도 됩니다.

AustinKim의 이미지

워크큐는 커널 스레드 종류인 워커 스레드에서 실행하므로 당연히 Preemption될 수 있습니다.

위 글에서 Concern하시는 것은 A 워크큐를 실행하고 있다가 스케줄링(Preemption)되어 B가 실행할 상황인 것 같습니다.

A란 워크큐가 실행 중일 때 다른 프로세스들이 계속 스케줄러에 큐잉을 하면서 계속
A란 워크큐를 실행 중인 워커 스레드와 자신의 우선 순위를 비교해 달라고 합니다.

이 때 스케줄러는 무조건 우선 순위를 비교합니다.
만약 다른 프로세스가 A란 워크큐를 실행 중인 A란 워커스레드 보다 우선 순위가 높다고 판단하면 A 워크큐를 실행 중인 A 워커 스레드의 struct thread_info.preempt_count 값을 -1만큼 감소시킵니다.

그래서 만약 struct thread_info.preempt_count 값이 0이 되면 Preemption되는 운명을 맞이 합니다.

Preemption되는 시점은 다음과 같습니다.

 1> 인터럽트 핸들링을 마친 후
 2> 시스템 콜 처리를 마무리한 후

preempt_disable() 함수는 현재 실행 중인 프로세스의 struct thread_info.preempt_count 값을 +1만큼 증가시켜서
preemption을 막을 수 있습니다.

따라서 다음 코드를 작성하면 Preemption을 방지할 수 있습니다.

first_wq {
+preempt_disable();
 
read(reg1)
read(reg2)
write(reg1)
write(reg2)
 
+preempt_enable();
}
 
second_wq {
+preempt_disable();
 
read(reg1)
read(reg2)
write(reg2)
+preempt_enable();
}

두 번째로는 뮤텍스를 활용하는 방법입니다.
A 워크큐를 핸들링하는 뮤텍스를 하나 생성한 다음, 뮤텍스로 Preemption이 우려되는 코드를 보호합니다.

first_wq {
+mutex_lock(&mutex_A);
 
read(reg1)
read(reg2)
write(reg1)
write(reg2)
 
+mutex_unlock(&mutex_A);
}
 
second_wq {
read(reg1)
read(reg2)
write(reg2)
}

어짜피 A란 워크큐가 실행 중에 B란 워크큐가 접근하면 뮤텍스를 걸어 놨으니 뮤텍스를 걸어 놓은 코드 앞에서 기다릴 것입니다.

(개인블로그)
http://rousalome.egloos.com

rajakym의 이미지

기 작성된 드라이버 코드에서 register 를 수정하는 workqueue 가 동시에 2개가 돌아가고 있어서 문의 드렸습니다.
답변 주셔서 정말 감사드립니다. 그리고 블로그 애독자입니다. 지금도 보고 있었는데 같은 블로그가 떠서 놀랐습니다. 감사합니다.

댓글 달기

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