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

빠르게 얻지 못한 잠금은 대기 경로로 넘깁니다

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

mutex는 공유 객체를 한 번에 한 실행 흐름만 수정하도록 보호합니다. 다른 태스크가 이미 가지고 있으면 기다리며 잠들 수 있으므로 호출 문맥이 중요합니다. 이 짧은 진입 함수에서도 문맥 검사, 빠른 획득, 느린 대기 경로를 구분할 수 있습니다.

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

먼저 알아둘 개념

소유권

한 태스크가 보호 구역에 들어갈 권리를 갖는 상태입니다.

빠른 경로와 느린 경로

경쟁이 없으면 작은 원자 연산으로 끝내고, 경쟁 시에는 대기자 관리와 스케줄링이 필요한 경로로 갑니다.

처음 읽을 때

코드를 읽을 때 might_sleep로 잠들 수 있는 곳인지 확인합니다. 그다음 어느 상태가 바뀌는지 각 줄에서 확인하세요.

더 깊이 살펴볼 때

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

그림으로 보는 변화

빠르게 얻지 못한 잠금은 대기 경로로 넘깁니다의 단계별 개념 그림
각 단계에 화살표 의미와 생략 범위를 표시했습니다. 주소·숫자 예제는 실제 장치 값을 뜻하지 않습니다.
1단계 설명

1단계 고정

GIF 원본 열기

1. 문맥 검사

might_sleep로 잠들 수 있는 곳인지 확인합니다.

검사는 잠금을 획득한 것과 다릅니다.

2. 빠른 획득

다른 소유자가 없으면 빠른 경로에서 잠금을 얻습니다.

실패한 경우에만 다음 대기 경로로 갑니다.

3. 대기 경로

경쟁을 처리하고 소유권을 얻은 뒤 반환합니다.

반환 뒤에는 호출자가 잠금을 해제할 책임이 있습니다.

mutex_lock를 한 줄씩 읽기

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

void __sched mutex_lock(struct mutex *lock)
{
	might_sleep();

	if (!__mutex_trylock_fast(lock))
		__mutex_lock_slowpath(lock);
}
void __sched mutex_lock(struct mutex *lock)

지정한 mutex의 소유권을 얻을 때까지 진행하며 반환값은 없습니다. 빠른 시도가 실패하면 대기 가능한 느린 경로로 들어가므로 잠들 수 있는 실행 문맥에서 사용해야 합니다.

	might_sleep();

이 위치가 잠들 수 있는 문맥인지 점검합니다. 이 줄 자체가 mutex 대기 목록에 태스크를 넣는 것은 아닙니다.

	if (!__mutex_trylock_fast(lock))

경쟁이 없는 경우 빠르게 소유권을 얻는 경로를 시도합니다. 실패해야 아래 느린 경로로 들어갑니다.

		__mutex_lock_slowpath(lock);

대기자 관리와 필요 시 스케줄링을 포함하는 경쟁 처리 경로에서 잠금을 얻습니다.

함께 생각해 볼 질문

might_sleep이 실제로 태스크를 재우나요?

주로 수면 가능 문맥을 검사하는 표시입니다. 대기 실행 자체와는 다릅니다.

mutex_lock이 성공 여부를 bool로 반환하나요?

이 함수의 반환형은 void이며 반환했다면 잠금을 얻은 경로입니다.

IRQ에서 mutex를 쓰면 되나요?

잠들 수 없는 문맥에서는 이 잠금의 요구사항을 충족하지 못합니다.

출처와 읽은 범위

Linux stable v6.18.37 · kernel/locking/mutex.c

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

맨 위로 ↑