Linux v6.18.37 · 개념과 코드 읽기

IRQ controller: GICv3, local APIC/IOAPIC와 RISC-V INTC

이 코드는 어떤 문제를 푸나요?

장치의 인터럽트를 처리한 뒤에는 컨트롤러에도 처리 상태를 갱신해야 합니다. arm64의 GIC, x86의 APIC 계열, RISC-V의 PLIC/AIA 등은 확인과 완료 방식이 다릅니다. 대표로 GICv3의 일반 EOI 콜백을 읽으며 Linux IRQ 번호와 하드웨어 INTID를 구분합니다.

읽을 범위: v6.18.37 · drivers/irqchip/irq-gic-v3.c · gic_eoi_irq 719–733행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.

먼저 알아둘 개념

INTID와 Linux IRQ

GIC가 사용하는 번호와 Linux irqdomain이 관리하는 번호는 구분됩니다. irqd_to_hwirq는 하드웨어 번호를 꺼냅니다.

EOI

처리 우선순위와 활성 상태의 종료에 관련된 동작입니다. EOImode에 따라 우선순위 종료와 deactivate가 분리될 수 있습니다.

erratum

특정 CPU나 시스템 구현의 알려진 문제를 우회하는 추가 동작입니다. 모든 기기에 항상 실행된다고 읽으면 안 됩니다.

처음 읽을 때

장치 요청, CPU 확인, 드라이버 처리, 컨트롤러 완료를 순서대로 설명해 보십시오.

더 깊이 살펴볼 때

일반 EOI 경로와 EOImode1·vCPU 전달·LPI 경로의 차이를 원문에서 비교하십시오.

그림으로 보는 변화

IRQ controller: GICv3, local APIC/IOAPIC와 RISC-V INTC의 단계별 개념 그림
각 단계에 화살표 의미와 생략 범위를 표시했습니다. 주소·숫자 예제는 실제 장치 값을 뜻하지 않습니다.
1단계 설명

1단계 고정

GIF 원본 열기

1. 하드웨어 번호 선택

irq_data에서 GIC INTID를 얻습니다.

화살표는 Linux 자료구조에서 하드웨어 번호를 꺼내는 관계입니다.

2. EOI 기록

ICC_EOIR1_EL1에 번호를 쓰고 ISB를 수행합니다.

레지스터 쓰기는 데이터 버퍼 저장이 아니라 GIC 상태 변경입니다.

3. 필요한 보완 처리

해당 erratum이 있으면 DSB 후 별도 비활성화를 수행합니다.

이 화살표는 조건이 참일 때만 이어집니다.

gic_eoi_irq를 한 줄씩 읽기

줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.

static void gic_eoi_irq(struct irq_data *d)
{
	write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);
	isb();

	if (gic_arm64_erratum_2941627_needed(d)) {
		/*
		 * Make sure the GIC stream deactivate packet
		 * issued by ICC_EOIR1_EL1 has completed before
		 * deactivating through GICD_IACTIVER.
		 */
		dsb(sy);
		gic_poke_irq(d, GICD_ICACTIVER);
	}
}
static void gic_eoi_irq(struct irq_data *d)

일반 GIC EOI 경로의 IRQ chip 콜백입니다. 다른 EOImode용 콜백도 있으므로 모든 GIC 종료를 이 한 함수로 일반화하지 않습니다.

	write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);

irq_data에서 하드웨어 INTID를 얻어 ICC_EOIR1_EL1에 씁니다. Linux IRQ 번호를 그대로 쓰는 것이 아니라 GIC가 이해하는 번호를 사용합니다.

	isb();

ISB로 CPU 인터페이스 시스템 레지스터 접근 뒤의 명령 실행을 동기화합니다.

	if (gic_arm64_erratum_2941627_needed(d)) {

해당 인터럽트 처리에 Arm erratum 2941627 보완이 필요한지 검사합니다. 참인 시스템에서만 추가 경로를 실행합니다.

		dsb(sy);

EOIR로 발생한 GIC stream deactivate가 필요한 완료 조건을 만족하도록 DSB SY를 수행합니다. 앞의 ISB와 다른 역할입니다.

		gic_poke_irq(d, GICD_ICACTIVER);

해당 인터럽트의 active 상태를 GICD_ICACTIVER에 쓰는 방식으로 지웁니다. active는 현재 처리 중임을 나타내는 상태이며 IRQ의 enable 비트를 내려 앞으로의 수신을 차단하는 동작과 다릅니다. 앞의 완료 처리만으로 충분하지 않은 하드웨어 erratum 조건에서 추가로 수행합니다.

함께 생각해 볼 질문

EOI가 장치 자체의 원인을 없앱니까?

아닙니다. 장치의 상태 레지스터 등에서 원인을 해소하는 동작과 컨트롤러 완료는 별개입니다.

IRQ 번호를 그대로 EOIR에 씁니까?

이 함수는 Linux IRQ가 아니라 변환된 하드웨어 INTID를 씁니다.

모든 GIC 완료가 이 함수로 끝납니까?

아닙니다. EOImode와 LPI·가상화 경로에 따라 다른 콜백이 사용됩니다.

출처와 읽은 범위

Linux stable v6.18.37 · drivers/irqchip/irq-gic-v3.c

해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고

맨 위로 ↑