이전 소절에서는 schedule_delayed_work() 함수를 호출하면 딜레이 워크 동적 타이머를 등록하는 과정을 살펴봤습니다. 이어서 지정한 지연 시각 후에 실행하는 딜레이 워크 동적 타이머 핸들러인 delayed_work_timer_fn() 함수를 분석합니다.
다음 그림을 보면서 딜레이 워크를 큐잉하는 과정을 소개합니다.

그림 7.22 딜레이 워크 실행 흐름도 중 3단계 동작
이번 소절에서는 딜레이 워크 전체 실행 흐름도에서 3단계인 딜레이 워크를 큐잉하는 과정을 살펴보겠습니다.
delayed_work_timer_fn() 함수는 언제 실행할까요? 동적 타이머 만료 시각에 도달하면 Soft IRQ 컨택스트에서 delayed_work_timer_fn() 함수를 호출합니다.
Soft IRQ 전체 구조와 흐름은 8장(커널 타이머)에서 상세히 다룹니다. Soft IRQ 개념이 익숙하지 않은 분은 8장을 먼저 읽고 오시면 됩니다.
먼저 delayed_work_timer_fn () 함수를 보겠습니다.
https://elixir.bootlin.com/linux/v4.19.30/source/kernel/workqueue.c
1 void delayed_work_timer_fn(unsigned long __data)
2 {
3 struct delayed_work *dwork = (struct delayed_work *)__data;
4
5 /* should have been called from irqsafe timer with irq already off */
6 __queue_work(dwork->cpu, dwork->wq, &dwork->work);
7}
6번째 코드를 보면 __queue_work() 함수를 호출해서 딜레이 워크를 실행합니다. 이후 동작은 워크와 같습니다.

그림 7.23 워크 전체 실행 흐름 과정 중 워크 큐잉 단계
위 그림은 워크의 실행 흐름도입니다. 워크를 큐잉하는 2단계 실행 함수 목록을 보면 __queue_work() 함수가 보입니다. 이 함수를 호출하면 워크를 워크큐에 큐잉하게 됩니다.
마찬가지로 delayed_work_timer_fn() 함수에서 __queue_work() 함수를 호출하면 딜레이 워크를 워크큐에 큐잉하게 됩니다. 또한 딜레이 워크를 실행하도록 워커 스레드를 깨우는 동작을 실행합니다.
이 후 딜레이 워크는 워크와 같은 동작을 수행합니다. 따라서 __queue_work() 함수부터 코드 분석은 생략합니다. 세부 코드 분석은 7.4절을 참고하세요.
이어서 다음 소절에서는 딜레이 워크를 실습하면서 코드 분석한 내용을 확인하겠습니다.
Edited: 04/19/2020
#Reference(워크큐)
워크큐 소개
워크큐 종류 알아보기
워크란
워크를 워크큐에 어떻게 큐잉할까?
워크를 큐잉할 때 호출하는 워크큐 커널 함수 분석
워커 쓰레드란
워크큐 실습 및 디버깅
ftrace로 워크큐 동작 확인
인터럽트 후반부로 워크큐 추가 실습 및 로그 분석
Trace32로 워크큐 자료 구조 디버깅하기
딜레이 워크 소개
라즈베리파이 딜레이 워크 실습 및 로그 확인
최근 덧글