Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

77112
549
416217


[라즈베리파이] 인터럽트 디버깅 - 인터럽트 핸들러 파악 #CS 5. 인터럽트

우리는 다음 __handle_irq_event_percpu 함수 13번째 코드에서 인터럽트 핸들러가 호출된다고 배웠습니다. 
1 irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags)
2 {
3 irqreturn_t retval = IRQ_NONE;
4 unsigned int irq = desc->irq_data.irq;
5 struct irqaction *action;
6
7 record_irq_time(desc);
8
9 for_each_action_of_desc(desc, action) {
10 irqreturn_t res;
11
12 trace_irq_handler_entry(irq, action);
13 res = action->handler(irq, action->dev_id); // <<--
14 trace_irq_handler_exit(irq, action, res);

그리고 ftrace 로 인터럽트 이벤트를 켜서 각종 인터럽트가 얼마나 자주 인터럽트가 호출되는지 알게 되었죠. 그럼 인터럽트별로 인터럽트 핸들러 함수가 뭔지 파악하려면 어떻게 해야 할까요? 

여기까지 배운 정보를 바탕으로 다음 패치 코드를 작성하면 인터럽트 핸들러 정보를 파악할 수 있습니다.
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 79f987b94..2c2ec3f63 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -142,8 +142,13 @@ irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags
2 for_each_action_of_desc(desc, action) {
irqreturn_t res;
4+     void *irq_handler = (void*)action->handler;
    trace_irq_handler_entry(irq, action);
7+
8+ trace_printk("[+] irq:[%d] handler: %pS caller:(%pS) \n", 
9+ irq, irq_handler, (void *)__builtin_return_address(0));
10  res = action->handler(irq, action->dev_id);
11  trace_irq_handler_exit(irq, action, res);
 
위 코드를 빌드한 후 라즈베리안에 설치한 다음에 5.7.2 ftrace 인터럽트 이벤트 절에 소개한 [irq_ftrace.sh] 스크립트를 실행하면 다음 ftrace 로그를 확인할 수 있습니다.
1 kworker/0:1-29    [000] d.h.    89.431707: irq_handler_entry: irq=23 name=3f00b880.mailbox
2 kworker/0:1-29    [000] d.h.    89.431712: __handle_irq_event_percpu: [+] irq:[23] irq_handler: bcm2835_mbox_irq+0x0/0x60 caller:(handle_irq_event_percpu+0x2c/0x68) 
3 kworker/0:1-29    [000] d.h.    89.431719: irq_handler_exit: irq=23 ret=handled
4 <idle>-0     [000] d.h.    89.432021: irq_handler_entry: irq=62 name=dwc_otg
5 <idle>-0     [000] d.h.    89.432025: __handle_irq_event_percpu: [+] irq:[62] irq_handler: dwc_otg_common_irq+0x0/0x28 caller:(handle_irq_event_percpu+0x2c/0x68)
6 <idle>-0     [000] d.h.    89.432028: irq_handler_exit: irq=62 ret=unhandled

위 로그에서 23번 인터럽트에 대한 정보를 상세히 분석해볼까요? 우선 pid가 29번인 kworker/0:1-29 프로세스 실행 도중 irq=23번 인터럽트가 발생했다는 사실을 알 수 있습니다.
kworker/0:1-29    [000] d.h.    89.431707: irq_handler_entry: irq=23 name=3f00b880.mailbox
kworker/0:1-29    [000] d.h.    89.431712: __handle_irq_event_percpu: [+] irq:[23]irq_handler: bcm2835_mbox_irq+0x0/0x60 caller:(handle_irq_event_percpu+0x2c/0x68) 
 
이번에는 두 번째 줄 로그를 분석할 차례입니다. 
이 ftrace 로그를 출력하는 함수는 __handle_irq_event_percpu이고 이 함수를 호출한 함수는 handle_irq_event_percpu라는 기본 정보와 irq23의 인터럽트 핸들러는 bcm2835_mbox_irq라는 정보를 알 수 있습니다.

이번에는 62번 인터럽트에 대한 로그를 짚어 보겠습니다.
4 <idle>-0     [000] d.h.    89.432021: irq_handler_entry: irq=62 name=dwc_otg
5 <idle>-0     [000] d.h.    89.432025: __handle_irq_event_percpu: [+] irq:[62] irq_handler: dwc_otg_common_irq+0x0/0x28 caller:(handle_irq_event_percpu+0x2c/0x68)
6 <idle>-0     [000] d.h.    89.432028: irq_handler_exit: irq=62 ret=unhandled

pid가 0인 idle 프로세스가 실행 도중 62번 dwc_otg 인터럽트가 발생했고 이 인터럽트 핸들러는 dwc_otg_common_irq란 정보를 알 수 있죠.

"이 포스팅이 유익하다고 생각되시면 공감이나 댓글로 응원해주시면 감사하겠습니다."
"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)

# Reference (인터럽트 처리)


핑백

덧글

댓글 입력 영역