# 잠금 검사기의 한도와 메모리 사용량을 확인합니다

v6.18.37 / kernel/locking/lockdep.c

lockdep은 관찰한 잠금 획득 순서를 이용해 모순된 의존 관계를 찾는 검사기입니다. 이름만 보고 lockdep_init 안에서 그래프 전체를 새로 할당한다고 생각하기 쉽지만, 이 버전의 함수는 주로 설정 한도와 메모리 사용량을 보고합니다. 실제 의존성 기록·검사는 별도 경로입니다.

## lockdep_init

```c

void __init lockdep_init(void)
{
	pr_info("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");

	pr_info("... MAX_LOCKDEP_SUBCLASSES:  %lu\n", MAX_LOCKDEP_SUBCLASSES);
	pr_info("... MAX_LOCK_DEPTH:          %lu\n", MAX_LOCK_DEPTH);
	pr_info("... MAX_LOCKDEP_KEYS:        %lu\n", MAX_LOCKDEP_KEYS);
	pr_info("... CLASSHASH_SIZE:          %lu\n", CLASSHASH_SIZE);
	pr_info("... MAX_LOCKDEP_ENTRIES:     %lu\n", MAX_LOCKDEP_ENTRIES);
	pr_info("... MAX_LOCKDEP_CHAINS:      %lu\n", MAX_LOCKDEP_CHAINS);
	pr_info("... CHAINHASH_SIZE:          %lu\n", CHAINHASH_SIZE);

	pr_info(" memory used by lock dependency info: %zu kB\n",
	       (sizeof(lock_classes) +
		sizeof(lock_classes_in_use) +
		sizeof(classhash_table) +
		sizeof(list_entries) +
		sizeof(list_entries_in_use) +
		sizeof(chainhash_table) +
		sizeof(delayed_free)
#ifdef CONFIG_PROVE_LOCKING
		+ sizeof(lock_cq)
		+ sizeof(lock_chains)
		+ sizeof(lock_chains_in_use)
		+ sizeof(chain_hlocks)
#endif
		) / 1024
		);

#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING)
	pr_info(" memory used for stack traces: %zu kB\n",
	       (sizeof(stack_trace) + sizeof(stack_trace_hash)) / 1024
	       );
#endif

	pr_info(" per task-struct memory footprint: %zu bytes\n",
	       sizeof(((struct task_struct *)NULL)->held_locks));
}

```

### 6632행

```c

void __init lockdep_init(void)

```

이 시점의 lockdep 함수는 잠금 의존성 추적의 한도와 정적 저장 공간 크기를 부팅 로그에 보여 줍니다. 실제 교착 가능성 검사는 이후 잠금 획득·해제 경로에서 수행됩니다.

### 6634행

```c

	pr_info("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");

```

잠금 의존성 검증기가 포함되었음을 알리는 배너를 출력합니다. 아래의 추적 한도와 메모리 사용량 보고가 어느 기능의 정보인지 구분하는 시작입니다.

### 6636행

```c

	pr_info("... MAX_LOCKDEP_SUBCLASSES:  %lu\n", MAX_LOCKDEP_SUBCLASSES);

```

같은 잠금 종류 안에서 중첩 관계를 구별할 subclass의 최대 수입니다. 현재 잠겨 있는 객체 개수가 아니라 구분 가능한 계층 수를 출력합니다.

### 6637행

```c

	pr_info("... MAX_LOCK_DEPTH:          %lu\n", MAX_LOCK_DEPTH);

```

태스크 하나에서 동시에 보유한 잠금 상태를 기록할 수 있는 최대 깊이입니다. 잠금 함수의 재귀를 이 횟수까지 허용한다는 뜻은 아닙니다.

### 6638행

```c

	pr_info("... MAX_LOCKDEP_KEYS:        %lu\n", MAX_LOCKDEP_KEYS);

```

lockdep이 서로 다른 잠금 클래스를 식별하여 보관할 수 있는 최대 수입니다. 같은 클래스의 여러 잠금 객체와 클래스 종류 수를 구분해야 합니다.

### 6639행

```c

	pr_info("... CLASSHASH_SIZE:          %lu\n", CLASSHASH_SIZE);

```

잠금 클래스를 빠르게 찾는 해시 테이블의 버킷 수입니다. 분류된 클래스 전체 개수와 다른 저장 구조의 크기를 보고합니다.

### 6640행

```c

	pr_info("... MAX_LOCKDEP_ENTRIES:     %lu\n", MAX_LOCKDEP_ENTRIES);

```

먼저 잡은 잠금과 다음에 잡는 잠금 사이의 의존 관계를 기록할 최대 항목 수입니다. 순서 충돌이나 교착 가능성을 찾는 그래프의 용량과 관련됩니다.

### 6641행

```c

	pr_info("... MAX_LOCKDEP_CHAINS:      %lu\n", MAX_LOCKDEP_CHAINS);

```

추적할 수 있는 서로 다른 잠금 획득 체인의 최대 수입니다. 한 태스크가 현재 보유한 잠금 개수와는 다른 전체 추적 한도입니다.

### 6642행

```c

	pr_info("... CHAINHASH_SIZE:          %lu\n", CHAINHASH_SIZE);

```

