Upgrade to Pro — share decks privately, control downloads, hide ads and more …

カーネルから見る OCIランタイム

0n1shi
March 22, 2019
1k

カーネルから見る OCIランタイム

0n1shi

March 22, 2019
Tweet

Transcript

  1. 自己紹介 大西 和貴 (@_k_onishi_) SAKURA Internet Inc. アプリケーショングループ レンタルサーバーチーム Linux

    / Kernel / CPU / Container / Virtualization / Pwn / C / Assembly / Python Linux Kernel 勉強会
  2. 目次 • コンテナとは • Cgroupsとは • CFS Bandwidth Controlの概要と実装 •

    Completely Fair Schedulerの概要と実装 • カーネルの独自パッチ • まとめ
  3. Cgroupsとは • cpu: CPUへのアクセス • cpuacct: CPUについての自動レポートを生成 • cpuset: マルチコアCPUのコア単位およびメモリノードを割り当て

    • memory: メモリに対する制限設定と自動レポートの生成 • blkio: ブロックデバイスの入出力アクセス • devices: デバイスへのアクセス • net_cls: ネットワークパケットへのタグ付け • net_prio: ネットワークトラフィックの優先度を動的に設定 • freezer: タスクを一時停止または再開 参考: https://qiita.com/legitwhiz/items/72ead813f5be784534e5
  4. Cgroupsとは • cpu: CPUへのアクセス • cpuacct: CPUについての自動レポートを生成 • cpuset: マルチコアCPUのコア単位およびメモリノードを割り当て

    • memory: メモリに対する制限設定と自動レポートの生成 • blkio: ブロックデバイスの入出力アクセス • devices: デバイスへのアクセス • net_cls: ネットワークパケットへのタグ付け • net_prio: ネットワークトラフィックの優先度を動的に設定 • freezer: タスクを一時停止または再開 参考: https://qiita.com/legitwhiz/items/72ead813f5be784534e5
  5. Cgroupsとは • cpu: CPUへのアクセス 参考: https://qiita.com/legitwhiz/items/72ead813f5be784534e5 # cgroupの作成 $ cgcreate

    -g blkio,memory,cpu,pids:test # 指定のプロセスをcgroupに参加させる。 $ echo $$ 2006 $ cgclassify -g blkio,memory,cpu,pids:test 2006 # 1秒間に0.5秒CPUリソースに対するアクセスを許可する $ cgset -r cpu.cfs_period_us=1000000 test $ cgset -r cpu.cfs_quota_us=500000 test
  6. CFS Bandwidth Controlの実装 参考: kernel/sched/core.c #ifdef CONFIG_CFS_BANDWIDTH { .name =

    "cfs_quota_us" , .read_s64 = cpu_cfs_quota_read_s64, .write_s64 = cpu_cfs_quota_write_s64, }, { .name = "cfs_period_us" , .read_u64 = cpu_cfs_period_read_u64, .write_u64 = cpu_cfs_period_write_u64, }, -rw-r--r-- 1 root root 0 Mar 22 09:14 /sys/fs/cgroup/cpu,cpuacct/test/cpu.cfs_period_us -rw-r--r-- 1 root root 0 Mar 22 09:14 /sys/fs/cgroup/cpu,cpuacct/test/cpu.cfs_quota_us
  7. CFS Bandwidth Controlの実装 • tg_set_cfs_bandwidth() ◦ __cfs_schedulable() // 対象タスクグループ配下に制限値を反映 ◦

    period及びquotaを更新 ◦ __refill_cfs_bandwidth_runtime() // quota マイクロ秒のランタイムプールを補 充 ◦ start_cfs_bandwidth() // period 用のタイマーを起動 ▪ sched_cfs_period_timer() • __refill_cfs_bandwidth_runtime() // quota マイクロ秒のランタイム プールを補充 参考: kernel/sched/core.c
  8. CFS Bandwidth Controlの実装 参考: kernel/sched/core.c void __refill_cfs_bandwidth_runtime (struct cfs_bandwidth *cfs_b)

    { u64 now; if (cfs_b->quota == RUNTIME_INF) return; now = sched_clock_cpu (smp_processor_id ()); cfs_b->runtime = cfs_b->quota; cfs_b->runtime_expires = now + ktime_to_ns(cfs_b->period); cfs_b->expires_seq ++; }
  9. Completely Fair Schedulerの実装 • タイマtick割り込み(schedule_tick() or hrtick()) ◦ task_tick_fair() ▪

    update_curr() • 実行した時間(delta_exec)の算出 • vruntimeの加算 • cgroup_account_cputime() // 統計情報(cpuacct)の更新 • account_cfs_rq_runtime() // CFS BW 関連の処理 ◦ __account_cfs_rq_runtime() if(bandwidth が有効) ▪ 残存するランタイム (runtime_remaining) から実行時間を減算 ▪ expire_cfs_rq_runtime() // if(! 残存するランタイムが有 効){runtime_remaining = 0;} ▪ assign_cfs_rq_runtime() if(残存するランタイムが 0) • start_cfs_bandwidth() // period 用のタイマーを起動 • ランタイムプールから残存するランタイムに補充 • 補充した分をランタイムプールから減算 ▪ 残存するランタイムが 0の場合、再度スケジューリング ▪ ... 参考: kernel/sched/core.c
  10. 独自パッチ URL: https://github.com/k-onishi/linux-4.20.16/compare/c017e5c...b14af01 # 1秒間に0.5秒CPUリソースに対するアクセスを許可する $ cgset -r cpu.cfs_period_us=1000000 test

    $ cgset -r cpu.cfs_quota_us=500000 test # 1秒間に0.5秒CPUリソースに対するアクセスを許可する $ cgset -r cpu.cfs_bandwidth_percent=50 test
  11. 独自パッチ URL: https://github.com/k-onishi/linux-4.20.16/compare/c017e5c...b14af01 #ifdef CONFIG_CFS_BANDWIDTH { .name = "cfs_quota_us" ,

    .read_s64 = cpu_cfs_quota_read_s64, .write_s64 = cpu_cfs_quota_write_s64, }, { .name = "cfs_period_us" , .read_u64 = cpu_cfs_period_read_u64, .write_u64 = cpu_cfs_period_write_u64, }, { /* New !! */ .name = "cfs_bandwidth_percent" , .read_s64 = cpu_cfs_bandwidth_read_u64, .write_u64 = cpu_cfs_bandwidth_write_u64, }