Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

16312
2027
233849


[리눅스커널] Soft IRQ 소개 6. 인터럽트 후반부 처리

Soft IRQ는 리눅스 커널을 이루는 핵심 기능 중 하나입니다. Soft IRQ 서비스 형태로 커널의 타이머, 스케줄링은 물론 네트워크 시스템에서 사용합니다. Soft IRQ 은 인터럽트 후반부 기법으로 씁니다. 이번 절에서는 Soft IRQ를 인터럽트 후반부 처리 중심으로 살펴봅니다. Soft IRQ 전체 구조를 익힌 다음 Soft IRQ에서 프로세스, 타이머 혹은 네트워크 시스템을 어떻게 처리하는지 알아보는 것이 좋습니다.  

Soft IRQ 를 실행한다는 것은 Soft IRQ 서비스 요청을 받아 이를 처리하는 과정입니다. Soft IRQ 전체 흐름을 이해하려면 먼저 Soft IRQ 서비스에 대해 알아야 합니다.

Soft IRQ 서비스 소개

우선 Soft IRQ 서비스란 용어를 알아봅시다. 리눅스 커널에서는 다음과 같이 10가지 Soft IRQ 서비스를 지원합니다. 
include/linux/interrupt.h 
const char * const softirq_to_name[NR_SOFTIRQS] = {
"HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "IRQ_POLL",
"TASKLET", "SCHED", "HRTIMER", "RCU"
};

“HI” 부터 “RCU” 까지가 Soft IRQ 서비스 이름입니다.
Soft IRQ 서비스는 부팅할 때 open_softirq() 란 함수를 써서 등록합니다.

이어서 Soft IRQ 서비스 실행 흐름을 단계별로 소개합니다.

Soft IRQ 서비스 라이프 사이클

Soft IRQ 서비스의 실행 흐름은 크게 3 단계로 나눌 수 있습니다. 다음 그림을 Soft IRQ 서비스 라이프 사이클에 대해서 알아봅시다.

 
  [그림 6.9] Soft IRQ 서비스 단계 별 실행 흐름

부팅 과정에서는 Soft IRQ 서비스를 1번 등록하고 [2]과 [3] 단계는 매우 자주 반복 실행합니다.

[1] 단계: 부팅 과정 
부팅 과정에서 open_softirq() 함수를 호출해 Soft IRQ 서비스를 등록합니다.

[2] 단계: 인터럽트 처리 
인터럽트 핸들러(인터럽트 컨택스트)나 인터럽트 서브 함수에서 raise_softirq() 함수를 호출해 Soft IRQ 서비스를 요청합니다. raise_softirq() 함수 이름 그대로 "Soft IRQ를 올린다"라고 부르는 경우도 있습니다.

이번 Soft IRQ 절에서는 이 동작을 "Soft IRQ 서비스를 요청한다"고 명시합니다.

[3] 단계: Soft IRQ 컨택스트 
__do_softirq() 함수에서 이미 요청한 Soft IRQ 서비스를 실행합니다.

인터럽트 핸들링이 끝나고 Soft IRQ 서비스를 바로 실행하는 동작을 Soft IRQ 컨택스트라고 합니다.
 
Soft IRQ 서비스 핸들러

 Soft IRQ 서비스 핸들러는 Soft IRQ 서비스를 실행할 때 호출하는 함수입니다. 부팅 과정에서 open_softirq() 함수로 Soft IRQ 서비스를 등록할 때 softirq_vec이란 전역 변수에 등록합니다. 다음 softirq_vec 전역 변수는 Trace32로 라즈베리안에 등록된 Soft IRQ 서비스 핸들러 정보입니다. 
(static struct softirq_action [10]) [D:0x80C02080] softirq_vec = (
    [0] = ((void (*)()) [D:0x80C02080] action = 0x80122888 = tasklet_hi_action),
    [1] = ((void (*)()) [D:0x80C02084] action = 0x80181270 = run_timer_softirq),
    [2] = ((void (*)()) [D:0x80C02088] action = 0x80614684 = net_tx_action),
    [3] = ((void (*)()) [D:0x80C0208C] action = 0x80615AB0 = net_rx_action),
    [4] = ((void (*)()) [D:0x80C02090] action = 0x804279B0 = blk_done_softirq),
    [5] = ((void (*)()) [D:0x80C02094] action = 0x0 = ),
    [6] = ((void (*)()) [D:0x80C02098] action = 0x8012299C = tasklet_action),
    [7] = ((void (*)()) [D:0x80C0209C] action = 0x801588EC = run_rebalance_domains),
    [8] = ((void (*)()) [D:0x80C020A0] action = 0x0 = ),
    [9] = ((void (*)()) [D:0x80C020A4] action = 0x8017ABC4 = rcu_process_callbacks))

