Linuxカーネルでcpuset cgroup継承セマンティクスに関連する「問題」とは何ですか?

Linuxカーネルでcpuset cgroup継承セマンティクスに関連する「問題」とは何ですか?

引用する2013年、systemdは新しい制御グループインターフェースを発表しました。(強調追加):

現在、セル属性として公開されているcgroup属性の数は制限されています。後でカーネルインターフェイスが整理され、拡張される予定です。例えばカーネルロジックの継承セマンティクスが壊れているため、現在cpusetまたはFreezeはまったく公開されていません。さらに、実行時にユニットを別のスライスに移行すること(つまり、実行中のユニットのSlice =属性の変更)は、現在のカーネルにアトミックcgroupサブツリー移動がないためサポートされていません。

それでは、カーネルロジックの継承セマンティクスにはどのような問題がありますかcpuset(たとえば、他のcgroupコントローラには適用されませんcpu)。

持つRedHatウェブサイトの記事簡単に管理できるシステム単位属性のサポートが不足していても、RHEL 7でcgroup CPUsetを使用する方法の実績のないソリューションがありますが、これは良い考えですか?上記の太字の引用が懸念されます。

つまり、ここで参照されているcgroup v1 cpusetを使用すると、どのような「gotchas」(gotchas)が可能になりますか?


私はこれのために賞金を始めます。

この質問に答えることができる情報源は次のとおりです(特定の順序はありません)。

  1. cgroup v1ドキュメント;
  2. カーネルソースコード;
  3. テスト結果
  4. 実際の世界経験。

上記の引用で太字の可能な意味の1つは、新しいプロセスが分岐したときに親プロセスと同じcpuset cgroupに残っていないか、同じcgroupにあるが「強制されていない」状態にあることです。実際には、cgroupが許可するものとは異なるCPUで実行されている可能性があります。しかし、これは純粋に私の推測だ。明確な答えが必要です。

ベストアンサー1

ここにあるカーネルバグトラッカーには、明確で解決されていないCPUsetの問題が1つ以上文書化されています。

エラー42789- cpuset cgroup:CPUがオフライン状態になると、すべてのcgroupのcpuset.cpusから削除されますが、オンライン状態になるとルートcpuset.cpusにのみ戻ります。

見積もりコメントチケットから(実際の送信にハイパーリンクを追加し、スパムボットを防ぐためにIBMメールアドレスを削除しました):

これはPrashanth Nageshappaによって独立して報告され、コミットで修正されました。8f2f748b0656257153bcf0941df8d6060acc5ca6しかし、後でLinusによってコミットに戻りました。4293f20c19f44ca66e5ac836b411d25e14b9f185。約束したように、修正によって他の場所で回帰が発生しました。

修正コミット(後で元に戻す)は問題をよく説明します。

現在のCPUホットプラグ中に、cpusetコールバックはシステム状態を反映するようにcpusetを変更し、この処理は非対称です。つまり、CPUがオフラインになると、すべてのCPUセットから削除されます。ただし、再びオンラインになると、ルートCPUsetにのみ再配置されます。

これにより、一時停止/再開中に深刻な問題が発生しました。一時停止中は、起動しないすべてのCPUをオフラインにし、再起動中にオンラインに戻します。つまり、回復後、すべてのcpuset(ルートcpusetを除く)は1つのCPU(boot CPU)に制限されます。ただし、一時停止/再開の全体的な目的は、システムを一時停止前の状態にできるだけ近づけて復元することです。


次のように、継承との関係に関する追加の洞察とともに、同じ非対称ホットプラグの問題を説明します。

エラー188101- cgroupのcpusetのプロセススケジューリングが正しく機能しません。

そのチケットを引用するには:

コンテナのcpuset(docker / lxcはすべてデフォルトのcgroupを使用)が空になると(hotplug / hotunplugのため)、そのコンテナで実行されているプロセスは、最も近い空でない祖先のCPUsetに予約できます。

ただし、実行中のコンテナのcpusetを更新(echoメソッドを使用)して、実行中のコンテナ(docker / lxc)のcpusetが空の状態から空でない状態に変更された場合(空のcpusetにCPUを追加)、そのコンテナで実行される操作は次のようになります。プロセスは、まだ最も近い空でない祖先と同じCPUSetを使用します。


cpusetには他の問題があるかもしれませんが、上記は「カーネルロジックの継承セマンティクスが破損しているため」systemdがcpusetを公開または使用しないことを理解して理解するのに十分です。

この2つのバグレポートで判断すると、回復後にCPUがCPUsetに再追加されることはありません。はい(手動で)追加すると、そのcgroupのプロセスはcpusetが許可しないCPUで実行され続けます。


私が見つけたLennart Petlingによるメッセージこれはその理由を直接確認します(太字)。

Lennart Poetteringは、2016年8月3日水曜日16:56 +0200に次のように書きました。

2016年8月3日水曜日14:46に、Werner Fink博士(suse.deのwerner)が次のように書きました。

v228の問題(現在のgitログ以降のAFAICSのようです)は、繰り返しCPUホットプラグイベント(オフライン/オンライン)です。根本的な原因は、CPUset.cpusを加工に復元できないことです。 libvirtは許可されていないため、これを行うことはできません。

これはカーネルcpusetインタフェースの制限です。これが現在systemdでcpusetを公開していない理由の1つです。幸いにも、systemdのCPUAffinity =を介して公開されるCPUアフィニティコントロールであるcpusetに代わるものがあります。これは本質的に同じことを行いますが、意味がありません。

私たちはsystemdでcpusetを直接サポートしたいのですが、カーネルインタフェースが退屈であればそうしません。例えば、現在のシステムが一時停止/再開周期を経ると、CPUセットは完全にフラッシュされます。

おすすめ記事