Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

593
557
422264


인터럽트 - Overview [Linux][Kernel] IRQ(Interrupt)

인터럽트하면 무슨 생각이 나죠? 
평소에 이런 말도 하죠. "인터럽트 걸지마!" "인터럽트가 걸려와서 제대로 일을 못했어요."

커널에서 인터럽트는 하드웨어와 소프트웨어의 인터페이스이라고 할 수 있구요,
각 물리적인 디바이스와 디바이스 드라이버의 인터페이스라고 할 수 있어요.

인터럽트 동작에 대한 수 많은 예시를 들 수 있는데요.

모바일 디바이스에서 사용자가 화면을 터치했을 때 인터럽트가 올라와서 해당 처리를 하거든요.
해당 처리는 Input Event를 유저 공간에 전달해서 메뉴가 바뀐다던가, 화면을 다시 그리던가 하는 동작을 하죠.

인터럽트 처리는 인터럽트 핸들러에서 처리하구요, 인터럽트 핸들러는 보통 ISR(Interrupt Service Routine)이라고 하는데요.
최대한 빠른 시간 내 데이터 처리를 하고 ISR을 끝내야 해요. 아래는 touch_irq_handler 함수에 stack tracer를 잡고 받은 ftrace log인데요.
CPU에 부하가 없어 idle 프로세스로 돌고 있다가 IRQ가 Trigger될 수 있는데요.
 => touch_irq_handler
 => handle_irq_event_percpu
 => handle_irq_event
 => handle_fasteoi_irq 
 => generic_handle_irq
 => __handle_domain_irq
 => gic_handle_irq
 => __irq_svc
 => lpm_cpuidle_enter
 => lpm_cpuidle_enter
 => cpuidle_enter_state
 => cpuidle_enter
 => cpu_startup_entry
 => secondary_start_kernel

하지만, 아래와 같이 _raw_spin_unlock_irqrestore() 함수가 처리되는 도중에 IRQ가 Trigger될 수도 있거든요.
 => touch_irq_handler
 => handle_irq_event_percpu
 => handle_irq_event
 => handle_edge_irq
 => generic_handle_irq
 => msm_gpio_irq_handler
 => generic_handle_irq
 => __handle_domain_irq
 => gic_handle_irq
 => __irq_svc
 => _raw_spin_unlock_irqrestore
 => _raw_spin_unlock_irqrestore
 => __wake_up
 => post_pkt_to_port
 => do_read_data
 => process_one_work
 => worker_thread
 => kthread
 => ret_from_fork

아래는 다른 경우인데요. 슬랩 메모리를 할당하는 도중에 IRQ가 처리됩니다.
 => touch_irq_handler
 => handle_irq_event_percpu
 => handle_irq_event
 => handle_edge_irq
 => generic_handle_irq
 => msm_gpio_irq_handler
 => generic_handle_irq
 => __handle_domain_irq
 => gic_handle_irq
 => __irq_svc
 => __slab_alloc.constprop.8
 => __slab_alloc.constprop.8
 => kmem_cache_alloc
 => jbd2__journal_start
 => __ext4_journal_start_sb
 => ext4_da_write_begin
 => generic_perform_write
 => __generic_file_write_iter
 => ext4_file_write_iter
 => new_sync_write
 => vfs_write
 => SyS_write
 => ret_fast_syscall

      android.ui-1832  [000] d.h1 14065.301991: touch_irq_handler <-handle_irq_event_percpu
      android.ui-1832  [000] d.h1 14065.302038: <stack trace>
 => touch_irq_handler
 => handle_irq_event_percpu
 => handle_irq_event
 => handle_edge_irq
 => generic_handle_irq
 => msm_gpio_irq_handler
 => generic_handle_irq
 => __handle_domain_irq
 => gic_handle_irq
 => __irq_usr
 => 


그럼 얼마나 빨리 touch_irq_handler()가 처리되는 속도를 측정해볼 수 있는데요.
ftrace graph tracer 기능을 활용하면 실제 touch_irq_handler()가 실행된 시간을 측정할 수 있어요.
아래는 ftrace log중 일부분인데요. 10us 이내로 실행이 되죠?
 ------------------------------------------
 5)  core_ct-356   =>  AudioTr-4407 
 ------------------------------------------

 5)               |  /* + comm : AudioTrack, prio : 97, pid : 4407, nr_thread : 88 */
 5)               |  /* - comm : AudioTrack, prio : 97, pid : 4407 */
 0)   2.135 us    |  touch_irq_handler();
 0)   2.343 us    |  touch_irq_handler();
 0)   2.239 us    |  touch_irq_handler();
 0)   3.802 us    |  touch_irq_handler();
 0)   2.448 us    |  touch_irq_handler();
 0)   1.667 us    |  touch_irq_handler();
 0)   1.875 us    |  touch_irq_handler();
 0)   9.427 us    |  touch_irq_handler();
 0)   2.396 us    |  touch_irq_handler();
 0)   2.187 us    |  touch_irq_handler();
 0)   2.136 us    |  touch_irq_handler();
 0)   1.667 us    |  touch_irq_handler();

이렇게 인터럽트 핸들러는 어떤 프로세스가 돌던 갑자기 실행될 수 있기 때문에 빠른 시간 내에 처리를 해야 해요.

#Reference 시스템 콜


Reference(워크큐)
워크큐(Workqueue) Overview


덧글

댓글 입력 영역