workqueue 가 동작하는 상황에서 schedule 이 될 수도 있나요?
글쓴이: rajakym / 작성시간: 화, 2019/01/08 - 3:39오후
리눅스 임베디드 프로그래밍 중입니다.
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 를 하나만 쓰는 방법밖엔 없나요?
Forums:
ISR 을 워크 큐로 돌리면 irq disable
ISR 을 워크 큐로 돌리면 irq disable 같은거 써도 됩니다.
preempt_disable() 이나 뮤텍스를 써보세요.
워크큐는 커널 스레드 종류인 워커 스레드에서 실행하므로 당연히 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되는 시점은 다음과 같습니다.
preempt_disable() 함수는 현재 실행 중인 프로세스의 struct thread_info.preempt_count 값을 +1만큼 증가시켜서
preemption을 막을 수 있습니다.
따라서 다음 코드를 작성하면 Preemption을 방지할 수 있습니다.
두 번째로는 뮤텍스를 활용하는 방법입니다.
A 워크큐를 핸들링하는 뮤텍스를 하나 생성한 다음, 뮤텍스로 Preemption이 우려되는 코드를 보호합니다.
어짜피 A란 워크큐가 실행 중에 B란 워크큐가 접근하면 뮤텍스를 걸어 놨으니 뮤텍스를 걸어 놓은 코드 앞에서 기다릴 것입니다.
(개인블로그)
http://rousalome.egloos.com
답변 감사드립니다
기 작성된 드라이버 코드에서 register 를 수정하는 workqueue 가 동시에 2개가 돌아가고 있어서 문의 드렸습니다.
답변 주셔서 정말 감사드립니다. 그리고 블로그 애독자입니다. 지금도 보고 있었는데 같은 블로그가 떠서 놀랐습니다. 감사합니다.
댓글 달기