반응형

출처 : http://kldp.org/node/54671



후배의 질문이기에 존칭을 생략합니다. ㅎㅎㅎ

* spin_lock_irqsave()와 spin_lock_irq()
둘다 interrupt를 disable 시킨 이후에 spin lock을 획득하는 것은 동일하지만,
spin_lock_irqsave()는 CPU의 flag 레지스터를 보관했다가
spin_unlock_irqrestore()로 복구할 수 있다.

* spin_lock()과 spin_lock_irq()의 차이는
spin_lock()은 interrupt를 disable하지 않기 때문에
interrupt handler(top half)에서는 사용할 수 없다.
대신 이때는 spin_lock_irq()나 spin_lock_irqsave()를 사용해야 한다.

* spin_lock_bh()
같은 종류의 softirq는 여려 CPU에서 동시에 실행될 수 있기 때문에
([ksoftirqd/CPUn] 커널 쓰레드가 softirq의 실행을 담당한다.)
softirq를 disable한 이후에 spin lock을 획득한다.
원래 이 함수의 이름은 spin_lock_softirq() 정도가 되어야 맞겠지만
예전 커널의 흔적이 아직 남아있다.

* 그리고, spin_lock()은
spin lock으로 보호해야 할 데이터가
interrupt handler(top half)에서도, softirq handler에서도 접근하지 않고
단지 그 외의 일반적인 커널 코드에서만 접근한다면
interrupt disable, softirq disable 같은 overhead 없이 spin lock을 얻을때 사용한다.






조금 보태자면, spin_lock()이 interrupt handler / softirq에서 사용할 수 없는 건 아닙니다.

Thread context 실행 중 임의의 시점에 중지되고 softirq나 irq가 실행될 수 있고, softirq 실행중엔 임의의 시점에 irq가 실행될 수 있습니다. 만약 같은 락을 thread context와 irq에서 사용한다면 thread context에서 락을 잡고 있는 중에 irq가 실행되고 irq가 다시 같은 락을 획득하려고 할 수 있습니다. 데드락이죠. spin_lock_{irq[save]|bh}()는 이런 데드락을 피하기 위해서 사용합니다.

하나의 락이 irq에서도 사용되고 softirq나 thread context에서도 사용된다면, softirq/thread context에선 spin_lock_irq()를 irq 코드에선 spin_lock()을 사용합니다. 같은 코드를 irq와 다른 컨택스트에서 공유하거나해서 irq 상태를 알 수 없으면 spin_lock_irqsave()를 쓰면 됩니다. irq handler안에서는 spin_[un]lock_irq()를 쓰면 곤란하구요. 마찮가지로 softirq와 thread context가 공유하는 락은 thread context에서 spin_lock_bh()를 쓰면 됩니다. softirq disable은 카운팅이 되기 때문에 softirq안에서도 그냥 써도 되구요 (bh_save가 없는 이유).

정리하면 하나의 컨택스트 (irq, softirq, thread context 중) 안에서만 사용되는 락은 spin_lock()을 쓰면 되고, 하나 이상의 컨택스트에서 사용되는 락은 낮은 우선순위의 컨택스트에서 락을 잡을 때 락을 사용하는 컨택스트 중 가장 높은 우선순위를 막고 잡으면 됩니다.





서로 다른 irq를 처리하는 handler 사이에 shared resource가 있다면 irq handler 안이라도 (interrupt nesting을 막기 위해) spin_[un]lock_irq()를 써야겠죠.




예, 그런데 최근에 irq handler들 nesting이 되지 않도록 바뀌었습니다. 바뀌기 전에도 인터럽트 핸들러 안에선 save/restore를 쓰는 게 좋구요 (아니면 lockdep이 뭐라고 할거에요).






반응형

'Linux > Linux Kernel' 카테고리의 다른 글

Serio Driver  (0) 2013.02.27
Sending simulated mouse events using uinput  (0) 2013.02.14
tty uart 를 input device driver로 연결  (0) 2013.02.14
Posted by Real_G