이미 본 잠금 획득 체인을 찾기 위한 해시 테이블의 버킷 수입니다. 중복된 체인을 다시 분석하지 않도록 조회하는 기반입니다.

### 6644행

```c

	pr_info(" memory used by lock dependency info: %zu kB\n",

```

lockdep의 정적 클래스·의존 관계·체인 저장소가 차지하는 총량을 출력합니다. 뒤의 sizeof 합계가 이 값이며 지금 동적으로 할당한 객체 수를 세는 출력은 아닙니다.

### 6645행

```c

	       (sizeof(lock_classes) +

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: (sizeof(lock_classes) +

### 6646행

```c

		sizeof(lock_classes_in_use) +

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: sizeof(lock_classes_in_use) +

### 6647행

```c

		sizeof(classhash_table) +

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: sizeof(classhash_table) +

### 6648행

```c

		sizeof(list_entries) +

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: sizeof(list_entries) +

### 6649행

```c

		sizeof(list_entries_in_use) +

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: sizeof(list_entries_in_use) +

### 6650행

```c

		sizeof(chainhash_table) +

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: sizeof(chainhash_table) +

### 6651행

```c

		sizeof(delayed_free)

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: sizeof(delayed_free)

### 6652행

```c

#ifdef CONFIG_PROVE_LOCKING

```

잠금 획득 순서와 의존 관계를 추적해 교착 가능성을 진단하는 설정입니다. 여기서는 실제 검사 실행이 아니라 이 기능에만 필요한 잠금 체인 자료의 크기를 메모리 사용량 합계에 포함합니다. 이 선택은 전처리 단계에서 이루어지며, CPU가 실행 중 이 줄의 조건을 검사하지 않습니다.

### 6653행

```c

		+ sizeof(lock_cq)

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: + sizeof(lock_cq)

### 6654행

```c

		+ sizeof(lock_chains)

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: + sizeof(lock_chains)

### 6655행

```c

		+ sizeof(lock_chains_in_use)

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: + sizeof(lock_chains_in_use)

### 6656행

```c

		+ sizeof(chain_hlocks)

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: + sizeof(chain_hlocks)

### 6657행

```c

#endif

```

잠금 의존성 검증을 사용할 때 필요한 체인 자료의 크기 합산을 마칩니다. 전체 바이트 합계를 KiB로 바꾸는 식은 조건 바깥에서 이어집니다.

### 6658행

```c

		) / 1024

```

앞에서 합한 바이트 수를 1024로 나누어 KiB 단위로 표시합니다. 출력 문자열의 kB 표기와 관계없이 실제 나눗셈 기준은 1024입니다. 앞줄에서 시작한 호출이나 식에 이어지는 부분이므로, 이 줄만으로 별도의 함수 호출이 생기지는 않습니다.

### 6659행

```c

		);

```

앞줄들에서 계산한 저장 공간 크기를 로그 함수의 인자로 넘겨 해당 보고를 마칩니다. 이 지점에서 추가 메모리를 할당하지 않습니다.

### 6661행

```c

#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING)

```

IRQ 허용·차단 지점을 추적하는 TRACE_IRQFLAGS와 잠금 의존성을 검사하는 PROVE_LOCKING을 모두 포함한 경우입니다. 잠금 사용 문맥을 진단할 스택 추적 자료가 존재하므로 그 저장 공간 크기를 별도로 출력합니다. 이 선택은 전처리 단계에서 이루어지며, CPU가 실행 중 이 줄의 조건을 검사하지 않습니다.

### 6662행

```c

	pr_info(" memory used for stack traces: %zu kB\n",

```

잠금 사용 경로를 진단하기 위해 저장하는 스택 추적 주소 배열과 조회 테이블의 크기를 별도로 출력합니다. 일반 커널 스택 전체 사용량을 뜻하지 않습니다.

### 6663행

```c

	       (sizeof(stack_trace) + sizeof(stack_trace_hash)) / 1024

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: (sizeof(stack_trace) + sizeof(stack_trace_hash)) / 1024

### 6664행

```c

	       );

```

앞줄들에서 계산한 저장 공간 크기를 로그 함수의 인자로 넘겨 해당 보고를 마칩니다. 이 지점에서 추가 메모리를 할당하지 않습니다.

### 6665행

```c

#endif

```

IRQ 상태 추적과 잠금 검증을 함께 쓸 때의 스택 추적 메모리 보고를 마칩니다. 뒤에서는 태스크 하나당 잠금 기록 크기를 출력합니다.

### 6667행

```c

	pr_info(" per task-struct memory footprint: %zu bytes\n",

```

태스크 하나의 task_struct 안에 들어가는 held_locks 배열 크기를 출력합니다. 각 태스크가 지금 보유한 잠금을 추적하는 데 드는 고정 비용입니다.

### 6668행

```c

	       sizeof(((struct task_struct *)NULL)->held_locks));

```

자료구조의 크기를 바이트 단위로 구해 lockdep의 정적 저장 공간 사용량을 보고하는 식에 더합니다. sizeof 안의 NULL 포인터 표현은 실제로 그 주소를 읽는 동작이 아닙니다. 대상: sizeof(((struct task_struct *)NULL)->held_locks));

