ISR 에서 msleep 하면 죽는 이유? 점점 흥미로워 지네요..
글쓴이: bily / 작성시간: 화, 2006/12/19 - 11:10오전
아래에도 질문을 올렸지만... 이 부분을 보다 보니..점점 흥미로워지네요.
실제, ISR 에서 msleep 를 하면 죽습니다.
저 역시, ISR 에서 msleep을 하지 마라는 이유는 빠른 ISR 의 처리를 위해서라고 알고 있었죠.
그런데, 단순히 빠른 ISR 을 위한것이라면,
실제 테스트 해보니 죽는건 왜 일까요?
..
msleep 코드를 주욱 따라가 보면,
msleep -> schedule_timeout_uninterruptible() -> schedule_timeout
-> schedule() 로 가게 됩니다.
마지막이 schedule() 라는 것이죠.
그 다음, 실제로 에러를 발생 시킨 곳은
if(unlikely(in_atomic() && !current->exit_state)
{
printk("... BUG: scheduling while atomic:"
}
입니다.
도대체 msleep 의 무엇이 걸려서 이런 에러를 내는 걸까요?
현재 생각으로는 in_atomic() 에서 인터럽트가 금지 되었으므로, 0으로 리턴되서
그냥 죽는걸로 추측되네요...
혹시 schedule 과 관련하여 단서가 될만한 부분이 있으면..
조언 부탁합니다. 왜 죽는지 너무 궁금하군요..
Forums:
isr 내부에서는 스케쥴링이 불릴 수 없습니다.
isr 내부에서는 스케쥴링이 불릴 수 없습니다.
msleep 에 의해서 schedule 이 불려졌고 schedule 내부에서 atomic 하게 처리가 되어야 할 상황이었다고 판단을 하고(if 문) 이것은 kernel bug 이기 때문에 디버깅 메세지를 출력하고(아키텍쳐의 구현마다 다릅니다만) 죽게되는 것입니다.
네. 답글 감사합니다.
네. 답글 감사합니다.
그러나, 여전히 근원적인 의문이 있습니다. 말씀하신대로, 왜 ISR 내부에서는 스케줄링이 불릴수가 없는거죠?
모든 자료를 뒤져보고 있는데, 전부 isr 에서는 스케줄링을 하지 마라고 하는데, 왜 하면 안되는지에
대한 답이 없네요.
구현마다 다르겠지만서도..
현재 상황으로 봐서는..만일 isr 중에 다른 인터럽트가 온다면 그 쪽으로 넘어 가도록 하겠다는 생각은
원천적으로 막혀 있는 것 아닌가요? 스케줄링 또는 sleep 등이 안되니 말이죠..
구현마다 다르지
구현마다 다르지 않습니다. 교수님이 학생을 가르치는 방식으로 하면..
빌려온 책을 책 보는 중에 초인종이 울리더란 말이지.
책갈피를 책에다 꽂아놓고 누군가 가봤더니 잡상인이야.
이런 제길! 하고 돌아오는 중에 다른 재밌을 것 같은 책이 눈에 띄더라 이거야.
잠시 멈춰서서 그 책을 들쳐보고 있는데 초인종이 또 울려.
이러언! 하고는 책갈피를 찾아봤는데 처음에 보던 책에 꽂아놓은 것 밖에 없더구만.
그놈을 뽑아서 새로 보던 책에 꽂아놓고 누군가 가봤더니 책주인이네.
빌려준 책에 대해 물어보는데 뭐 대답할게 있나... 마저 보고 알려주겠다하고 그냥 와야지.
그 책을 다시 볼려니 어디까지 읽었는지 알 수가 없네 그랴. 망할 책갈피를 다른 책에 사용한 탓이지.
이걸 어쩌면 좋나. 어 ? 어디 자네가 대답해보게.
netsted interrupt는
netsted interrupt는 가능하고...많은 경우에 발생을 하고요..
지금 설명하신거는 nested interrupt가 불가하는 말씀인가요 ?
용어에 대해 먼저
용어에 대해 먼저 물어보겠습니다.
잡상인과 대화를 나누는 도중에 책 주인이 찾아온 경우를 말씀하시는 건가요,
아니면 "8층에 계신 주민 들은 지금 즉시 현관문을 열고 밖으로 나와보세요." 식의 아파트 안내방송을 말씀하시는 건가요 ?
해결
해결 했습니다.preemp_count 가 답입니다.
하려고 했던 일이
하려고 했던 일이 뭔지 모르겠지만,
preemption 과 ISR내부의 schedule() 콜이 무슨 상관인지...
2.4 용으로 배포되던 preemption 패치는 arm 커널에서 누락된 부분이 있긴했습니다.
irq core 쪽이 좀 미흡했죠. 2.6은 살펴보지 않아서 모르겠고요.
어쨌거나 질문의 원래 내용과 무슨 관련이 있는지 모르겠네요.
in_atomic() 때문에 if ()
in_atomic() 때문에 if () 가 참이 되었고, 그래서 panic() 이 불려졌다라고 결론내리신 듯 한데,
그놈이 예전엔 if (in_interrupt()) 처럼 되어 있었습니다.
2.6 에 preemption 이 들어가고 SMP 와 잘 머지되면서 살짝살짝 바뀐 것들.
ISR
뭔가 강제적으로 일을 바꾸기 위해선.. 또는 멈추게 하기 위해선..
많은 비용이 발생합니다... 그러한 비용을 최대한 줄이기 위한 정책이 포함되어 있을 것이구요..
그보다.. ISR의 경우 위에 분이 예를들어 설명하신걸 제가 제대로 이해했다면..
이런경우가 되었겠지요..
ISR을 처리하는 동안 ISR이 또 발생하면 어떻게 되겠느냐 입니다...
그리고 또 그 ISR이 처리되는 동안 또 ISR이 발생된다면..?
ISR을 하나의 프로세스라고 생각하시는분들이 많은 것 같은데..
단지 커널내의 처리 Routine 입니다...
해서 ISR이 처리되는 동안.. 다른 ISR 발생에 대한 처리를 지연시키거나.. 막아야합니다..
당연한 거겠지만 그러기 위해선..
Atomic 하게 일이 진행이 되어야합니다..
시스템에서 Atomic하다는 것은 엄청난 비용으로 연결이 됩니다..
임계처리가 되어야하기 때문에.. 그러한 행위를 원하는 요청이나 신호가 많이 오게 되면...
줄서서.. 기다리게 되는 거지요..
그럼 평범한(!) Process들이 .. 뒤에서.. 어! 우린 언제 실행되?
이런 상황이 됩니다...
아마도 이러한 상황을 최대한 줄이기 위해서..
ISR은 짧게 필요한 일만 처리하고 마치고... 사후에.. 그 짧고 반드시 실행되야 하는 일들로 남은..
정보를 가지고.. 스케줄러를 통해서 처리하게 되지요....
스케줄러는 프로세스에 의해서 불려올 수 있고..
또는 Time tic에 한번씩 정기적으로 능동적으로 스케줄링하기도 합니다..
(자세한 말은 생략하도록 하겠구요..)
도움이 많이 안되서 죄송합니다...
왜라는 물음에 대한 답변은 그걸 쓰기로 결정하기로 한 모든 배경을 설명해야하지만..
지식이 방대하지 못함으로 여기서 마치겠습니다..
댓글 달기