-
· 인터럽트 번호(HW 中 IRQ번호)에 대해서 껐다(mask) 켰다(unmask) 가능
· CPU에 대해서도 인터럽트 번호 껐다가 켰다가 가능.
- 인터럽트 관리가 필요한 경우
· 인터럽트 핸들러가 사용하는 전역 자료구조에 접근할 때
· 경쟁 상태 -> critical section -> semaphore로도 처리할 수 있음 -> schedule(cpu 가져감)
· 인터럽트 핸들러는 매우 빨라야한다. CPU 빼앗겨서는 안됨. semaphore는 cpu를 가져감.
=> 따라서 CPU 발생하지 않는 인터럽트 사용.
· 누가?
· 후반부처리, 시스템 호출
· 인터럽트 핸들러가 받고, 많은 부분을 후반부로 처리(대체로 kernal thread에서 처리) 를 넘긴다.
- 인터럽트 번호 확인
· cat /proc/interrupts
- 인터럽트 관리 함수
· 하드웨어
· 인터럽트 발생시 해당 irq 번호의 인터럽트는 mask 된다.(꺼진다.)
· 그 다음부터는, 해당 irq 번호의 인터럽트가 발생하면 block 된다.
· cpu에 대한 인터럽트 mask 는 드물다.
· 소프트웨어
· irq 번호나 CPU에 대해 인터럽트를 mask 할 수 있다.
· 여러가지 interrupt mask 함수들이 제공된다.
- CPU에 대한 interrupt mask 함수들
· local_irq_disable() · 현재 CPU에 대한 interrupt를 mask 한다. · header : include/linux/irqflags.h · local_irq_enable() · 현재 CPU에 대한 interrupt를 unmask 한다. |
=> 두 함수는 nested call 에서 문제가 발생.
· local_irq_save(flags); // save는 매크로다. 따라서 flags 값이 바뀐다. · unsigned long flags · 현재 CPU에 대한 interrupt 상태를 flags 에 저장하고, 이 CPU에 대한 interrupt를 mask 한다. · local_irq_restore(flags); · CPU에 대한 interrupt 상태를 flags 값으로 복원. |
=> 두 함수는 nested call 에서 문제 해결
- IRQ 번호에 대한 interrupt mask
· void disable_irq(unsigned int irq); // <-> enable_irq(irq)
· header file : include/linux/interrupt.h
· irq: mask 하려는 irq 번호
· disable_irq() 호출 시 관련 irq의 interrupt handler가 이미 실행 중이면 어떻게 하나?
· Ex. 커널스레드나 시스템콜에 의해 CPU1(disable_irq())을 호출 하려는데 , CPU0는 interrupt handler를 사용중.
· 실행 중인 interrupt handler 가 끝날 때까지 대기한 후 interrupt mask
· schedule 아님. busy waiting.
· interrupt context(후반부처리) 에서 사용 가능
· 하지만 가급적이면 interrupt context에서 사용하지 않는 것이 좋다.
· Nested call 가능.