일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- concurrency control
- 데이터베이스
- recoverability
- 네트워크
- 인터럽트
- SDK
- 시스템프로그래밍
- B tree 데이터삽입
- vite
- 운영체제
- 프로세스 주소 공간
- BreadcrumbsComputer-Networking_A-Top-Down-Approach
- 온디바이스AI
- 코딩애플
- Git
- 개발남노씨
- Extendable hashing
- 백엔드
- CPU 스케줄링
- 쉬운 코드
- 코딩테스트 [ ALL IN ONE ]
- 운영체제와 정보기술의 원리
- 커널 동기화
- 시그널 핸들러
- 김영한
- 반효경
- 트랜잭션
- 갤럭시 S24
- SQL
- 쉬운코드
- Today
- Total
티끌모아 태산
Chapter 3: Interrupt and Exception 본문
Interrupt
interrupt는 사전적 의미로 to break in upon an action 이라는 뜻입니다.
- 컴퓨터 과학의 맥락에서 인터럽트는 불시에 발생할 수 있는 (드문) 사건들을 효율적으로 처리하는 방법을 제공합니다.
- 인터럽트는 하드웨어(네트워크 인터페이스 카드(NIC), 프린터, 디스크, 마우스, 키보드 등)와 CPU 사이의 통신 도구로 기능합니다.
Taxonomy
- Synchronous interrupt, called exception or software interrupt is generated by the 'CPU' while executing instructions
- Programming error
- System call: requests by process for kernel service
- Debuger
- Asynchronous interrupt, called (hardware) interrupt is generated by the 'hardware device' external to the CPU at arbitary times
- e.g., timer interrupt, I/O devices (disk contorller, ...)
Interrupt Handling in the Linux Kernel
인터럽트 신호(interrupt signal)가 발생하면, CPU는 현재의 제어 흐름(current flow of control)을 중지하고 새로운 활동(인터럽트 핸들러)으로 점프합니다. 그리고 현재 하드웨어의 컨텍스트를 커널 스택에 저장하며, 프로그램 카운터에 인터럽트 관련 주소를 배치합니다.
인터럽트 핸들러가 프로세스는 아니지만, 인터럽트가 발생했을 때 '인터럽트 컨텍스트'에서 실행되는 커널 제어 경로(Kernel Control Path, KCP)입니다. 즉, 이는 현재 프로세스의 컨텍스트 내에서 실행되지 않습니다. (not running in the context of current processes)
⭐️Process Context vs Interrupt Context
리눅스의 철학은 '현재 돌고 있는 프로세스에게 최대한 피해를 적게 주자!' 입니다.
- Process context: "커널이 프로세스를 대신하여 작업을 수행하는 동안의 커널 운영 모드", 예를 들어 시스템 콜을 실행하거나 커널 스레드를 실행하는 것을 말합니다. 프로세스는 커널과 프로세스 컨텍스트에서 연결되기 때문에, 프로세스 컨텍스트는 'sleep' 상태가 될 수 있거나 스케줄러를 호출할 수 있습니다. 스케줄 가능(schedulable)한 모든 것은 프로세스 컨텍스트로 간주됩니다.
- Kernel thread? 커널 스레드는 프로세스 컨텍스트에서 실행됩니다. 커널 스레드는 스케줄 가능합니다. 왜냐하면 그것은 스위칭될 수 있는 확실한 컨텍스트를 자체적으로 가지고 있기 때문입니다.
- Interrupt context: "하드웨어 인터럽트에 의해 트리거된 인터럽트 핸들러를 실행하는 동안의 커널 운영 모드.". Interrupt handler is not running in the context of any particular process. That is, interrupt handlers are not schedulable and restricted in use.
- Limitation of an interrupt handler
- Cannot sleep/block: i.e., cannot call schedule()
- No blokcing lock: i.e., no semaphore, 대신 use sipnlock spin_lock_irqsave()
- No bolocking KMA: i.e., no kmalloc(size, GFP_KERNEL), use non-blocking kmalloc(size, GFP_ATOMIC)
- cannot access user space
프로세스 컨텍스트에서는 현재 프로세스를 대신하여 KCP를 실행하는 반면 인터럽트 컨텍스에서는 인터럽트 핸들러가 현재 프로세스를 대신하여 수행하는 것이 아니다. 즉, 인터럽트 핸들러는 현재 프로세스와는 연관이 없다.
Interrupt에서는 sleep, block, schedule() 호출 등을 할 수 없다. 어떠한 인터럽트 설계 철학 때문인가? interupt handler가 수행하는 일은 현재 돌아가고 있는 프로세스와는 아무런 상관없는 일을 하는 것이기 때문에 sleep, block, schedule() 호출 등을 하는 행위는 현재 프로세스에게 좋지 않은 영향을 줄 수 있다. 예를들어, 인터럽트 핸들러가 스케줄러를 불러 Process switching 발생하면 현재 돌고있는 프로세스가 방을 빼야하는 상황이 오기 때문에 현재 프로세스입장에서는 좋지 않기 때문이다.
Process Context는 System call or kernel thread를 수행하는 것으로 커널 수행 모드에서 자유롭게 스케줄러를 부를 수 있다. 반면에 interrupt context는 하드웨어 인터럽트에 의해서 트리거된 인터럽트 핸들러를 수행하는 커널 모드로 인터럽트 핸들러는 커널 모드에서 자유롭게 스케줄러를 호출할 수 없고 제약이 있다. 이러한 제약이 있는 이유는 인터럽트 핸들러가 수행하는 것은 현재 프로세스와 아무런 관련이 없는 수행이고 혹여 스케줄러를 호출할 경우 프로세스 스위칭이 발생해 CPU제어권이 빼앗길 수 있기 때문이다. 그래서 현재 수행중인 프로세스에게 피해를 최소화 하는 것이 중요하기 때문에 제한적으로 사용하는 것이다.
Interrupt Handling Requirements
- Kernel efficiency
- Interrupt can come at any time, when the kernel may want to finish something else it was trying to do
- Hence, the kernel's goal is to get the interrupt out of the way as soon as possible (top-half), and defer as much processing as it can (bottom-half). 즉, 중요한 사항을 먼저 처리하고 더 중요한 것을 나중에 처리하는 방식으로 수행한다.
- Efficient handling of multiple I/Os
- The kernel may accept a new interrupt signal while handling a previous one
- the kernel control paths should therefore be executed in a nested manner
- Kernel synchronization
- 커널 내에는 인터럽트가 비활성화되어야 하는 중요한 영역(Critical regions)이 존재합니다.
- 이러한 영역은 시스템 반응성을 유지하기 위해 가능한 한 작게 유지되어야 합니다. 커널 내부에서 데이터 일관성을 유지하고, 레이스 조건(race conditions)을 방지하기 위해 중요한 영역에서 인터럽트를 비활성화해야 할 필요성을 강조합니다. 중요 영역이란 여러 스레드나 프로세스가 동시에 접근하면 안 되는 코드 영역을 말하며, 이를 보호하기 위한 동기화 메커니즘이 필요합니다. 예를 들어, 두 스레드가 동시에 같은 메모리 위치를 수정하려 할 때 발생할 수 있는 문제들을 방지하기 위함입니다. 이러한 동기화 기술은 커널의 성능과 안정성에 중요한 영향을 미칩니다.
나중에 동기화를 공부할 때 더 자세히 공부하겠지만 잠시 간략하게 알아보겠습니다. 커널 제어 경로(kernel control path)를 중첩하는 것은 멀티프로세싱을 구현하기 위해 중요하다. 그러나 커널 제어 경로의 중첩은 커널 데이터 구조에 대한 동시 접근으로 인해서 race condition이 발생할 수 있다. race condition이란 두 개 이상의 중첩된 커널 제어 경로가 어떻게 얽혀 있는지에 따라 어떤 계산의 결과가 달라질 때 발생합니다. 그래서 커널 동기화가 이를 막기위해 필요합니다. (Kernel synchronization is required to prevent race condition.) 즉, 커널 동기화는 불안전한 동시성을 예방하고 race condition이 발생하지 않도록 보장합니다.
IRQs and Interrupt Controller
메모리 및 입출력 장치 등의 하드웨어 장치에는 컨트롤러(Controller)라는 것이 붙어있습니다. 컨트롤러는 일종의 작은 CPU로서, 컴퓨터 전체에 CPU라는 중앙처리장치가 있듯이 컨트롤러는 각 하드웨어 장치마다 존재하면서 이들을 제어하는 작은 CPU라고 할 수 있다. 예를들어, 메모리를 제어하는 컨트롤러를 메모리 컨트롤러, 디스크를 제어하는 컨트롤러를 디스크 컨트롤러하고 합니다.
- Hardware device controller
- 각 디바이스 컨트롤러는 인터럽트 요청을 발생시킬 수 있는 출력 라인을 가지고 있습니다(예: IRQ, Interrupt ReQuest).
- 하드웨어 인터럽트의 유형에는 타이머, I/O, IPI(인터 프로세서 인터럽트) 등이 있습니다.
- IRQ 라인은 하드웨어 회로의 입력 핀에 연결되어 있으며, 이를 (Programmable Interrupt Controller, PIC)라고 합니다.
- 프로그래머블 인터럽트 컨트롤러 (PIC)
- IRQ 라인을 모니터링하며, 신호가 발생하는지 확인합니다.
- IRQ 라인에서 신호가 발생하면:
- 2.1. 발생한 신호를 해당하는 벡터로 변환합니다.
- 2.2. PIC의 I/O 포트에 벡터를 저장합니다(데이터 버스를 통해 CPU가 읽을 수 있도록).
- 2.3. 프로세서의 INTR 핀에 신호를 보냅니다. 즉, 인터럽트를 발행합니다.
- 2.4. CPU가 PIC의 I/O 포트 중 하나에 쓰기를 통해 인터럽트 신호를 인정할 때까지 기다립니다. 이때 INTR 라인을 클리어합니다.
인터럽트의 일반적인 기능
하드웨어 인터럽트(timer, I/O)든 소프트웨어 인터럽트(exception, system call)든 일반적으로 인터럽트가 발생하면 CPU는 하던일을 멈추고 운영체케 커널 내에서 해당 인터럽트의 처리를 위해 정의된 코드를 찾게 됩니다. (jump to the interrupt handler). 커널은 정의된 코드를 쉽게 찾기위해 interrupt vector를 갖고 있습니다. 인터럽트 벡터란 인터럽트 종류마다 번호를 정해서, 번호에 따라 처리해야할 코드가 있는 위치를 가리키는 자료구조입니다. 실제 처리해야 할 코드는 인터럽트 처리 루틴(interrupt sevice routine) 또는 핸들러(interrupt handler)라고 불리는 다른 곳에 정의된다.
그래서 인터럽트 처리루틴을 통해 해당하는 인터럽트 처리를 완료하고 나면 원래 수행하던 작업으로 돌아가 중단되었던 일을 계속해서 수행하게 됩니다.
❗️Remind
- 프로세스 스위칭은 커널 모드 작업이 끝날 때 발생하며, switch_to 매크로를 통해 커널 모드에서 실행 중인 프로세스의 하드웨어 컨텍스트(esp, eip 등)를 변경합니다.
- 사용자 모드와 커널 핸들러 사이에서 "인터럽트의 하드웨어 핸들링"은 하드웨어 컨텍스트(eip, esp 등)를 변경합니다. 이것은 중첩된 커널 제어 경로에서 발생하지 않는 경우 종종 "모드 스위칭"이라고 불립니다.
- Interrupt handler is not a process, but a kernel control path(KCP) that runs in the ‘interrupt context’ when the interrupt occurred (i.e., not running in the context of current process)
Interrupt Vectors In Linux
인터럽트 벡터란 인터럽트 종류마다 번호를 정해서, 번호에 따라 처리해야할 코드가 있는 위치를 가리키는 자료구조입니다.
- Each interrupt (and exception) is identified by a number (0~255)
⭐️인터럽트의 기본적인 동작 과정은 다음과 같습니다.
- CPU는 메모리에 있는 명령, 정확히는 프로그램 카운터가 가리키고 있는 명령을 읽어와 작업을 수행한다.
- 이때, 인터럽트 요청이 들어온다. ex) I/O interrupt, Timer interrupt, System call, etc.
- CPU는 하던 일을 멈추고 다음 실행할 명령어와 현재 상태를 PCB(Process Control Block) 블록에 저장한다. (*PCB는 각각의 프로그램마다 하나씩 존재하며 해당 프로그램의 어느 부분이 실행중이 었는지 즉, 실행 상태를 저장한다.) -> CPU의 제어권이 사용자 프로그램에서 인터럽트 처리 루틴으로 넘어간다.
- ISR(Interrupt Service Routine)을 실행한다.
- 인터럽트 처리 후 기존 상태를 복구한다. *CPU의 제어권이 인터럽트가 발생하기 직전의 프로세스에게 다시 넘어가간다.
- 기존 프로그램을 계속 수행한다.
Nested Execution
- 커널 제어 경로는 임의로 중첩될 수 있습니다. (The kerenl control paths may be arbitaryly nested)
- 인터럽트 핸들러는 또 다른 인터럽트 핸들러에 의해 중단될 수 있으며, 이는 커널 제어 경로의 중첩된 실행을 야기할 수 있습니다.
- 예외 상황 역시 인터럽트에 의해 중단될 수 있습니다.
- 리눅스는 동시에 발생하는 다수의 인터럽트를 처리하기 위해 중첩된 인터럽트 실행을 사용합니다.
- 중첩된 인터럽트가 필요한 이유는
- PIC(Programmable Interrupt Controller)와 디바이스 컨트롤러의 처리량을 향상시키기 위함입니다.
- 이를 통해 우선 순위 레벨 없이 인터럽트 모델을 구현할 수 있으며, 하드웨어 장치 간에 미리 정의된 우선 순위를 설정할 필요가 없습니다.
- 중첩된 인터럽트의 전제 조건으로,
- 현재 프로세스는 커널 제어 경로가 인터럽트에 연관되어 실행되는 동안 전환되지 않습니다. (The current process is not switched while executing a kernel control path associated with an interrupt)
- 인터럽트 핸들러의 커널 제어 경로는 디스크 I/O 작업을 시작하는 것과 같은 작업을 차단하지 않아야 하며, 즉 인터럽트 핸들러가 실행 중일 때 프로세스 전환이 이루어지지 않아야 합니다.
- 중첩된 커널 제어 경로를 재개하기 위해 필요한 모든 데이터는 현재 프로세스와 밀접하게 연결된 커널 모드 스택에 저장됩니다.
⭐️인터럽트를 설계할 때 고려해야하는 것들을 작성하시오.
- 인터럽트 유형 결정: 인터럽트는 동기적인 예외(소프트웨어 인터럽트)와 비동기적인 하드웨어 인터럽트로 분류될 수 있습니다. 동기적 인터럽트는 CPU가 명령어를 실행하는 도중에 발생하며, 비동기적 인터럽트는 CPU 외부의 장치로부터 발생합니다.
- 인터럽트 우선 순위 설정: 여러 인터럽트가 동시에 발생할 경우, 어떤 인터럽트를 먼저 처리할지 우선 순위를 정해야 합니다. 이는 시스템의 응답성과 효율성에 큰 영향을 미칩니다.
- 인터럽트 핸들러 설계: 인터럽트가 발생했을 때 실행될 인터럽트 핸들러를 효율적으로 설계해야 합니다. 핸들러는 가능한 빠르게 실행되어야 하며, 시스템의 다른 부분과 올바르게 상호 작용해야 합니다.
- 컨텍스트 스위칭 고려: 인터럽트 처리 중에 현재 실행 중인 프로세스의 상태를 저장하고 복원하는 컨텍스트 스위칭을 효율적으로 관리해야 합니다.
- 인터럽트 마스킹 및 락킹: 특정 조건에서 인터럽트를 일시적으로 차단(마스킹)하거나, 데이터 무결성을 보장하기 위해 락을 사용하는 방법을 고려해야 합니다.
- 공유 리소스 관리: 여러 인터럽트 핸들러가 동일한 리소스에 접근할 수 있으므로, 동시성 제어와 데이터 무결성을 유지하는 방법을 설계해야 합니다.
- 성능 최적화: 인터럽트 처리는 시스템의 전반적인 성능에 영향을 미치므로, 성능 저하를 최소화하는 방법을 고려해야 합니다.
- 에러 처리 및 디버깅: 인터럽트 시스템에서 발생할 수 있는 예외 상황과 에러를 효과적으로 처리하고, 디버깅을 용이하게 하는 설계가 필요합니다.
이러한 요소들을 종합적으로 고려하여 인터럽트 시스템을 설계하면, 효율적이고 안정적인 시스템 운영이 가능해질 것입니다.
Exceptions
예외는 소프트웨어 인터럽트의 한 종류로 동기적인 인터럽트 입니다. 이는 CPU가 명령어를 실행하는 도중에 발생합니다.
- CPU-detected exceptions
- Generated when the CPU detects an anomalous condition (CPU가 비정상적인 상태를 감지했을 때 생성됨)
- Programmed exceptions (intentional)
- Occurs at the request of the programmar
Exception Handling(1)
- 대부분의 예외는 UNIX 신호(signal)를 해당 프로세스에 보내는 것으로 처리됩니다. 이로 인해 예외를 일으킨 프로세스가 신호를 받을 때까지 처리가 연기(deferred)되며, 그 결과 커널이 예외를 신속하게 처리할 수 있습니다.
- 인터럽트 처리에 관해서는, 인터럽트는 관련된 프로세스가 중단된 후 오랜 시간이 지나서 완전히 관련 없는 프로세스가 실행 중일 때 도착하는 경우가 많습니다. 따라서 현재 프로세스에 UNIX 신호를 보내는 것은 의미가 없습니다.
Exception Handling(2)
About 20 different exceptions in Linux
- The kernel must provide a dedicated exception handler for each exception type
- The exception handler sends a UNIX signal to the process that caused the exception
Exception Handler(3)
- 리눅스는 예외를 사용하여 프로그래밍 오류나 비정상적인 하드웨어 상태를 처리합니다. (Linux usage for exceptions)
- 예를 들어, 프로그램이 0으로 나누기를 수행할 때 CPU는 "divide error" 예외를 발생시킵니다.
- 예외 핸들러는 현재 프로세스에 SIGFPE 신호를 보내어 회복하거나 중단시킵니다.
- Manage hadware resource efficiently (예를 들어 페이지 폴트 처리가 이에 해당합니다.)
예외 처리를 위한 표준 순서는 다음과 같습니다:
- 커널 모드 스택에 있는 대부분의 레지스터 내용을 저장합니다.
- Handle the exception (by C funtion)
- Exit from the handler (by 'ret_from_exception()')
Characteristics of Interrupt Handler
- 인터럽트 핸들러는 '인터럽트 컨텍스트'에서 실행됩니다. (Interrupt handler run in 'interrupt context')
- 인터럽트 핸들러가 대신 실행되는 프로세스는 항상 TASK_RUNNING 상태를 유지해야 합니다.
- 결과적으로, 인터럽트 핸들러는 I/O 디스크 작업과 같은 어떠한 블로킹(blocking) 작업도 수행할 수 없습니다. (interrupt handlers cannot perform any blocking procedure such as I/O disk opertation)
- 인터럽트 루틴을 처리하는 데에는 긴급성의 차이가 있습니다. (Different urgency in handling interrupt routines)
- 인터럽트 발생 시 수행해야 할 모든 작업이 같은 긴급성을 가지는 것은 아닙니다:
- 일부 중요한 작업은 가능한 한 빨리 수행되어야 합니다.
- 긴급하지 않은 작업은 인터럽트 핸들러가 실행되는 동안 연기되어야 합니다. 인터럽트 핸들러가 실행 중일 때 해당 IRQ 라인의 신호는 일시적으로 무시됩니다.
- 인터럽트 발생 시 수행해야 할 모든 작업이 같은 긴급성을 가지는 것은 아닙니다:
- 인터럽트에는 여러 클래스가 있습니다.
인터럽트 핸들러가 시스템의 다른 부분에 방해를 주지 않으면서 빠르고 효율적으로 작업을 처리해야 한다는 점을 강조하고 있습니다. 중요하지 않은 작업은 핸들러가 실행되지 않을 때까지 연기될 수 있으며, 이는 시스템의 반응 시간과 안정성을 최적화하는 데 도움이 됩니다.
⭐️exception handling vs interrupt handling의 철학적 차이는 무엇이냐
먼저 exception handler는 UNIX signal을 발생시켜 이 signal을 프로세스에게 본낸다.(Most exceptions are handled simply by sending a UNIX signal to the process that caused the exception.) 반면에 interrupt handler는 signal을 만들지 않는다.
❗️왜냐하면, 우선 interrupt는 현재 process와는 아무런 관련이 없는 행동을 한다. 그래서 만약 signal을 만들어서 현재 프로세스에게 보내는 행위는 아무런 의미가 없고 오히려 현재 프로세스를 방해하는 역할만 할 뿐이다. 결국, signal은 Exception 핸들러만 만들어 내고 interrupt 핸들러는 만들지 않는다. 모드 스위칭을 해서 커널 스택에 다 save해야 하는 등 서로의 매커니즘은 비슷하지만 핸들러가 시그널을 만드는가의 핵심 차이가 있다.
Interrupt Classes
- Critical (중요)
- 마스크 가능한 인터럽트가 비활성화된 상태에서 즉시 조치를 요구합니다. ( Immediate actions required with maskable interrupts disabled.) 즉, 다른 인터럽트는 차단하고 해당 인터럽트에 집중해서 즉시 처리합니다.
- 예를 들어, PIC(프로그래머블 인터럽트 컨트롤러)에 인터럽트를 인지하고, PIC나 장치 컨트롤러를 재프로그래밍하고, CPU와 장치 양쪽에서 접근하는 데이터 구조를 업데이트하는 것입니다. 이러한 작업들은 중요하며 신속하게 수행되어야 합니다.
- Noncritical (비중요)
- 인터럽트가 활성화된 상태에서 즉시 조치를 요구합니다.
- 예를 들어, CPU만이 접근하는 데이터 구조를 업데이트하는 것이 있습니다(예: 키보드 키가 눌렸을 때의 스캔 코드 읽기).
- Noncritical deferrable (연기 가능한 비중요)
- 커널 작업에 영향을 주지 않고 오랫동안 연기될 수 있습니다.
- 예를 들어, 버퍼(예: 키보드 라인 버퍼) 내용을 어떤 프로세스의 주소로 복사하는 것이 있습니다. 관심 있는 프로세스는 데이터를 기다릴 것입니다.
- 이는 softirqs, tasklets, work queues와 같은 별도의 함수를 통해 처리됩니다(Linux에서, 다음 슬라이드에서 설명).
인터럽트는 시스템이 외부에서 들어오는 신호나 요청에 반응해야 할 때 사용되며, 그 긴급성에 따라 다른 방식으로 처리됩니다. 중요한 인터럽트는 시스템의 주요 작업을 방해하지 않는 선에서 가능한 빠르게 처리되어야 하고, 비중요한 인터럽트는 덜 긴급하여 인터럽트가 활성화된 상태에서도 처리할 수 있으며, 연기 가능한 비중요 인터럽트는 시스템의 기본 작업에 영향을 주지 않는 한 연기될 수 있습니다.
Conflicting Goals of Interrupt Handler
- Interrupt processing must be fast! (인터럽트 처리는 빨라야 합니다!)
- 인터럽트 핸들러는 현재 실행 중인 코드(예: 커널 코드, 다른 인터럽트 핸들러, 사용자 프로세스 등)와 비동기적으로 실행되어 이를 중단시킬 수 있습니다. 중단된 코드의 지연을 피하기 위해 인터럽트 핸들러는 신속하게 완료되어야 합니다.
- 인터럽트 핸들러는 해당 인터럽트(또는 모든 인터럽트)와 함께 현재 프로세서가 비활성화된 상태에서 실행됩니다. 이는 인터럽트 핸들러가 가능한 한 빠르게 작업을 완료하고 인터럽트를 다시 활성화해야 함을 의미합니다.
- 인터럽트 핸들러는 때때로 상당한 양의 작업을 수행합니다.
- 작업에 시간이 걸릴 수 있습니다(예: 네트워크 인터페이스 카드(NIC)에서 네트워크 패킷 처리).
- 인터럽트 핸들러는 블로킹될 수 없으며, 이는 인터럽트 핸들러에서 수행할 수 있는 작업을 제한합니다.
- 해결책
- 인터럽트 핸들러를 'Top-half'(상반부)와 'Bottom-half'(하반부)로 분할합니다.
'Top-half'와 'Bottom-half'는 인터럽트 처리를 두 부분으로 나누어 처리하는 설계 패턴입니다. 'Top-half'는 인터럽트에 빠르게 반응하여 필수적인 최소한의 처리를 수행하고, 나머지 덜 긴급한 작업은 'Bottom-half'에 의해 처리되어 시스템의 다른 작업을 방해하지 않으면서도 인터럽트 처리를 완성합니다. 이러한 분할 처리는 효율적인 시스템 성능을 유지하는 데 도움이 됩니다.
Top-half and Bottom-half of interrupt handler
- Top-half (일명, hard IRQ handler)
- 하드웨어 인터럽트 수신 즉시 실행됩니다.
- 기본적인 하드웨어 관련 및 시간에 민감한 작업을 수행합니다.
- 일부 또는 모든 인터럽트가 비활성화된 상태에서 실행됩니다.
- 나머지 작업(즉, 'Bottom-half')을 나중에 실행되도록 스케줄합니다.
- 즉시 종료합니다.
- 이 방식으로, 커널 응답 시간을 최소화합니다!
- Bottom-half (일명, soft IRQ handler)
- 인터럽트 핸들러의 하위 작업(즉, 비교적 중요도가 낮고 시간을 많이 소모하는 작업)이 나중에 모든 인터럽트가 활성화된 상태에서 실행됩니다.
- 인터럽트에 대한 실질적인 처리를 담당하는 부분입니다.
이러한 분할 처리 방식은 인터럽트가 발생했을 때 커널이 빠르게 반응할 수 있도록 하면서도, 시스템의 다른 부분에 미치는 영향을 최소화하고, 더 복잡하거나 시간이 많이 소요되는 작업을 나중에 처리할 수 있게 합니다. 이는 인터럽트 처리의 효율성을 높이고 시스템의 전반적인 성능을 개선하는 데 도움이 됩니다.
⭐️Linux Solution for Bottom-half Implementation
- Top-half와 Bottom-half로 나누어서 INTR 핸들러를 돌리는 이유:
- Top-half (Hard IRQ Handler): 이 부분은 인터럽트가 발생했을 때 즉시 실행됩니다. Top-half는 매우 빠르게 실행되어야 하며, 주로 인터럽트에 의해 필요한 가장 긴급하고 기본적인 처리를 담당합니다. 이는 하드웨어와 관련된 시간에 민감한 작업을 포함하며, 일반적으로 다른 인터럽트를 받지 않도록 인터럽트를 비활성화한 상태에서 실행됩니다.
- Bottom-half (Soft IRQ Handler): Bottom-half는 Top-half에 의해 예약된 나머지 작업을 처리합니다. 이 부분은 시간에 덜 민감하거나 덜 긴급한 작업을 처리하며, 일반적으로 모든 인터럽트가 활성화된 상태에서 실행됩니다. Bottom-half는 시스템의 응답성을 유지하면서도 더 복잡하거나 시간이 오래 걸리는 작업을 수행할 수 있습니다.
- Work Queue를 사용하는 이유:
- 블로킹 작업 수행 가능: Work Queue는 프로세스 컨텍스트에서 실행되므로, 인터럽트 컨텍스트에서는 수행할 수 없는 슬립(블로킹) 작업을 할 수 있습니다. 예를 들어, 대량의 메모리 할당, 세마포어 획득, 블록 I/O 수행 등이 가능합니다.
- 유연한 작업 스케줄링: Work Queue는 특정 작업을 나중에 수행하기 위해 예약할 수 있으며, 커널 스레드에 의해 실행됩니다. 이는 인터럽트 핸들링을 더 유연하게 만들어주며, 시스템 부하를 분산시키는 데 도움이 됩니다. Runs in process context; thus schedulable and can therefore sleep
- 복잡한 작업 처리: Work Queue는 복잡하거나 시간이 많이 소요되는 작업을 처리하는 데 적합합니다. 특히, 디바이스 드라이버에서 비동기적으로 처리해야 하는 복잡한 작업을 관리하는 데 자주 사용됩니다.
- 컨텍스트 스위칭으로 인한 오버헤드: Work Queue는 커널 스레드를 기반으로 하기 때문에 컨텍스트 스위칭이 발생합니다. 이는 오버헤드를 발생시킬 수 있지만, 동시에 더 복잡한 작업을 가능하게 합니다.
'CS 지식 > 시스템프로그래밍' 카테고리의 다른 글
Chapter 4 : Timing Measurements (0) | 2023.12.25 |
---|---|
Chapter 1: Linux Processes (0) | 2023.12.22 |
소개 (0) | 2023.12.21 |