Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Linuxのプロセススケジューラの歴史 v2.6.23~v4.18
Search
Satoru Takeuchi
PRO
January 29, 2022
Technology
0
450
Linuxのプロセススケジューラの歴史 v2.6.23~v4.18
以下動画のテキストです。
https://youtu.be/hrKENEC7Gsg
Satoru Takeuchi
PRO
January 29, 2022
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
Rook: Intro and Deep Dive With Ceph
sat
PRO
1
89
会社員しながら本を書いてきた知見の共有
sat
PRO
3
770
デバイスにアクセスするデバイスファイル
sat
PRO
1
32
ファイルシステムのデータを ブロックデバイスへの操作で変更
sat
PRO
1
28
デバイスドライバ
sat
PRO
0
45
マルチスレッドの実現方法 ~カーネルスレッドとユーザスレッド~
sat
PRO
2
110
共有メモリ
sat
PRO
3
67
マルチスレッドプログラム
sat
PRO
3
56
Linuxのブートプロセス initramfs編
sat
PRO
2
76
Other Decks in Technology
See All in Technology
Microsoft Build 2025 技術/製品動向 for Microsoft Startup Tech Community
torumakabe
2
240
VISITS_AIIoTビジネス共創ラボ登壇資料.pdf
iotcomjpadmin
0
150
Create a Rails8 responsive app with Gemini and RubyLLM
palladius
0
140
Witchcraft for Memory
pocke
1
160
UIテスト自動化サポート- Testbed for XCUIAutomation practice
notoroid
0
120
Amazon Bedrockで実現する 新たな学習体験
kzkmaeda
1
430
AIのAIによるAIのための出力評価と改善
chocoyama
2
530
生成AIでwebアプリケーションを作ってみた
tajimon
2
140
TechLION vol.41~MySQLユーザ会のほうから来ました / techlion41_mysql
sakaik
0
160
Oracle Cloud Infrastructure:2025年6月度サービス・アップデート
oracle4engineer
PRO
2
180
OAuth/OpenID Connectで実現するMCPのセキュアなアクセス管理
kuralab
5
960
Абьюзим random_bytes(). Фёдор Кулаков, разработчик Lamoda Tech
lamodatech
0
310
Featured
See All Featured
Scaling GitHub
holman
459
140k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
Code Review Best Practice
trishagee
68
18k
Automating Front-end Workflow
addyosmani
1370
200k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
Raft: Consensus for Rubyists
vanstee
140
7k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
Fireside Chat
paigeccino
37
3.5k
Producing Creativity
orderedlist
PRO
346
40k
KATA
mclloyd
29
14k
Transcript
Linuxのプロセススケジューラの歴史 v2.6.23~v4.18 Jan. 29th, 2022 Satoru Takeuchi Twitter: satoru_takeuchi 1
はじめに • Linuxカーネル(以下カーネル)のプロセススケジューラの歴史を振り返る • 対象バージョン: 最初のリリースv2.6.23からv4.18まで • 用語 ◦ タスク:
カーネルのスケジューリング単位。プロセスあるいはスレッド ◦ LCPU: カーネルがCPUとして認識するもの(物理CPU or コア or スレッド) ◦ Current: LCPU上で現在動作中のタスク 2
Completely Fair Scheduler (CFS) • レイテンシターゲットによるスケジューリング • 細かいタイムスライス粒度 • プラガブルなスケジューリングアルゴリズム
3
レイテンシターゲットによるスケジューリング • ランキューはvruntimeと呼ばれる仮想的なキー(後述)とした赤黒木 ◦ スケジューリング処理の計算量は O(log(n)) ◦ active/inactiveキュー、および優先度別ランキューは廃止 • 各タスクはレイテンシターゲットと呼ばれる期間に一度CPU時間を得られる
◦ レイテンシターゲットは数 ms~数十ms。システムのLCPU数やバージョンによって変わる ◦ タイムスライス = レイテンシターゲット ()/runnableタスク数 4
LCPU上で動くタスク 5 タスク数2 タスク数3 タスク数4 時間 t0 t1 t0 t1
t0 t1 t2 t0 t1 t2 t0 t1 t2 t3 t0 t1 t2 t3 レイテンシターゲット レイテンシターゲット
スケジューラの挙動: 初期状態 • 仮定 ◦ レイテンシターゲット : 10 [ms] •
タイムスライス=10/(runnableタスク数=3) [ms] 6 0 0 0 t0 t1 t2 vruntime(簡単のため簡略化している ) LCPU
ランキュー先頭のタスクをcurrentに 7 0 0 t1 t2 LCPU 0 t0
タイムスライス切れまで動かす • 10/3 [ms]動くとvruntimeが1.0増えるよう計算 8 0 0 t1 t2 LCPU
1.0 t0
currentをランキューに再挿入 9 0 0 t1 t2 LCPU 1.0 t0
vruntime=1.0になるまで繰り返し。これが続く 10 1.0 1.0 t0 t1 LCPU 1.0 t2
sleep中のタスクが起床したときは? 11 1.0 1.0 t1 t2 LCPU t3 1.5 t0
おはよう
vruntimeをrunnableタスク内最小値にしてランキューに挿入 • vruntime=15のタスクの残りタイムスライス ◦ (2.0-1.5)*(10/3)=1.67 [ms] → (2.0-1.5)*(10/4) = 1.25
[ms] • vruntime=10のタスクの残りタイムスライス ◦ (2.0-1.0)*(10/3)=3.3 [ms] → (2.0-1.0)*(10/4) = 2.5 [ms] 12 1.0 1.0 t1 t2 LCPU 1.0 t3 1.5 t0
nice値の扱い • Niceの変化によってタイムスライスの比率が変わる ◦ nice値が低い(高優先度): 比率が上がる ◦ nice値が低い(低優先度): 比率が下がる 13
T0 0 T1 -1 T0 0 T1 0 T0 0 T1 1 時間 T0 0 T1 0 nice値 T0のnice値 > t1のnice値 T0のnice値 == t1のnice値 T0のnice値 < t1のnice値 T0 0 T1 -1 T0 0 T1 1
プラガブルなスケジューラ • アルゴリズム別にスケジューリングクラスという概念を導入 ◦ 効果: 後からスケジューラを追加するのが楽 & コードの見通しが良い ◦ クラスごとにコールバック関数のセットを用意
▪ 次のcurrentを選ぶ関数、タスクの sleep時に呼ぶ関数、起床時に呼ぶ関数、など • 高優先度のクラスに属する実行可能タスクは低優先度のクラスに属するタスクより 優先動作 ◦ スケジューリングクラス (優先度順) ▪ rt_shed_class: リアルタイムタスク。ポリシーは SCHED_{FIFO,RR} ▪ fair_sched_class: 通常のプロセス。ポリシーは SCHED_OTHER 14
細かいタイムスライス粒度 • O(1)まで ◦ レガシーなインターバルタイマーを使用 : 定期的に割り込みが発生し続ける ◦ ms単位が限度 •
CFS ◦ ワンショット高精度タイマー : タイムスライスが切れる時に割り込みを発生させる ◦ ns単位の制御が可能 15
V2.6.24: fair group scheduling • Cpu cgroup 1. グループ間でCPUを均等配分 2.
グループ内でさらに均等配分 • Cpu cgroupのcpu.sharesパラメタによって重み付けも可能 • ネストも可能 16
LCPU上で動くタスク 17 時間 t0 t1 t2 t0 t1 t2 cgroupなし
Cgroupあり グループA: t0, t1 グループB: t2 t0 t1 t2 t0 t1 t2 1 1/3 1/3 1/3 1 1/4 1/4 1/2 1/2
LCPU上で動くタスク: share変更あり 18 時間 t0 t1 t0 t1 Cgroupあり グループA:
t0 share: 1 グループB: t1 share: 1 Cgroupあり グループA: t0 Share: 1 グループB: t1 Share: 2 1 1/2 1/2 t0 t1 1 1/3 2/3 t0 t1
Use case: ユーザ間でCPU資源を均等配分 • 例: ユーザAがt0, ユーザBがt1-t3を動かしているとする 19 Fair group
scheduling不使用 ユーザごとにグループ作成 時間 t0 t1 t2 t3 時間 t0 t1 t2 t3 タスク同士が公平 ユーザ同士は不公平 ユーザ同士が公平
V2.6.24: cpuset cgroup • Cpusetをcgroupに統合したもの • cpusetを/dev/cpusetだけでなく/sys/fs/cgroupから操作可能に 20
リアルタイムタスクが止まらない問題 • リアルタイムタスクが暴走すると通常のタスクが一切動けない • コアが1つしかないとシステムがハング • 例: ランキュー上にいるタスク ◦ T0:
リアルタイムタスク(SCHED_FIFO)。CPUを自発的に明け渡さず動き続ける ◦ T1: 通常のタスク(SCHED_OTHER)。t0暴走中に起床 21 t0 時間 t1は一切動けない t1起床
V2.6.25: Realtime group scheduling • リアルタイムタスクは所定の期間内に一定の時間しか動作できない ◦ 所定の期間: sysctlのkernel.sched_rt_period_us(デフォルトは1000000[us]) ◦
一定の時間: sysctlのkernel.sched_rt_runtime_us(デフォルトは950000[us]) • 空いた時間に通常のタスクが動ける • Cpu cgroupのcpu.rt_{period,runtime}によって入れ子構造にできる 22 t0 時間 t1は1秒間に50msだけは動ける t1 t0 t1 t1起床
重要なカーネルスレッドが動けない問題 • 優先度最高のリアルタイムタスクがCPUを使い続けるとカーネルの重要なタスクが 動けなくなる ◦ 例: CPU hotplug時のシステムの機能をほぼ止める stop_machineという処理 •
原因: カーネルタスクの最高優先度 == ユーザタスクの最高優先度 23
V2.6.37: Stop scheduling class • 全てのユーザプロセスに優先して動くカーネル専用スケジューリングクラス • スケジューリングクラス(優先度順) 1. (new)
Stop_sched_class 2. Rt_sched_class 3. fair_sched_class 24
スケジューラの挙動: stop scheduling classなし • 例: ランキュー上のタスク • T0: ユーザのタスク。暴走していて
CPUを自発的に手放さない ◦ 優先度最大(99)のリアルタイムタスク • T1: カーネルの重要なタスク。 t0暴走中に起床 ◦ 優先度最大(99)のリアルタイムタスク 25 t0 時間 t1は一切動けない t1起床
スケジューラの挙動: stop scheduling classあり • 例: ランキュー上のタスク • T0: ユーザのタスク。暴走していて
CPUを自発的に手放さない ◦ 優先度最大(99)のリアルタイムタスク • T1: カーネルの重要なタスク。 t0暴走中に起床 ◦ Stop scheduling classのタスク 26 t0 時間 t1起床 t1 t0 T1 sleep or exit
Con Kolivas氏、再び • Brain Fuck Scheduler(BFS)というスケジューラを引っ提げてLKMLに帰還 • 「mainlineに入れるつもりは無い」と最初から宣言 27 待たせたな
しばらくしたらフェードアウト 28 じゃあの
V2.6.38: autogroup • システム高負荷時におけるデスクトップ環境の応答性向上機能 ◦ 通称ミラクルパッチ • アイデア ◦ セッションごとにタスクを自動的にグループ分け
◦ グループごとに平等に CPU資源を与える • Linus氏が「小さい効果で効果が大きい」と大絶賛。パッチ投稿後速攻マージ • しかしこれも一部ケースを救うだけ ◦ 例: デスクトップアプリを動かす横でカーネルビルドをぶん回す非常に一般的なワークロード 29
Fair group schedulingの課題: 上限設定ができない • 例: 2ユーザA, B同居のマルチテナントシステム ◦ やりたいこと:
個々のユーザにCPU資源を”最大”1/2与えたい ▪ ユーザ間の不平等、過剰なサービスの提供を避けたい ◦ Fair group schedulingにできること: ユーザごとにグループ作成 30 時間 Aだけがタスクを動かしている状態 (あるべき姿) Aのタスク Aだけがタスクを動かしている状態 (現実) Aのタスク idle Aのタスク idle
V3.2: CFS bandwidth controller • あるcpu cgroupが所定期間内に動ける時間を制限 ◦ cpu.Cfs_period: 期間([us]単位)
◦ Cpu.cfs_quota: 動ける時間([us]単位) • ネストも可能 • コンテナやVMのリソース制限に使われる 31
スケジューラの挙動 • レイテンシターゲットは10ms • グループAのcpu.cfs_period=10ms, cpu.cfs_runtime=5ms 32 時間 t0 t1
t0 t0 t1 bwc不使用 t1がsleep t1が起床 t0 t1 t0 idle t0 t1 Bwc使用 T0はグループAに所属 t1がsleep t1が起床
V3.14: Deadlineスケジューラ • 所定の期間中にどれだけのCPU時間を使うかを設定できる • rootのみ使える • スケジューリングクラス 1. Stop_sched_class
2. (new) Deadline_sched_class 3. Rt_sched_class 4. Fair_sched_class • sched_setscheduler() or sched_setparam()で以下3つのパラメタを与える 1. Period: タスクはperiodで示された期間中に最大 1度動作 2. Runtime: タスクが一度起床してから sleepするまでの計算所要時間 3. deadline: タスクが起床してから計算を終了しなくてはならない期間 33
v4.18 • マイナーチェンジ中心、機能的にはあんまり変わってない(はず) 34
まとめ • CFSの導入 • Cgroupによるfair share scheduler, bandwidth controllerの導入 •
Deadline schedulerの導入 35