Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

91258
1323
114593


[리눅스커널] 워크큐: wake_up_worker() 함수 분석 8. Workqueue

다음은 워크큐에서 가장 중요한 워커 쓰레드를 깨우는 wake_up_worker() 함수를 살펴보겠습니다.
[https://elixir.bootlin.com/linux/v4.14.43/source/kernel/workqueue.c]
1 static void wake_up_worker(struct worker_pool *pool)
2 {
3 struct worker *worker = first_idle_worker(pool);
4
5 if (likely(worker))
6 wake_up_process(worker->task);
7}

first_idle_worker() 함수를 호출해서 워커 풀에 등록된 아이들 워커를 가져옵니다.

first_idle_worker() 함수 구현부를 보면 다음 6번 줄 코드와 같이 &pool->idle_list 주소에 접근해서 struct worker 구조체 구조를 읽어 옵니다.
1 static struct worker *first_idle_worker(struct worker_pool *pool)
2 {
3 if (unlikely(list_empty(&pool->idle_list)))
4 return NULL;
5
6 return list_first_entry(&pool->idle_list, struct worker, entry);
7 }

&pool->idle_list는 링크드 리스트입니다. 이 링크드 리스트는 struct worker 이란 워커 구조체의 entry 주소를 가리키고 있습니다. &pool->idle_list 주소에서 struct worker.entry 주소를 빼서 struct worker 자료 구조 주소를 읽는 코드입니다.

코드만 봐서는 이해하기 어려운 내용입니다.
&pool->idle_list 주소로 struct worker 구조체 주소를 읽어오는 구문을 워크큐 자료구조 절에서 그림과 함께 살펴볼 예정입니다.

다음은 5~6번 줄 코드를 볼 차례입니다.
5 if (likely(worker))
6 wake_up_process(worker->task);

워커 풀에서 아이들 워크를 읽어서 해당 워커 쓰레드를 깨웁니다. struct worker.task 멤버 타입은 struct task_struct으로 프로세스를 표현하는 태스크 디스크립터입니다.

wake_up_worker() 함수는 워커 쓰레드를 깨우는 중요한 함수입니다. 이 함수를 호출하면 워커 쓰레드가 깨어나는 동작을 한다고 예상하고 코드를 볼 필요가 있습니다.

여기까지 다음 워크큐 핵심 커널 함수 코드 분석을 했습니다.
find_worker_executing_work()
set_work_pwq()
get_work_pool()
wake_up_worker()

위 함수들은 워크큐를 처리하는 어느 함수에서도 자주 쓰니 잘 알아 둘 필요가 있습니다. 또한 이 함수에서 쓰는 자료구조를 잘 활용하면 세련된 커널 디버깅 코드를 작성할 수 있습니다.

다음 절에서는 워크를 누가 언제 실행하는지 살펴 보겠습니다.

#Reference 워크큐
워크큐 소개
워크큐 종류 알아보기
워크란  
워크를 워크큐에 어떻게 큐잉할까?
   워크를 큐잉할 때 호출하는 워크큐 커널 함수 분석   
워커 쓰레드란
워크큐 실습 및 디버깅
   ftrace로 워크큐 동작 확인   
   인터럽트 후반부로 워크큐 추가 실습 및 로그 분석 
   Trace32로 워크큐 자료 구조 디버깅하기 
딜레이 워크 소개  
   딜레이 워크는 누가 언제 호출할까?
라즈베리파이 딜레이 워크 실습 및 로그 확인  


핑백

덧글

댓글 입력 영역