Skip to content

[문제해결공유] rpi_get_interrupt_info가 ftrace로 안 잡힌 케이스 #1

@orangecalculator

Description

@orangecalculator

안녕하세요. 유용한 책 써주셔서 감사합니다.

3장 내용 실습하고 있었는데 문제가 있어서 삽질하다가 다른 분들도 이런 문제 있으실까 봐 공유하고자 합니다.

특히 이 부분은 앞쪽 내용이라서 경험이 많이 없어서 개인적으로 좀 오래 걸렸던 것 같습니다.

제 경우 라즈베리파이 4에 4.19 커널을 올려서 사용하고 있는데 문제는 해당 함수가 짧아서 inline이 되는 바람에 함수 호출로 안 잡혀서 애를 좀 먹었습니다.

아래와 같이 덤프를 열어서 /rpi_get_interrupt_info로 검색을 해보니 함수 호출이 inline 된 걸 확인했습니다.

pi@raspberrypi:~/linux-rasberrypi $ objdump -xd out/vmlinux | less

...

c028d054 <rpi_get_interrupt_info>:
c028d054:       e1a0c00d        mov     ip, sp
c028d058:       e92dd810        push    {r4, fp, ip, lr, pc}
c028d05c:       e24cb004        sub     fp, ip, #4

...

c028d0a4:       e88c4010        stm     ip, {r4, lr}
c028d0a8:       e282200c        add     r2, r2, #12
c028d0ac:       eb01f5be        bl      c030a7ac <__trace_bprintk>
c028d0b0:       e24bd010        sub     sp, fp, #16
c028d0b4:       e89da810        ldm     sp, {r4, fp, sp, pc}
c028d0b8:       c028d078        .word   0xc028d078

c028d0bc <show_interrupts>:
c028d0bc:       e1a0c00d        mov     ip, sp
c028d0c0:       e92ddff0        push    {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
c028d0c4:       e24cb004        sub     fp, ip, #4
c028d0c8:       e24dd00c        sub     sp, sp, #12

...

c028d3cc:       e88c4001        stm     ip, {r0, lr}
c028d3d0:       e282200c        add     r2, r2, #12
c028d3d4:       e59f00fc        ldr     r0, [pc, #252]  ; c028d4d8 <show_interrupts+0x41c>
c028d3d8:       eb01f505        bl      c030a7f4 <__trace_bprintk>
c028d3dc:       e595002c        ldr     r0, [r5, #44]   ; 0x2c
c028d3e0:       e1a02000        mov     r2, r0
c028d3e4:       e30011f8        movw    r1, #504        ; 0x1f8
c028d3e8:       e34c10d9        movt    r1, #49369      ; 0xc0d9

...

show_interrupts 함수를 살펴보니 rpi_get_interrupt_info 함수를 부르는 부분은 온데간데없고 __trace_bprintk 함수를 부르는 부분만 남아있는 걸 보고 발견했네요.

아래와 같이 함수 앞에 리눅스 커널 소스에서 제공하는 noinline 매크로를 삽입해서 해결했습니다.

diff --git a/3장.커널 디버깅과 코드 학습/3.1.2/patch_source_file/linux/kernel/irq/proc.c b/3장.커널 디버깅과 코드 학습/3.1.2/patch_source_file/linux/kernel/irq/proc.c
index d8d0078..2738f0a 100644
--- a/3장.커널 디버깅과 코드 학습/3.1.2/patch_source_file/linux/kernel/irq/proc.c
+++ b/3장.커널 디버깅과 코드 학습/3.1.2/patch_source_file/linux/kernel/irq/proc.c
@@ -471,7 +471,7 @@ int __weak arch_show_interrupts(struct seq_file *p, int prec)
 # define ACTUAL_NR_IRQS nr_irqs
 #endif

-void rpi_get_interrupt_info(struct irqaction *action_p)
+noinline void rpi_get_interrupt_info(struct irqaction *action_p)
 {
        unsigned int irq_num = action_p->irq;
        void *irq_handler = NULL;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions