HN 日本語サマリー

← 一覧へ戻る
インフラ・DevOps

Xenのdom0 I/OパスをNUMA対応にする

Making Xen's dom0 I/O path NUMA aware (edera.dev)

21 pointsby virtio_vixen4 コメント

要約

この記事は、Xenハイパーバイザーのdom0(管理ドメイン)におけるI/OパスのNUMA(Non-Uniform Memory Access)対応の改善について解説しています。以前のNUMA対応の課題を克服するため、dom0自身のメモリ配置を最適化し、SRAT、SLIT、CPUIDといったNUMAトポロジー情報を正確に生成することで、dom0内のワークロードがホストの物理的なNUMAトポロジーを正しく認識できるようにしました。これにより、ストレージやコンテナなどのI/Oパスのパフォーマンスが向上し、自動NUMAバランシングが有効になることで、システム全体の効率が改善されます。

全文翻訳

この記事シリーズのパート3では、XenのパラバーチャルI/Oアーキテクチャと、それがNUMA(Non-Uniform Memory Access)ホストで高コストになる理由を説明しました。具体的には、NUMAメタデータのない外部マッピングされたページ、スケジューラが配置を決めるkthread、dom0カーネルとホストの実際のトポロジー間の情報ギャップなどです。パート3では、この問題の修正には構造的なものとコンポーネントごとのものの2つの要素があり、パート4で両方を提供すると約束して締めくくりました。 パート4ではその約束を果たします。その過程で、当初計画になかった2つの問題も扱います。1つは、本格的な作業を開始する前に直面した問題です。dom0自身のメモリ配置が非常に偏っていたため、まずそれを修正せずにdom0用のトポロジーを合成しても、カーネルに嘘をつくようなものでした。これは迂回路ではなく前提条件です。パート4の他のすべての作業はこの上に構築されています。もう1つは、作業が名目上完了した後で直面した問題です。それは、私たちのツールスタックにおけるメモリ配置のバグで、マルチvnode vNUMAがツリーに存在して以来、静かに壊れており、メモリ帯域幅ベンチマークの下でのみ表面化しました。これは真の迂回路であり、最後の方で扱います。 まず前提条件から始めましょう。 最初の発見:dom0のメモリが間違った場所にあった 標準のXenは、dom0をブートする際に、ホストのBIOSメモリマップ(E820)をdom0が所有すべきメモリのサブセットにトリミングする必要があります。トリミングはホストのE820を物理アドレス順にウォークし、dom0_memを満たすのに十分なメモリが確保されるまで領域をdom0のものとしてマークします。シングルノードホストではこれは無害です。dom0のメモリは利用可能な唯一のノードから取得されます。マルチソケットホストでは、同じコードが深刻な問題を引き起こします。ホストのメモリ領域は通常、物理アドレス順にNUMAノードごとにグループ化されているため、E820を順にウォークすると、dom0は最初に低アドレスノードのメモリをすべて取得します。 最悪のケースは深刻です。128 GiB、8ノードのホストでdom0_memが35%の場合(私たちのラボボックスの設定)、dom0は低アドレスノードのRAMの100%を占有し、他のノードは0%になります。ノード0から2はほぼ完全にdom0に消費され、ノード3から7にはdom0所有のページはまったくありません。dom0がリモートノードでの割り当てを試みることさえできない場合、dom0をNUMA対応にしても、カーネルが実行できないトポロジーを合成することになります。生成されるSRATは、60%のdom0メモリが他の6つのノードに何も持たずに存在する1つのノードを記述することになります。 私たちのトリミングは、この順次取得を比例取得に置き換えます。これは、私たちのツリーがアップストリームXenから分岐する場所の1つです。2パスで実行されます。パス1はホストの合計RAMを合計し、パス2は各領域にdom0_mem予算の比例配分を与えます。算術はBresenhamスタイルで、丸め誤差が蓄積されるため、合計は正確にdom0_memと等しくなります。dom0のメモリは、各ホストノードの物理RAMのシェアに比例して、すべてのホストノードに分散されます。 dom0が実際にすべてのホストノードにメモリを所有するようになったので、残りの作業を開始できます。 dom0をNUMA対応にする 任意のXenドメインのための3つのNUMAトポロジー要素 シリーズパート2から思い出してください。NUMA対応のXenドメインは、3つのトポロジー要素を認識します。 ACPIシステムリソースアフィニティテーブル(SRAT):CPUとメモリ範囲をNUMAノードにマッピングします。 ACPIシステムローカリティ情報テーブル(SLIT):ノード間距離のマトリックスを提供します。 CPUIDのx2APIC ID:CPUごとのパッケージ/コア/スレッド識別子をエンコードします。 正確なNUMA認識を必要とする任意のXenドメインには、これら3つすべてが存在し、一貫している必要があります。アップストリームXenは、ツールスタックがXEN_DOMCTL_setvnumainfo経由でvNUMAレイアウトを要求する際に、PVHおよびHVM domUのほとんどの作業を行います。SRATとSLITは要求されたトポロジーに合わせて合成されます。しかし、アップストリームXenはCPUIDのx2APIC IDをvNUMAレイアウトから合成しません。この3番目の要素は、この投稿で説明されている作業が始まる前からEderaの拡張機能であり、私たちはそれをさらに拡張して、マルチノードdomUでの非2のべき乗のvCPU数を処理できるようにしました。 dom0は話が異なります。この投稿で説明されている作業まで、アップストリームXenはdom0のためにこれら3つのうちのどれも合成しませんでした。dom0は、ホストにいくつの物理ノードがあっても、単一のフラットなNUMAノードとして認識されていました。このセクションで説明されている作業は、特定の条件下で、これら3つの合成をdom0にも拡張します。 条件:dom0はPVHであること。dom0_vcpus_pin=1でブートすること。これにより、各dom0 vCPUは特定のホストpCPUに1対1でハードピン留めされます。dom0 vCPU数はホストpCPU数と等しく、すべてのpCPUに対応するdom0 vCPUが存在すること。ホストは複数のNUMAノードを持つこと。これらの条件は、実装にも有用な副作用をもたらします。すべてのdom0 vCPU NがpCPU Nにピン留めされているため、vCPU NのvNUMAノード割り当ては、pCPU Nに対応するホストのNUMAノードにすぎません。レイアウトアルゴリズムを設計する必要も、ブート時に配置決定を行う必要も、部分的にカバーされたホストトポロジーのエッジケースもありません。なぜなら、dom0は定義上、ホスト全体をカバーするからです。実装は、ホストのcpu_to_nodeテーブルの直接ウォークとして機能します。 条件が満たされると、dom0は以下を取得します。 dom0がカバーする各ホストNUMAノードごとに1つの近接ドメインを記述する合成SRAT。適切なCPUセットと、各ノード内の適切なメモリ領域が含まれます。 ホスト自身のSLITから直接スライスされた合成SLIT。dom0が認識する距離は、LinuxがSLITが存在しない場合に代わりに使用するデフォルトの「ローカル10、リモート20」のスタブではなく、実際のノード間距離です。 domUケースを処理するのと同じメカニズムを使用して、合成トポロジーに一致するようにエンコードされたCPUIDのx2APIC ID。 この後、dom0内のnumactl -Hは、ついに実際のトポロジーを表示します。以前は1つと報告されていたものが8つのノードになり、それぞれが実際に属するCPUとメモリを持っています。dom0内のストレージデーモンは実際のトポロジーを認識します。dom0内のコンテナランタイムは実際のトポロジーを認識します。 そして、カーネル自身の自動NUMAバランシングが、ついに作用する対象を得ました。正確なマップにより、各タスクの実行場所をサンプリングし、時間の経過とともにそのタスクのページを同じノードに移行させ、リモートアクセスを自己修復します。この自己修復は、フラットな1ノードビューに対しては存在しません(バランスを取る対象がないため)。これは、トポロジー作業がアンロックするもう1つの機能です。ただし、これは計画というよりはフォールバックであり、独自のコストを持つサンプリングヒューリスティックです。カーネルのガイダンスは、すでにピン留めされているワークロードに対してはこれをオフにすることです。これは、後続のセクションがI/Oパスに対して行うこととまさに同じです。 すべてのEderaデプロイメントのdom0シェルは、初めて正確な情報に基づいて動作するようになりました。 また、dom0のNUMA対応は、混合ノードで本当に重要であることも注目に値します。多くのEderaデプロイメントはすべてEderaではありません。同じマシンで、通常のランタイム下で通常のコンテナとして実行されるポッド(dom0内で直接)と、Ederaランタイム下で実行されるポッド(それぞれ独自のゾーンに封入されている)があります。これらの通常のコンテナは、他のdom0ワークロードと同様に扱われます。この作業の前は、それらはNUMAを認識せずに実行されていました。Ederaホスト上で、非Ederaポッドは、単なるLinuxとして同じボックスで実行されていたときよりも遅くなる可能性があります。なぜなら、マシンをXen dom0に変換したことで、ワークロードが以前認識していたトポロジーが隠されてしまったからです。dom0をNUMA対応にすることで、そのギャップが埋まります。dom0内に残るコンテナは、ベアメタルで認識していたトポロジーを取得するため、Ederaを採用しても、最初にサンドボックス化されなかったワークロードに静かに負荷がかかることはありません。 なぜSRAT、SLIT、CPUIDがすべて重要なのか ACPIテーブルだけで十分だと仮定するのは魅力的です。カーネルはブート時にそれらを読み込み、NUMAインフラストラクチャがトポロジーを取得し、完了です。一部のコンシューマーにとってはそれで十分です。ほとんどのNUMA対応ユーザー空間ツールが構築されているhwlocライブラリは、カーネルのsysfsビューからトポロジーのビューを派生させます(カーネルはそれをSRATとSLITからさらに populat します)。これら2つを正しく設定すれば、sysfsサーフェスは正しく populat され、hwlocは満足します。 他の