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

미뤄 둔 작업이 있는지 확인한 뒤 처리합니다

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

하드웨어 IRQ에서 모든 일을 끝내면 다른 인터럽트 처리가 오래 지연될 수 있습니다. 일부 작업을 softirq로 미뤄 처리합니다. do_softirq는 현재 문맥을 확인하고 CPU에 남은 작업 비트를 읽어 실행 여부를 결정합니다.

읽을 범위: v6.6 · kernel/softirq.c · do_softirq 441–457행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.

먼저 알아둘 개념

pending 비트

처리할 종류가 있음을 나타내는 표시입니다. 작업 객체 전체를 담는 큐 자체와는 다릅니다.

IRQ 저장·복원

현재 마스크 상태를 기억했다가 그대로 되돌립니다. 무조건 인터럽트를 켜는 것과 다릅니다.

처음 읽을 때

코드를 읽을 때 이미 인터럽트 문맥이면 이 진입 경로를 진행하지 않습니다. 그다음 어느 상태가 바뀌는지 각 줄에서 확인하세요.

더 깊이 살펴볼 때

이 경로의 호출 문맥, 잠금·인터럽트 상태, 오류 시 남는 자원을 함께 추적해 보세요. 호출된 함수가 수행하는 작업과 현재 함수가 직접 보장하는 범위를 구분하는 것이 중요합니다.

그림으로 보는 변화

미뤄 둔 작업이 있는지 확인한 뒤 처리합니다의 단계별 개념 그림
각 단계에 화살표 의미와 생략 범위를 표시했습니다. 주소·숫자 예제는 실제 장치 값을 뜻하지 않습니다.
1단계 설명

1단계 고정

GIF 원본 열기

1. 호출 문맥 확인

이미 인터럽트 문맥이면 이 진입 경로를 진행하지 않습니다.

분기 화살표는 조기 반환을 포함합니다.

2. pending 읽기

로컬 IRQ 상태를 보존하고 처리할 작업 비트를 확인합니다.

다른 CPU 전체의 pending을 한 번에 읽는 것이 아닙니다.

3. 처리와 복원

작업이 있으면 실행하고 원래 IRQ 상태를 복원합니다.

별도 스택 사용과 새 태스크 생성은 구분합니다.

do_softirq를 한 줄씩 읽기

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

asmlinkage __visible void do_softirq(void)
{
	__u32 pending;
	unsigned long flags;

	if (in_interrupt())
		return;

	local_irq_save(flags);

	pending = local_softirq_pending();

	if (pending)
		do_softirq_own_stack();

	local_irq_restore(flags);
}
asmlinkage __visible void do_softirq(void)

호출 규약·가시성·초기화 섹션·반환 여부 같은 함수 속성을 컴파일러에 알려 줍니다. 이 표기 자체가 초기화 함수를 호출하는 줄은 아닙니다.

	__u32 pending;

이 CPU에서 처리 대기 중인 softirq 종류를 비트별로 기록할 값입니다. 하나의 IRQ 번호가 아니라 여러 종류의 대기 상태를 함께 담습니다.

	unsigned long flags;

local_irq_save가 진입 당시 IRQ 상태를 보관할 변수입니다. 처리를 마칠 때 이를 사용해 원래 상태로 돌아가므로 무조건 IRQ를 켜는 동작과 다릅니다.

	if (in_interrupt())

이미 인터럽트 문맥인 경우 이 일반 softirq 진입 경로에서 재진입하지 않도록 검사합니다.

		return;

이 경로에서 할 일이 없거나 진행할 수 없는 문맥이므로 값을 돌려주지 않고 호출자에게 돌아갑니다.

	local_irq_save(flags);

이 CPU의 IRQ 상태를 flags에 기록한 뒤 IRQ를 막습니다. 끝에서 원래 상태를 복원할 수 있습니다.

	pending = local_softirq_pending();

현재 CPU에 처리 대기 중인 softirq 종류를 비트마스크로 읽습니다.

	if (pending)

현재 CPU에 대기 중인 softirq 비트가 하나라도 있을 때만 처리 함수를 호출합니다.

		do_softirq_own_stack();

대기 중인 softirq를 적절한 스택 경로에서 처리합니다.

	local_irq_restore(flags);

진입 때 저장한 IRQ 상태를 복원합니다. 무조건 활성화한다고 해석하지 않습니다.

함께 생각해 볼 질문

pending이 0이면 무엇을 하나요?

softirq 본문은 실행하지 않고 원래 IRQ 상태를 복원합니다.

IRQ restore는 항상 IRQ enable인가요?

이전에 저장했던 상태를 복구합니다.

softirq이면 잠드는 작업을 자유롭게 해도 되나요?

실행 문맥과 구성에 따른 제약을 확인해야 합니다. 일반 프로세스 문맥처럼 가정하면 안 됩니다.

출처와 읽은 범위

Linux stable v6.6 · kernel/softirq.c

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

맨 위로 ↑