리눅스 커널 - Process and Interrupt Context Synchronization
프로세스 컨텍스트와 인터럽트 컨텍스트에 대한 내용은 다음 페이지에서 다루었다: 프로세스/인터럽트 컨텍스트 프로세스 컨텍스트와 인터럽트 컨텍스트에서 같은 critical section에 접근하는 시나리오에 대해서 생각해보자. 이 시나리오에서는 데드락이 발생할 수 있는데 상황은 아래와 같다. 1. 프로세스 컨텍스트에서 스핀락을 잡는다. 2. 인터럽트가 발생하여 인터럽트 핸들러가 동작하고 스핀락을 잡으려고 한다. 위와 같은 상황에서 프로세스 컨텍스트가 스핀락을 해제해야 하는데, 인터럽트 핸들러에 의해 CPU를 빼앗겨 스핀락을 해제할 수 없다. 인터럽트 핸들러는 스핀락을 잡을 수 없다. 아래 그림에서 Problem situation에 해당한다. 이러한 데드락 상황을 피하기 위해서, 프로세스 컨텍스트에서 인터럽트를 disable 후 스핀락을 얻으면 된다. 아래 그림의 Solution에 해당한다. spin_lock_irqsave() 함수로 현재 인터럽트 상태(disable이었는지 enable이었는지)를 저장하고 인터럽트를 disable 한 뒤 스핀락을 획득한다. spin_unlock_irqrestore()는 스핀락을 해제하고 저장해놨던 이전 인터럽트 상태를 복원한다. 이야기를 더 진행하기 위해 먼저 bottom half context를 소개한다. 이 컨텍스트는 인터럽트 컨텍스트의 일종인데, 인터럽트는 enable 되어 있고 블로킹 함수는 부르면 안 되는 상태이다. 인터럽트 핸들러에서 전반부 작업이 끝나고 나서 도는 softirqs와 tasklets이 bottom half context에서 도는 것이다 (이후에 ksoftirqd에 의해 도는 softirq는 프로세스 컨텍스트에서 돈다.). Bottom half context와 critical section을 공유하는 프로세스 컨텍스트의 경우 spin_lock_bh() 함수로 스핀락을 잡아야 한다 (ksoftirqd에 의해 도는 softirq는 spin_lock()으로 잡는다.). spin_lock_bh(...