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

v6.6 / kernel/softirq.c

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

## do_softirq

```c

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);
}

```

### 441행

```c

asmlinkage __visible void do_softirq(void)

```

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

### 443행

```c

	__u32 pending;

```

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

### 444행

```c

	unsigned long flags;

```

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

### 446행

```c

	if (in_interrupt())

```

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

### 447행

```c

		return;

```

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

### 449행

```c

	local_irq_save(flags);

```

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

### 451행

```c

	pending = local_softirq_pending();

```

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

### 453행

```c

	if (pending)

```

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

### 454행

```c

		do_softirq_own_stack();

```

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

### 456행

```c

	local_irq_restore(flags);

```

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

