이 코드는 어떤 문제를 푸나요?
이 버전의 fair 스케줄러를 과거의 가장 작은 vruntime만 고르는 CFS 설명으로 끝내면 실제 선택 방식과 어긋납니다. Linux 6.18.37의 이 경로는 EEVDF의 가상 마감 시각을 사용합니다. update_deadline은 현재 실행 요청을 다 썼는지 보고 다음 요청의 마감 시각을 갱신합니다.
읽을 범위: v6.18.37 · kernel/sched/fair.c · update_deadline 1112–1135행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.
먼저 알아둘 개념
vruntime
실제 CPU 실행 시간을 가중치로 환산한 누적 값입니다. 같은 실제 시간을 실행해도 가중치에 따라 증가량이 달라집니다.
가상 마감 시각
실제 시계의 업무 마감 시각이 아니라 스케줄링 비교를 위한 가상 시간입니다. 다음 요청 길이를 가중치로 환산하여 현재 vruntime에 더합니다.
eligibility와 선택
EEVDF는 CPU 서비스를 더 받아도 되는 후보인지와 가상 마감 시각을 함께 고려합니다. 이 함수 하나가 모든 후보 중 다음 task를 고르는 것은 아닙니다.
처음 읽을 때
가중치가 같은 task에서 slice를 짧게 바꾸면 다음 가상 deadline까지의 간격이 줄어든다고 생각해 보세요. 공정한 장기 지분과 한 번의 요청 길이를 구분하는 연습입니다.
더 깊이 살펴볼 때
calc_delta_fair의 가중치 변환과 pick_eevdf의 적격성 판단을 연결해 읽으세요. deadline 숫자만 작다고 아직 CPU 서비스를 받을 자격이 없는 entity가 무조건 선택되지는 않습니다.
그림으로 보는 변화

1. 현재 요청 확인
vruntime < deadline이면 요청이 남음
화살표는 조건 판단 흐름입니다. 비교 대상은 실제 벽시계 시간이 아닙니다.
2. 다음 요청 길이 결정
custom_slice가 없으면 기본 slice 사용
기본 길이는 실제 실행 요청 시간이며 가상 시간으로 환산되기 전입니다.
3. 새 deadline 계산
deadline = vruntime + calc_delta_fair(slice)
화살표는 새 상태로의 갱신입니다. true 반환은 호출자에게 요청 소진을 알립니다.
update_deadline를 한 줄씩 읽기
줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.
static bool update_deadline(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
if (vruntime_cmp(se->vruntime, "<", se->deadline))
return false;
/*
* 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.
*/
if (!se->custom_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);
avg_vruntime(cfs_rq);
/*
* The task has consumed its request, reschedule.
*/
return true;
}static bool update_deadline(struct cfs_rq *cfs_rq, struct sched_entity *se)fair 실행 큐와 그 안의 scheduling entity를 받아 요청 소진 여부를 알려 줍니다. entity는 task 또는 스케줄링 그룹을 나타낼 수 있습니다.
if (vruntime_cmp(se->vruntime, "<", se->deadline))vruntime_cmp로 현재 vruntime이 deadline보다 작은지 봅니다. 단순 벽시계 비교가 아니라 가상 시간 비교에 맞춘 보조 표현입니다.
return false;아직 요청 시간이 남았으므로 deadline을 바꾸지 않고 false를 반환합니다.
if (!se->custom_slice)이 entity가 사용자 지정 slice를 사용하지 않는지 확인합니다.
se->slice = sysctl_sched_base_slice;지정값이 없다면 현재의 기본 slice 설정을 적용합니다. 기본 설정 변경을 다음 요청에 반영할 수 있습니다.
se->deadline = se->vruntime + calc_delta_fair(se->slice, se);요청 slice를 entity 가중치에 따른 가상 시간 증가량으로 환산한 뒤 현재 vruntime에 더합니다. 이것이 새 가상 deadline입니다.
avg_vruntime(cfs_rq);실행 큐의 평균 가상 시간 관련 상태를 갱신합니다. entity 하나의 deadline뿐 아니라 큐의 시간 기준도 함께 다룹니다.
return true;기존 요청을 다 사용했음을 true로 알려 재스케줄 판단으로 이어지게 합니다. 이 줄이 직접 task를 교체하는 것은 아닙니다.
함께 생각해 볼 질문
deadline이 지나면 실시간 요구를 놓친 것인가요?
여기서 deadline은 fair 스케줄링의 가상 비교 값입니다. SCHED_DEADLINE의 실제 실행 보장 요구와 다른 개념입니다.
vruntime이 아직 deadline보다 작으면 왜 false인가요?
현재 실행 요청을 아직 다 사용하지 않아 새 deadline을 만들 필요가 없기 때문입니다.
이 함수에서 context switch가 일어나나요?
직접 다른 task로 전환하지 않습니다. 요청 소진 여부를 반환하고 호출자가 후속 재스케줄 결정을 합니다.
출처와 읽은 범위
Linux stable v6.18.37 · kernel/sched/fair.c
해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고
