지위는 약속이 아니다 — 리눅스 스케줄러가 '스스로를 묶는 태스크'를 신뢰하는 이유
리눅스가 “다음에 어떤 태스크를 실행할지” 정하는 방식 깊은 곳에 작은 반전이 숨어 있다. 스케줄러는 여러 정책을 고정된 권위의 서열로 쌓아 두는데, 그 상위에 기질이 정반대인 두 정책이 나란히 앉아 있다. 하나는 순수한 지위다 — 태스크가 그저 “나는 중요하다”라고 선언하고 우선순위 번호를 받아 아래의 누구보다 먼저 실행된다. 다른 하나는 계약이다 — 태스크가 CPU를 얼마나, 얼마나 자주 쓸지 신고하고, 그 신고를 검사에 부친 뒤에야 승인된다. 반전은 커널이 어느 쪽을 위에 두느냐다. 계약이 지위를 앞선다. 스스로를 묶는 태스크가, 그저 “중요하다”라고 주장하는 태스크보다 더 신뢰받는다.
지난 몇 달 리눅스 스케줄러를 읽고 있다. 공정성을 둘러싼 논쟁이 — 누구의 감정도 얽히지 않는 C 언어 안에서 — 결판나는 광경을 지켜보는 즐거움 때문이다. 거의 모든 프로세스를 돌리는 공정 분배 클래스는 시간을 고르게 나누기 위해 정교한 “허구의 장부”를 적는다. 그 장부 이야기는 전에 썼다. 그런데 바로 옆에는 공정 게임에 애초에 참가하지 않는 두 클래스가 살고 있고, 그 관계가 권위란 대체 어디서 오는가에 대한 조용한 교훈이 된다.
프로세서를 원하는 세 가지 방식
배우들을 늘어놓자. 일반 클래스는 CPU 시간을 “나눠 갖는 것”으로 다루고, 자신이 얼마나 공정하게 하고 있는지 재기 위해 허구의 시계를 발명한다. 실시간 클래스(SCHED_FIFO / SCHED_RR)는 그걸 전부 내던진다. 공정이라는 개념이 없다. 우선순위 1~99가 있고, 실행 가능한 것 중 가장 높은 우선순위가 이긴다, 그게 전부다. FIFO 태스크는 스스로 양보하지 않는 한 계속 실행된다. 장부도 회계도 허구의 무엇도 없다. 있는 건 지위와 도착 순서뿐 — 공정한 클래스에서 몇 밀리미터 옆에, 더 오래되고 투박한 질서가 함께 산다.
그리고 SCHED_DEADLINE이 있는데, 이는 통째로 제3의 세계, 계약의 세계에 속한다. 데드라인 태스크는 세 숫자 — runtime, period, deadline — 로 기술되며, 합쳐서 “period마다 runtime 마이크로초를 deadline 안에 실행하라”라고 말한다. 속은 EDF(가장 이른 마감부터 실행)를, 각 태스크의 초과가 남의 보증으로 새어 나가지 않게 하는 CBS(Constant Bandwidth Server)로 감싼 것이다12. 셋 중 유일하게 “양”에 대해 약속하는 클래스이며, 커널의 클래스 서열에서 실시간 우선순위 위에 놓인다.
보증이란 곧 거절이다
계약을 신뢰할 만한 것으로 만드는 메커니즘이야말로 내가 계속 곱씹는 부분이다. 데드라인 태스크가 되려고 신청하면 커널은 승인 제어(admission control)를 돌린다. 이미 모든 데드라인 태스크에 약속된 대역을 합산하고, 당신의 요청이 여전히 “보증에 허용되는 상한” 안에 드는지 확인한다. 들지 않으면 그 요청은 문 앞에서 거절된다12.
이 의미를 음미해 보라. 공정 스케줄러는 아무도 거절하지 않는다. 천 개의 태스크를 건네도 전부 받고, 과부하면 모두가 함께 똑같이 느려질 뿐 상대적 공정은 유지된다. 그렇게 할 수 있는 건 절대량을 아무것도 약속하지 않기 때문이다 — 약속하는 건 비율뿐이다. 데드라인 스케줄러는 절대량을 약속한다. 그리고 절대적 약속을 지키는 유일한 방법은 지킬 수 없는 약속을 거절하는 것이다. 보증을 정직하게 구현하면 반드시 거부권이 세트로 딸려 온다. “아니오”라고 말하지 않는 시스템은 기껏해야 최선노력(best-effort)의 공정만 제공할 수 있다. 보증하는 능력과 거절하는 능력은, 같은 하나의 능력을 앞뒤에서 본 것에 지나지 않는다.
이건 깔끔하게, 그리고 조금 불편하게 일반화된다. 마감에 진짜로 커밋할 수 있는 사람·팀은 일을 거절할 힘을 가진 사람·팀이다. “다 맡겠습니다”는 강함이 아니다. 그 말을 하는 순간, 당신의 모든 약속은 보증에서 “희망”으로 조용히 강등된다. 무엇이든 받는 큐가 되는 순간, 그 마감은 보증이 아니라 순서의 표명이 된다.
커널은 “강자를 억누르기”를 그만두었다
이걸 적어 두고 싶게 만든 변화가 여기다. 실시간 태스크는 설계상 아래를 태연히 굶긴다. 오랫동안 리눅스는 이걸 RT 스로틀링으로 처리했다 — 실시간 태스크가 일정 몫을 다 쓰면 강제로 멈추는 전역 상한으로, 일반 태스크가 완전히 배제되지 않도록 “마지막 5% 남짓”의 CPU를 확보하는 방식이다3. 작동은 했다. 하지만 그것은 벌로써 작동했다. 강자에게 손을 넣어 유휴 상태로 만든다 — 때로는 회수한 시간을 아무도 필요로 하지 않을 때조차.
리눅스 6.12에서 이 메커니즘은 교체되었다45. 실시간 클래스를 위에서 억누르는 대신, 커널은 이제 공정 클래스 쪽을 전용 데드라인 서버로 감싼다. 공정 스케줄러 자신이 하나의 대역 예약 — runtime과 period를 가진 데드라인 엔티티 — 으로 등록되고, 일반 태스크가 굶주릴 위기에 처하면 그 서버가 최상위에서 기동해 일반 태스크를 실행한다4. 이 패치 묶음 중 하나는 감탄스러울 만큼 직설적으로 “Remove default bandwidth control(기본 대역 제어 제거)”라고 제목 붙어 있다4.
반전의 형태를 보라. 옛 설계는 강자를 제한함으로써 약자를 지켰다. 새 설계는 약자에게 하한을 보증함으로써 약자를 지킨다 — 계약의 언어로 쓰이고, 남은 것으로 베풀어지는 게 아니라 권리로서 주장된다. 목표는 같고 아키텍처는 정반대다. 강자에 대한 상한은 강자의 행동을 왜곡하고 낭비(아무도 요청하지 않은 유휴 CPU)를 낳는다. 약자에 대한 하한은 지키려는 것에만 콕 집어 닿는다. 커널 개발자들은 정치 이론에서 연역해 여기 도달한 게 아니다. 실측하고, 스로틀링이 서투르다는 걸 알고, 움직였다. 그것이 “위를 깎기”와 “아래를 보증하기”라는 구별 — 최저임금 대 기본소득 보장, 발언 시간 제한 대 발언권 보장 — 에 딱 겹치기에 설계의 교훈으로 훔쳐 올 가치가 있다.
왜 계약이 왕관을 앞서는가
그럼 왜 DEADLINE이 실시간 우선순위 위에 앉을까. 우선순위 99의 실시간 태스크는 방에서 가장 중요하고, 그렇게 선언한다. 하지만 얼마나 먹을지에 대해서는 아무 약속도 하지 않는다 — 영원히 실행될 수 있다. 데드라인 태스크는 자신의 식욕을 신고했고 그 신고를 승인 제어에 검증받았다. 바로 그렇기에 최상위에서 신뢰받을 수 있다 — 구조상 맹세한 것 이상은 먹을 수 없으니까. 무제한인 것은 감시받고, 역사적으로는 스로틀링당해야 했다. 스스로를 제한한 것은 감시가 전혀 필요 없다. 권위는 가장 강하게 주장하는 자가 아니라, 검증될 수 있는 자에게로 흐른다.
여기서 아렌트를 듣는 건 억지가 아니라고 생각한다. 『인간의 조건』에서 그녀는 약속하는 힘을 예측 불가능한 미래에 대한 인간의 응답으로 다뤘다 — 다가오는 것을 명령할 수는 없지만 스스로를 묶을 수는 있고, 서로 묶는 일이 행위의 혼돈 속에 신뢰할 만한 섬을 세운다6. 결정적으로, 그녀는 이것을 옛 의미의 주권에 대치시켰다 — 누구에게도 아무것도 빚지지 않을 만큼 강한 단일 의지라는 환상. 그런 주권은 타인과 더불어 사는 것과 양립하지 않는다고 그녀는 논한다. 지속하는 유일한 권위는 스스로를 약속으로 묶는 종류다6. 커널의 서열 — 스스로를 묶는 계약을, 묶이지 않는 왕관 위에 두는 것 — 은 그 논증을 컴파일해 실행한 것처럼 읽힌다. 우선순위 99는 “날것의 지배”로서의 주권. SCHED_DEADLINE은 “지켜진 약속”으로서의 주권. 스케줄러와 철학자는 어느 쪽 위에 시스템을 세울 수 있는지에 대해 의견이 일치한다.
아직 확신이 서지 않는 것
이야기를 정직하게 유지하는 두 갈래의 금.
계약은 당신이 신고하는 숫자만큼만 좋다. 승인 제어가 검사하는 건 당신의 약속 대역이 다른 모두와 정합적인가이지, 당신의 runtime 추정치가 참인가는 검사할 수 없다. 과소 신고하면 CBS가 도중에 끊어 버리고, 과대 신고하면 남들이 자기 약속에 쓸 수 있었을 용량을 울타리 쳐 버린다1. 제도가 강제할 수 있는 건 “거짓말쟁이의 피해가 본인에게 갇히는 것”까지이고, 정직한 자기 평가를 강요할 수는 없다. 그리고 애초에 자신의 최악 경우를 잴 여유가 없는 이를 조용히 배제한다. 검증 가능한 자기 제한은 아름다운 신뢰의 토대다 — 다만 그것이 “자신을 잴 능력”을 전제한다는 걸 깨닫기 전까지는.
그리고 이 우아한 이론은 결국 단일 프로세서 이론이다. 데드라인 태스크를 어느 CPU에서 실행할지 묻는 순간 깔끔한 보증은 느슨해진다 — 멀티프로세서에서는 승인 검사가 필요조건이지만 더는 충분조건이 아니게 되고, 배치 제약이 한 코어에서는 아름답게 성립하는 한계를 깨뜨릴 수 있다1. 시간에서는 밀폐된 약속이 공간에서 새어 나온다. 다음에 읽고 싶은 게 바로 그것이다 — “언제”의 이론은 “어디”의 이론이 되고서야 완성된다고 시사하는 듯하니.
-
The Linux Kernel. “Deadline Task Scheduling.” 접속일 2026-07-18. (EDF + CBS, runtime/period/deadline 매개변수, 승인 제어, 그리고 SMP에서는 승인 검사가 필요조건이지만 충분조건이 아니라는 서술) ↩ ↩2 ↩3 ↩4
-
Wikipedia. “SCHED_DEADLINE.” 접속일 2026-07-18. (Linux 3.14부터 사용 가능, EDF + Constant Bandwidth Server, 승인 제어는 비실시간용 시간을 남기기 위해 보통 95% 안팎으로 상한) ↩ ↩2
-
heise online. “Linux 6.12: Scheduler now expandable and EEVDF conversion complete.” 접속일 2026-07-18. (RT 스로틀링은 역사적으로 일반 태스크용으로 CPU의 약 5%를 확보했다. 새 서버는 대신 일반 프로세스가 제 몫을 받도록 보증한다) ↩
-
LWN.net. “SCHED_DEADLINE server infrastructure.” 접속일 2026-07-18. (공정/데드라인 서버, defer-server 방식 기동, 기본 fair_server_runtime 950ms / period 1s, “Remove default bandwidth control” 패치) ↩ ↩2 ↩3
-
Phoronix. “Linux 6.12 Scheduler Code Adds SCHED_DEADLINE Servers & Complete EEVDF.” 접속일 2026-07-18. ↩
-
한나 아렌트, 『인간의 조건』(1958), 제35절 “예측 불가능성과 약속의 힘”. 약속은 예측 불가능한 미래를 묶는 능력이며, 주권적 자기 지배가 줄 수 없는 신뢰 가능성을 근거 짓는다는 주제. ↩ ↩2