이 함수들은 __do_softirq() 함수에서 호출됩니다.

Soft IRQ 서비스를 요청할 때는 raise_softirq() 함수나 raise_softirq_irqoff() 함수를 호출해야 합니다. 이 때 요청할 Soft IRQ 서비스 아이디를 지정해야 합니다.

* 유튜브 강의 동영상도 있으니 같이 들으시면 좋습니다.




"이 포스팅이 유익하다고 생각되시면 댓글로 응원해주시면 감사하겠습니다.  
혹시 글을 읽고 궁금점이 있으면 댓글로 질문 남겨주세요. 상세한 답글 올려 드리겠습니다!"

# Reference 인터럽트 후반부 처리








6.9 Soft IRQ 서비스는 누가 언제 처리하나?




6.13 Soft IRQ 디버깅
6.13.1 ftrace Soft IRQ 이벤트 분석 방법
6.13.2 /proc/softirqs로 Soft IRQ 서비스 실행 횟수 확인


# Reference: For more information on 'Linux Kernel';

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2


Thanks,
Austin Kim



    핑백

    덧글

    • 김문섭 2019/10/30 12:52 # 삭제 답글

      한가지 질문이 있는데요,
      threaded irq와 Soft irq의 차이점은 irq handler를 수행하는데 있어서,
      process level(thread)의 관여가 있느냐 없느냐? 수준으로 생각하면 되나요?
    • AustinKim 2019/10/30 13:36 #

      맞습니다. 부연해 설명을 드리겠습니다.

      threaded IRQ 방식과 Soft IRQ 방식의 차이점은 다음과 같습니다.
      1. threaded IRQ는 인터럽트 후반부를 처리하는 전용 프로세스인 IRQ 스레드가 인터럽트 후반부를 처리합니다.
      즉, 프로세스 레벨에서 인터럽트 후반부를 처리합니다.

      2. Soft IRQ는 인터럽트 핸들러 처리를 마무리 한 후 바로 실행을 시작합니다.

      두 방식의 처리 순서는 다음과 같습니다.

      【threaded IRQ】
      1. 인터럽트 발생
      2. 인터럽트 핸들러 실행 마무리
      3. 스케줄링
      4. threaded IRQ(IRQ 스레드) 실행
      5. 인터럽트 후반부 처리

      【Soft IRQ】
      1. 인터럽트 발생
      2. 인터럽트 핸들러 실행 마무리
      3. Soft IRQ 서비스 실행
      4. 인터럽트 후반부 처리
    • AustinKim 2019/10/30 13:36 # 답글

      맞습니다. 부연해 설명을 드리겠습니다.

      threaded IRQ 방식과 Soft IRQ 방식의 차이점은 다음과 같습니다.
      1. threaded IRQ는 인터럽트 후반부를 처리하는 전용 프로세스인 IRQ 스레드가 인터럽트 후반부를 처리합니다.
      즉, 프로세스 레벨에서 인터럽트 후반부를 처리합니다.

      2. Soft IRQ는 인터럽트 핸들러 처리를 마무리 한 후 바로 실행을 시작합니다.

      두 방식의 처리 순서는 다음과 같습니다.

      【threaded IRQ】
      1. 인터럽트 발생
      2. 인터럽트 핸들러 실행 마무리
      3. 스케줄링
      4. threaded IRQ(IRQ 스레드) 실행
      5. 인터럽트 후반부 처리

      【Soft IRQ】
      1. 인터럽트 발생
      2. 인터럽트 핸들러 실행 마무리
      3. Soft IRQ 서비스 실행
      4. 인터럽트 후반부 처리
    • albeit 2021/02/04 14:50 # 삭제 답글

      안녕하세요 위의 내용에서 추가적으로 궁금한게 있어서 문의드립니다.

      Soft IRQ에서
      1. 프로그램이 실행중(프로세스) 에서 인터럽트 발생
      2. 인터럽트 핸들러 처리(top half)
      3. Soft IRQ 서비스 실행
      4. 인터럽트 후반부 처리

      Q1. core가 1개 일때 위 과정으로 처리하게 되면 인터럽트 후반부 처리가 끝날 때까지 실행중이던 프로세스로 전환이 안되기 때문에 모두 top half에서 처리 하는것과 차이가 없는 것 아닌가요?

      Q2. threaded IRQ 3.스케줄링은 이전의 프로세스로 돌아가는 스케줄링인가요? 그러면 여기서도 마찬가지로 core가 1개 일 때, 4. threaded IRQ(IRQ 스레드) 실행 으로 오게 되면 kernel thread인 threaded IRQ를 처리하기 위해서 svc 모드로 전환되어 인터럽트 후반부 처리가 끝날때까지 유저 프로세스는 실행이 안되는 상황 아닌가요?
    • AustinKim 2021/02/05 08:18 #

      A1. Soft IRQ 서비스는 인터럽트 핸들러의 실행을 마무리한 후 바로 일을 시작합니다. 이 시점에서는 프로세스로 전환이 이뤄지지 않습니다. 하지만 Soft IRQ 서비스 핸들러 실행 시간이 오래 걸리면 바로 프로세스로 복귀하게 됩니다.

      Soft IRQ 서비스를 스레드 레벨에서 처리하는 용도의 커널 스레드가 ksoftirqd 스레드인데, 이 스레드에서도 인터럽트의 후반부를 처리할 수 있습니다.

      인터럽트 핸들러에서 Soft IRQ 서비스를 요청하면, 인터럽트 핸들러 실행을 마친 후 바로 Soft IRQ 서비스 핸들러를 호출하게 됩니다. 이 과정만 보면 이게 무슨 후반부 처리인가란 의문이 생길 수 있습니다. 그런데 Soft IRQ 서비스를 다양한 용도로 설계할 수 있습니다. 사실 인터럽트 핸들러 이외에도 프로세스 레벨에서 Soft IRQ 서비스를 요청할 수 있는데, 인터럽트가 발생한 후 호출되는 Soft IRQ 서비스 핸들러에서는 Soft IRQ 서비스를 통해 관리되는 드라이버의 동기를 맞출 수 있습니다.

      예를 들면 다음과 같은 시나리오를 이야기할 수 있습니다.

      1. Soft IRQ 서비스 요청(스레드 레벨)
      2. ksoftirqd 스레드에서 Soft IRQ 서비스 실행
      : 인터럽트가 올라올 때 까지 바이패스 하자
      : 특정 필드에 설정
      3. 인터럽트 발생
      4. _do_softirq() 함수에서 Soft IRQ 서비스 실행

      이런 내용은 입문자 입장에서는 이해하기 어려울 것 같아 책에서는 너무 구체적으로 설명하지 않았습니다.

      A2. 유저 프로세스가 실행하는 동안에 IRQ 스레드는 다음과 같은 순서로 동작합니다.

      1. 유저 프로세스 동작
      2. 인터럽트 발생
      3. 인터럽트 벡터로 실행 공간 이동
      4. 인터럽트 핸들러에서 IRQ 스레드를 깨움
      5. 인터럽트 핸들러에서 실행을 마무리
      6. 유저 프로세스로 복귀
      ...(6.7 사이에 인터럽트가 지속적으로 발생합니다.)
      7. 인터럽트가 발생(전체 시스템 관점)
      : 대부분 리눅스 시스템(1.5GHz 이상)에서 1초에 인터럽트(전체 시스템 관점)가 1500번 이상 발생합니다.
      7.1 인터럽트 처리를 마친 후 선점 스케줄링을 할 조건인지 체크
      : IRQ 스레드로 Preemption
      7.2 IRQ 스레드 핸들러를 통해 IRQ 처리 함수 호출
      8. 스케줄러에 의해 유저 프로세스는 다시 실행

      조금 어려운 내용인데요. '10장 스케줄링'을 읽으면 더 빨리 이해할 수 있습니다.

      감사합니다.
    • albeit 2021/02/05 09:47 # 삭제 답글

      자세한 답변 감사드립니다. 프로세스 인터럽트 스케줄링 등이 다 엮여 있기 때문에 책 내용을 전체적으로 학습 한 후에 다시 봐야 이해가 더 잘되겠네요. 좋은 책 써주셔서 감사합니다.
    댓글 입력 영역