Linux 4.14 で導入された cpuset の cgroup v2 mode
(2019-02-23 少し追記しています)
4.14 kernel から cgroup の cpuset コントローラーに cpuset_v2_mode
というオプションが使えるようになりました。
しばらく見ないうちに cpuset
コントローラーをマウントするとファイルがたくさん増えていますが、このオプションを設定すると、従来からある cpuset.{cpus,mems}
ファイルの動きが変わるようです。そしていつの間にか増えている cpuset.effective_{cpus,mems}
ファイルと合わせて使って cpuset の制限を行うようです。
このオプションを設定したときの動きが、cgroup v2 の cpuset の動きになるようです(v2 の cpuset は現時点ではまだマージされていません)。
現在使える cpu や memory が effective
で表示されており、それと cpuset.{cpus,mems}
のマスクを取って、使える cpu, memory を導き出すようですね。
従来の cpuset(v1 mode)
# mount -t tmpfs cgroup /sys/fs/cgroup/ # mkdir /sys/fs/cgroup/cpuset # mount -t cgroup -o cpuset cgroup /sys/fs/cgroup/cpuset/ # cd /sys/fs/cgroup/cpuset/ # mkdir test01 # cd test01 # echo "0-1" > cpuset.cpus # echo "0" > cpuset.mems
この状態で test01
cgroup 内のファイルは、
# for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0-1 cpuset.effective_cpus: 0-1
となっています。ここでおもむろに cpu をひとつオフラインにします。cpu1 です。
# echo 0 > /sys/devices/system/cpu/cpu1/online
すると、
# for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0 cpuset.effective_cpus: 0
cpuset.cpus
と cpuset.effective_cpus
が 0
になります。
ここで再度 cpu1 をオンラインにすると、
echo 1 > /sys/devices/system/cpu/cpu1/online # cat /sys/devices/system/cpu/cpu1/online 1
# for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0 cpuset.effective_cpus: 0
特に変化はありません。
cpuset_v2_mode
付きマウント(v2 mode)
マウントオプションとして cpuset_v2_mode
を与えます。
# mount -t cgroup -o cpuset,cpuset_v2_mode cgroup /sys/fs/cgroup/cpuset/ # cat /proc/self/mounts | grep cpuset cgroup /sys/fs/cgroup/cpuset cgroup rw,relatime,cpuset,cpuset_v2_mode 0 0
この状態では、さきほどと特に変化はありません。
# for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0-1 cpuset.effective_cpus: 0-1
ここで cpu1 をオフラインにします。
# echo 0 > /sys/devices/system/cpu/cpu1/online
すると、
# for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0-1 cpuset.effective_cpus: 0
cpuset.cpus
はそのままで実際の cpuset.effective_cpus
のみ値が変わります。
ここまで来ると動きは予想できますね。再度 cpu1 をオンラインにしてみます。
# echo 1 > /sys/devices/system/cpu/cpu1/online # for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0-1 cpuset.effective_cpus: 0-1
cgroup作成後にCPUが増えた時(2019-02-23 追記)
cgroup作成後にcpuが減って、また戻った場合の動きは見ましたが、cgroup作成後にonline の cpu が増えた場合にどうなるのかが気になったので試してみました。
# echo 0 > /sys/devices/system/cpu/cpu2/online # mkdir test01 # cd test01 # cat cpuset.cpus # cat cpuset.effective_cpus 0-1 # echo "0-1" > cpuset.cpus # echo "0" > cpuset.mems # for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0-1 cpuset.effective_cpus: 0-1 # echo 1 > /sys/devices/system/cpu/cpu2/online # for f in $(ls cpuset.*cpus); do echo -n "$f: "; cat $f; done cpuset.cpus: 0-1 cpuset.effective_cpus: 0-1
上の例のように CPU をひとつ(cpu2) offline にしておいて、cgroup を作成後、cpu2 を online にしても cpuset.effective_cpus
の値は変化しません。
まとめ
CPU/メモリーの online, offline を切り替えると:
- v1 mode:
cpuset.{cpus,mems}
、cpuset.effective_{cpus,mems}
の値も変化するが、その後再度状態が変わってもそのまま - v2 mode:
cpuset.{cpus,mems}
の値は変化しない。cpuset.effective_{cpus,mems}
の値は実際に合わせて変化する
ただし、cpuset.effective_*
の復元は cgroup 作成時の値まで。
おまけ(2019-02-23 追記)
ちなみにこのオプションが使えるようになったコミットは次のものですが、これはオプションの追加と、そのオプションが指定されているときの条件分岐を変更しているだけですので、処理自体はこの前にあらかじめ実装されているようですね。