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

공정 스케줄링: 실행한 시간으로 다음 가상 마감 시각 갱신하기

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

Linux v6.6의 fair 스케줄러에도 EEVDF가 들어 있습니다. 가장 작은 vruntime만 고른다는 과거 CFS 설명으로 끝내면 실제 선택 기준을 놓칩니다. 이 버전의 update_deadline은 요청 소진 뒤 다음 가상 마감 시각을 만들고, 경쟁자가 있으면 함수 안에서 재스케줄을 요청합니다.

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

먼저 알아둘 개념

vruntime

실제 CPU 실행 시간을 가중치로 환산한 누적 값입니다. 같은 실제 시간을 실행해도 가중치에 따라 증가량이 달라집니다.

가상 마감 시각

실제 시계의 업무 마감 시각이 아니라 스케줄링 비교를 위한 가상 시간입니다. 다음 요청 길이를 가중치로 환산하여 현재 vruntime에 더합니다.

eligibility와 선택

EEVDF는 CPU 서비스를 더 받아도 되는 후보인지와 가상 마감 시각을 함께 고려합니다. 이 함수 하나가 모든 후보 중 다음 task를 고르는 것은 아닙니다.

처음 읽을 때

가중치가 같은 task에서 slice를 짧게 바꾸면 다음 가상 deadline까지의 간격이 줄어든다고 생각해 보세요. 공정한 장기 지분과 한 번의 요청 길이를 구분하는 연습입니다.

더 깊이 살펴볼 때

calc_delta_fair의 가중치 변환과 pick_eevdf의 적격성 판단을 연결해 읽으세요. deadline 숫자만 작다고 아직 CPU 서비스를 받을 자격이 없는 entity가 무조건 선택되지는 않습니다.

그림으로 보는 변화

공정 스케줄링: 실행한 시간으로 다음 가상 마감 시각 갱신하기의 단계별 개념 그림
각 단계에 화살표 의미와 생략 범위를 표시했습니다. 주소·숫자 예제는 실제 장치 값을 뜻하지 않습니다.
1단계 설명

1단계 고정

GIF 원본 열기

1. 현재 요청 확인

signed(vruntime - deadline) < 0이면 요청이 남음

화살표는 조건 판단 흐름입니다. 비교 대상은 실제 벽시계 시간이 아닙니다.

2. 다음 요청 길이 설정

slice = sysctl_sched_base_slice

이 버전은 이 지점에서 기본 slice를 대입합니다. 최신 버전의 custom_slice 조건을 그대로 적용하지 않습니다.

3. deadline 갱신과 재선택 요청

새 deadline 계산; nr_running > 1이면 resched_curr

화살표는 새 상태로의 갱신과 후속 요청입니다. 이 함수의 반환형은 void이며 직접 context switch를 실행하지 않습니다.

update_deadline를 한 줄씩 읽기

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

static void update_deadline(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
	if ((s64)(se->vruntime - se->deadline) < 0)
		return;

	/*
	 * For EEVDF the virtual time slope is determined by w_i (iow.
	 * nice) while the request time r_i is determined by
	 * sysctl_sched_base_slice.
	 */
	se->slice = sysctl_sched_base_slice;

	/*
	 * EEVDF: vd_i = ve_i + r_i / w_i
	 */
	se->deadline = se->vruntime + calc_delta_fair(se->slice, se);

	/*
	 * The task has consumed its request, reschedule.
	 */
	if (cfs_rq->nr_running > 1) {
		resched_curr(rq_of(cfs_rq));
		clear_buddies(cfs_rq, se);
	}
}
static void update_deadline(struct cfs_rq *cfs_rq, struct sched_entity *se)

Linux v6.6의 EEVDF 요청 마감 시각 갱신 함수입니다. 반환형은 void이며 조건에 따라 내부에서 재스케줄 요청도 처리합니다.

	if ((s64)(se->vruntime - se->deadline) < 0)

vruntime과 deadline의 차이를 signed 64비트로 해석하여 현재 가상 실행 시간이 아직 마감 전인지 판단합니다. 실제 벽시계 비교가 아닙니다.

		return;

요청이 남았다면 아무 값도 반환하지 않고 함수를 끝냅니다. 이 버전에는 false 반환이 없습니다.

	se->slice = sysctl_sched_base_slice;

다음 요청 길이를 기본 slice 값으로 설정합니다. 이 버전의 이 함수에는 custom_slice 조건 분기가 없습니다.

	se->deadline = se->vruntime + calc_delta_fair(se->slice, se);

slice를 entity 가중치에 따른 가상 시간으로 바꾼 뒤 현재 vruntime에 더하여 새 deadline을 만듭니다.

	if (cfs_rq->nr_running > 1) {

이 fair 실행 큐에 실행 가능한 entity가 둘 이상인지 확인합니다. 혼자라면 불필요한 경쟁자 재선택 요청을 생략합니다.

		resched_curr(rq_of(cfs_rq));

해당 CPU runqueue에 재스케줄이 필요함을 요청합니다. 이 호출 자체가 레지스터를 교체하는 context switch는 아닙니다.

		clear_buddies(cfs_rq, se);

소진한 entity에 대한 buddy 선택 힌트를 정리하여 다음 선택 판단에 오래된 힌트가 남지 않게 합니다.

함께 생각해 볼 질문

deadline이 지나면 실시간 요구를 놓친 것인가요?

여기서 deadline은 fair 스케줄링의 가상 비교 값입니다. SCHED_DEADLINE의 실제 실행 보장 요구와 다른 개념입니다.

vruntime이 아직 deadline보다 작으면 무엇을 하나요?

요청을 아직 다 사용하지 않았으므로 즉시 반환합니다. v6.6 구현은 void 함수라 false 같은 결과값을 반환하지 않습니다.

이 함수에서 context switch가 일어나나요?

요청을 소진하고 경쟁자가 있으면 resched_curr로 재스케줄을 요청합니다. 실제 task 전환은 별도의 스케줄링 실행 지점에서 이루어집니다.

출처와 읽은 범위

Linux stable v6.6 · kernel/sched/fair.c

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

맨 위로 ↑