넓스 2020. 11. 10. 17:50

-

· 인터럽트 번호(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 가능.