[완료]리눅스 workqueue
글쓴이: jungwook / 작성시간: 월, 2010/02/01 - 11:02오후
안녕하세요?
지금 리눅스 커널에 대해 공부하고 있는데, 모르는 부분이 나와 질문드립니다.
인터럽트 관련 챕터를 보고 있는데, workqueue 관련하여 질문하겠습니다.
책에서는 지연처리를 위해 인터럽트 처리를 지연시키기 위해 소프트 인터럽트와 tasklet사용하고, workqueue는 주로 프로세스 콘텍스트의 처리를 지연시키기 위해
이용하고 있다고 나와있네요.
소프트 인터럽트와 tasklet은 책을 보며 이해를 하였는데, 프로세스 콘텍스트의 처리를 지연시킨다는 말이 정확히 이해가 되지 않네요.
즉, 콘텍스트 스위치가 발생할 때 어떤 부분을 지연시킨다는 것은 아닌것 같고,
기능이, 지정한 처리를 복수로 등록해 두고, 나중에 실행을 지시하는 것이라는데, 어떤 처리인가요?
다른 책을 보니, 지연가능한 함수와 work queues는 꽤 다른데, 주요 차이는 연기가능한 함수는 인터럽트 콘텍스트 안에서 발생하고 반면에 work queue안의 함수는 프로세스 콘텍스트에서 동작한다.
이해가 잘 되지 않네요. @.@
즉, 어떤 경우에 workqueue를 사용하는지 아시는 분은 답변 부탁드릴께요.
Forums:
인터럽트를 처리하기
인터럽트를 처리하기 위해선 Linux에선 3가지 방법이 있습니다.
softirq, tasklet, work queue
가 그것이죠.
인터럽트란 HW적으로 CPU에 interrupt를 만들어 무엇인가 처리해야 할일을 처리하게끔(?) 만드는 역할을 합니다. 키보드를 누를때도 인터럽트가 발생하고, USB에 장치를 연결해도, 심지어 time tick을 처리하기 위해서도 1초에 300번정도(커널설정에 따라 변경 가능(i.e. 1000)) HW interrupt가 발생합니다. HW적으로 인터럽트핀이 CPU를 깨워서 인터럽트가 걸리면 맨앞 핸들러로 뛰어서 어떤인터럽트가 걸렸는지 확인하는 루틴이 실행됩니다. 이 루틴안에서 어떤 인터럽트인지 확인하고 다음처리를 담당하게 되죠. 그러나 주위해야하는점은 어떤 HW 인터럽트가 먼저 걸렸을때엔 다른 HW 인터럽트가 걸리지 않게 됩니다(인터럽트 pin을 SW적으로 내리기 전까진). 즉,응답성을 위해선 인터럽트 핸들러에선 정말 간단하게 어떤 인터럽트인지만 확인하고, 바로 인터럽트를 해제하지 않으면 그사이엔 어떠한 HW 인터럽트가 발생되지 않아 시스템의 응답성이 떨어지게 되겠죠.. 바로 HW인터럽트를 받아서 인터럽트핀을 해제하고 약간 지연되게 처리하는 방법이 위의 3가지라고 보시면 됩니다.
softirq
32가지 미리 정의된 인터럽트들을 정의하고, 인터럽트 핸들러가 종료되서 인터럽트 가능한 상태로 바뀌면 바로 softirq가 실행된다. 가장 높은 우선순위를 가지고 있으며, 고정된 인터럽트들을 처리하기 위해서 사용합니다. 현재 커널은 32가지중 6가지만 사용합니다. 종류는 HI_SOFTIRQ(높은 우선순위), TIMER_SOFTIRQ(타이머), NET_TX_SOFTIRQ(네트워크 패킷송신), NET_RX_SOFTIRQ(네트워크 패킷수신), SCSI_SOFTIRQ(SCSI), TASKLET_SOFTIRQ(태스크릿들)이고, HI_SOFTIRQ가 우선순위가 가장높게 처리됩니다.
tasklet
동적으로 할당된 softirq라고 생각하면 됩니다. 위 softirq의 SCSI_SOFTIRQ가 처리되고나서 TASKLET_SOFTIRQ가 처리되는데 이때엔 동적으로 할당을 받아서 처리하고 싶은 handler를 등록하고 처리하게 됩니다.
work queue
softirq나 tasklet들이 실행중에는 sw인터럽트중이라, hw 인터럽트는 가능하지만, 여전히 sw적으로 우선적으로 처리되는것들입니다. 즉 softirq중에는 user process들이나, context switch등은 처리되지 않고 있겠죠. 모든 sw irq를 softirq로만 처리한다면 user process나 context switch등은 처리안되어 유저입장에선 상당히 반응성이 안좋은 커널이라 생각할수 있습니다. 그래서 context switch등과 동일한 level에서 스케쥴링되는 work queue를 두어 sw interrupt들이지만 상당히 시간을 요하거나 계산해야될게 많은 작업들 혹은 휴면이 필요한 I/O작업이 필요한 일들은 context switch될때 같이 되게 만들어 주어 커널 응답성을 좋게 해줄수 있습니다.
와 설명 잘 해주시네요.
전에 봤던 건데 까먹고 있다가 여기서 읽어보고 아, 그랬구나 생각나고 좀 더 정리가 됐습니다. 감사합니다.
헛.. 답변
헛.. 답변 감사드립니다.
아주 쉽게 명확하게 이해가 되네요.
즉, sw 인터럽트에서 시간이 상당히 오래 걸리고 계산량이 많은 작업은 context switch가 될때 같이 실행을 시킴(kernel thread가 실행시킨다고 책에 나오더라고요.) 으로써 반응성을 높히는 방법으로 이해하면 되겠네요.
그리고 32개의 미리 정의된 인터럽트란 무엇이죠? 현재 6개만 사용한다고 나와있는데, 나머지는 어떤것인지 궁금하네요.
여기서 하나 더 궁금한건 만약 키보드를 누름으로써 인터럽트가 발생하게 되면, 하드웨어 인터럽트가 발생하고, 그 후에 softirq가 발생하는 건가요??
하지만 현재 정의된 소프트 irq는 HI_SOFTIRQ(높은 우선순위), TIMER_SOFTIRQ(타이머), NET_TX_SOFTIRQ(네트워크 패킷송신), NET_RX_SOFTIRQ(네트워크 패킷수신), SCSI_SOFTIRQ(SCSI), TASKLET_SOFTIRQ(태스크릿들) 인데 여기엔 정의가 되어 있지 않은 것 같은데, 어떻게 처리가 되는지 궁금하네요.
즉, 궁금한 것은 모든 인터럽트는 hw 인터럽트가 발생되고, softirq나 tasklet, work queue가 뛰다라 해당 hw 인터럽트를 처리하기 위해 발생하지 않나 하는 것입니다.
32개가 미리
32개가 미리 정의되어있다는 의미는 kernel내부에 softirq배열값이 32 size로 잡혀있고, 그중 현재는 6개만 등록되어서 사용중입니다. 그값이 많으면 많을수록 순차적으로 실행될테니(HI_SOFTIRQ가 먼저실행), 구지 우선순위를 두고싶지 않은것들까지 순위대로 매겨지는 불편함을 없애고자 TASK_SOFTIRQ에서는 커널에서 나중에 필요되어진것들을 동적으로 할당해서 같은우선순위대로 처리하도록 되어있습니다.
만약 키보드를 누르면 HW interrupt가 발생해서 interrupt vector 맨앞에 있는 handler에서 HW interrupt를 해제시켜주고, softirq를 raise시켜줍니다. 그럼 kernel은 interrupt handler가 끝남과 동시에 softirq가 raise되어있는지를 체크해서 do_softirq()를 실행하여 현재 pending되어있는 softirq를 실행시켜주죠. 키보드 핸들러는 아마도 HI아니면 TASKLET중하나일텐데 찾아보지 않아서 잘모르겠네요..
work queue는 좀더 헤비한일을 처리하기 위해, kernel thread를 work queue로 구현 많이 합니다. 커맨드 창에서 "top"을 실행시켜보면, 많은 kernel thread가 실행되는것 보실수 있습니다.
kthreadd
ksoftirqd // softirq를 스케쥴링하는 kernel thread
events
kblockd
khubd // USB device를 관리하는 허브 thread
kseriod // termios로 키보드 input을 처리하는 thread
kswapd // memory swap관리
kpsmoused // mouse event 처리
udevd
reiserfs
답변 감사합니다.
속 시원하게 해결되었네요.
더 궁금한 점은 이제 제가 찾아보겠습니다.
답변 감사드립니다.
댓글에 대해 질문이요
32가지 미리 정의된 인터럽트들을 정의하고, 인터럽트 핸들러가 종료되서 인터럽트 가능한 상태로 바뀌면 바로 softirq가 실행된다.
여기서 말하는 인터럽트 핸들러는 hw 인터럽트 핸들러겠죠? 이게 종료되면 바로 softirq가 실행된다고 하셨는데
그럼 모든 인터럽트에 대해서 softirq가 실행되는건가요?? 그럼 안되지 않나요???
제가 잘은 모르지만 do_IRQ() 내에서 irq_exit()가 호출될 때, pending된 softirq가 있을 때 invoke_softirq()가 호출되고 이건 또
__do_softirq()를 호출해 sw 인터럽트 핸들러가 실행되는걸로 알고 있는데 제가 아는게 맞는지 답변해 주시면 감사하겠습니다. ^^
와 설명 감사합니다.
코드부터 봐가면서 인터럽트 과정을 공부하다가 답답했던게 해결되었네요
도움정말많이되는글이네요 ㅋㅋ
감사합니다 조금 헷갈리는부분들이 뻥 뚫리는 기분이네요 좋은글!!
댓글 달기