Red Hat Training
A Red Hat training course is available for RHEL 8
34.2. IRQ バランシングのチューニング
マルチコアホストでは、Red Hat Enterprise Linux が割り込みキュー (IRQ) のバランスをとり、CPU コア全体に割り込みを分散するようにすることで、パフォーマンスを向上させることができます。
34.2.1. 割り込みと割り込みハンドラー
ネットワークインターフェイスコントローラー (NIC) が受信データを受信すると、Direct Memory Access (DMA) を使用してそのデータをカーネルバッファーにコピーします。次に、NIC はハード割り込みをトリガーして、このデータについてカーネルに通知します。これらの割り込みは、すでに別のタスクに割り込んでおり、ハンドラー自体は割り込むことができないため、最小限の作業を行う割り込みハンドラーによって処理されます。ハード割り込みは、特にカーネルロックを使用する場合、CPU 使用率の点でコストがかかる可能性があります。
その後、ハード割り込みハンドラーは、パケット受信の大部分をソフトウェア割り込み要求 (SoftIRQ) プロセスに任せます。カーネルは、これらのプロセスをより公平にスケジュールできます。
例34.1 ハードウェア割り込みの表示
カーネルは、割り込みカウンターを /proc/interrupts
ファイルに保存します。enp1s0
などの特定の NIC のカウンターを表示するには、次のように入力します。
# egrep "CPU|enp1s0" /proc/interrupts CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 105: 141606 0 0 0 0 0 IR-PCI-MSI-edge enp1s0-rx-0 106: 0 141091 0 0 0 0 IR-PCI-MSI-edge enp1s0-rx-1 107: 2 0 163785 0 0 0 IR-PCI-MSI-edge enp1s0-rx-2 108: 3 0 0 194370 0 0 IR-PCI-MSI-edge enp1s0-rx-3 109: 0 0 0 0 0 0 IR-PCI-MSI-edge enp1s0-tx
各キューには、最初の列に割り込みベクトルが割り当てられています。カーネルは、システムの起動時、またはユーザーが NIC ドライバーモジュールをロードしたときに、これらのベクトルを初期化します。各受信 (RX
) キューと送信 (TX
) キューには、どの NIC またはキューから割り込みが発生しているかを割り込みハンドラーに通知する固有のベクトルが割り当てられます。列は、各 CPU コアの受信割り込みの数を表します。
34.2.2. ソフトウェア割り込み要求
ソフトウェア割り込み要求 (SoftIRQ) は、ネットワークアダプターの受信リングバッファーをクリアします。カーネルは、他のタスクが割り込みされない時間に SoftIRQ ルーチンが実行されるようにスケジュールします。Red Hat Enterprise Linux では、ksoftirqd/cpu-number
という名前のプロセスがこれらのルーチンを実行し、ドライバー固有のコード関数を呼び出します。
各 CPU コアの SoftIRQ カウンターを監視するには、次のように入力します。
# watch -n1 'egrep "CPU|NET_RX|NET_TX" /proc/softirqs'
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
NET_TX: 49672 52610 28175 97288 12633 19843 18746 220689
NET_RX: 96 1615 789 46 31 1735 1315 470798
このコマンドは出力を動的に更新します。Ctrl+C を押して出力に割り込みます。
34.2.3. NAPI ポーリング
New API (NAPI) は、受信ネットワークパケットの効率を向上させるためのデバイスドライバーパケット処理フレームワークの拡張機能です。ハード割り込みは、通常、カーネル空間からユーザー空間へのコンテキストの切り替えを引き起こし、またその逆のコンテキストの切り替えも引き起こし、それ自体を中断することができないため、コストがかかります。割り込み結合を行っても、割り込みハンドラーは CPU コアを完全に独占します。NAPI を使用すると、ドライバーは、パケットを受信するたびにカーネルによってハード割り込みされるのではなく、ポーリングモードを使用できます。
通常の操作では、カーネルは最初のハード割り込みを発行し、続いて NAPI ルーチンを使用してネットワークカードをポーリングするソフト割り込み要求 (SoftIRQ) ハンドラーを発行します。SoftIRQ が CPU コアを独占しないようにするために、ポーリングルーチンには、SoftIRQ が消費できる CPU 時間を決定するバジェットがあります。SoftIRQ ポーリングルーチンが完了すると、カーネルはルーチンを終了し、後で再度実行してネットワークカードからパケットを受信するプロセスを繰り返すようにスケジュールします。
34.2.4. irqbalance サービス
Non-Uniform Memory Access (NUMA) アーキテクチャーを備えたシステムと備えていないシステムの両方で、irqbalance
サービスは、システム条件に基づいて CPU コア間で効果的に割り込みのバランスをとります。irqbalance
サービスはバックグラウンドで実行され、10 秒ごとに CPU 負荷を監視します。CPU の負荷が高すぎる場合、このサービスは割り込みを他の CPU コアに移動します。その結果、システムのパフォーマンスが向上し、負荷がより効率的に処理されます。
irqbalance
が実行されていない場合、通常は CPU コア 0 がほとんどの割り込みを処理します。中程度の負荷でも、この CPU コアはシステム内のすべてのハードウェアのワークロードを処理しようとしてビジーになる可能性があります。その結果、割り込みまたは割り込みベースの作業ができなかったり、遅延したりする可能性があります。これにより、ネットワークやストレージのパフォーマンスの低下、パケットロス、その他の問題が発生する可能性があります。
irqbalance
を無効にすると、ネットワークのスループットに悪影響を及ぼす可能性があります。
CPU コアが 1 つしかないシステムでは、irqbalance
サービスは何のメリットも提供せず、自動的に終了します。
デフォルトでは、irqbalance
サービスは有効になっており、Red Hat Enterprise Linux 上で実行されています。サービスを無効にした場合に再度有効にするには、次のように入力します。
# systemctl enable --now irqbalance
関連情報
- ソリューション記事 Do we need irqbalance?
- ソリューション記事 How should I configure network interface IRQ channels?
34.2.5. CPU 上で SoftIRQ を実行できる時間の増加
SoftIRQ の実行時間が十分でない場合、受信データの速度が、バッファーを十分な速さでドレインするカーネルの能力を超える可能性があります。その結果、ネットワークインターフェイスコントローラー (NIC) のバッファーがオーバーフローし、パケットが失われます。
softirqd
プロセスが 1 回の NAPI ポーリングサイクルでインターフェイスからすべてのパケットを取得できなかった場合、それは SoftIRQ に十分な CPU 時間がないことを示しています。これは、10 Gbps 以上の高速 NIC を備えたホストに当てはまる可能性があります。net.core.netdev_budget
および net.core.netdev_budget_usecs
カーネルパラメーターの値を増やすと、softirqd
がポーリングサイクルで処理できる時間とパケット数を制御できます。
手順
net.core.netdev_budget
パラメーターのチューニングが必要かどうかを判断するには、/proc/net/softnet_stat
ファイル内のカウンターを表示します。# awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t 221951548 0 0 0 0 0 0 0 0 0 0 0 0 192058677 0 20380 0 0 0 0 0 0 0 0 0 1 455324886 0 0 0 0 0 0 0 0 0 0 0 2 ...
この
awk
コマンドは、/proc/net/softnet_stat
の値を 16 進形式から 10 進形式に変換し、表形式で表示します。各行は、コア 0 から始まる CPU コアを表します。関連する列は次のとおりです。
- 最初の列: 受信フレームの総数
-
3 番目の列: 1 回の NAPI ポーリングサイクルでインターフェイスからすべてのパケットを取得できなかった
softirqd
プロセスの回数。 - 最後の列: CPU コア番号
/proc/net/softnet_stat
ファイルの 3 番目の列のカウンターが、時間の経過とともに増加する場合は、システムをチューニングします。net.core.netdev_budget_usecs
およびnet.core.netdev_budget
パラメーターの現在の値を表示します。# sysctl net.core.netdev_budget_usecs net.core.netdev_budget net.core.netdev_budget_usecs = 2000 net.core.netdev_budget = 300
これらの設定を使用すると、
softirqd
プロセスは、1 回のポーリングサイクルで、NIC から最大 300 個のメッセージを処理するのに最大 2000 マイクロ秒あります。ポーリングは、どの条件が最初に満たされたかに基づいて終了します。次の内容を含む
/etc/sysctl.d/10-netdev_budget.conf
ファイルを作成します。net.core.netdev_budget = 600 net.core.netdev_budget_usecs = 4000
パラメーターを現在の値の 2 倍に設定します。
/etc/sysctl.d/10-netdev_budget.conf
ファイルから設定をロードします。# sysctl -p /etc/sysctl.d/10-netdev_budget.conf
検証
/proc/net/softnet_stat
ファイルの 3 番目の列を監視します。# awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t
それでも値が増加する場合は、
net.core.netdev_budget_usecs
とnet.core.netdev_budget
をより高い値に設定します。カウンターが増加しなくなるまで、このプロセスを繰り返します。