有害なUSBスティックストールの問題– LWN.net、2013年11月。
Artem S. Tashkinovは最近、少なくとも一部のLWN読者にはなじみのある問題に遭遇しました。低速のストレージデバイス(たとえば、USBスティック、またはメディアプレーヤー)をLinuxマシンに接続し、それに大量のデータを書き込みます。 システム全体がハングアップするだけです 、おそらく数分間。
今回、Artemは興味深い観察を行いました。システムは、64ビットカーネルで実行するとストールしますが、同じハードウェアで32ビットカーネルを使用した場合、そのような問題は発生しませんでした。
この記事では、64ビットカーネルでは、ダーティページキャッシュ(ライトバックキャッシュ)がデフォルトでメモリの20%まで拡張できると説明しています。 32ビットカーネルでは、実質的に最大180MBに制限されていました。
Linusは、64ビットでも最大180MBに制限することを提案しましたが、現在のLinux(v4.18)はこれを行いません。 Linusが提案したパッチを、Linux4.18の現在の機能と比較してください。そのような変更に対する最大の議論は、デイブ・チナーから来ました。彼は、バッファリングを減らしすぎると、ファイルシステムが断片化する原因になると指摘しました。彼はまた、「ストリーミングIOの場合、通常、少なくとも5秒のキャッシュされたダーティが必要であると説明しました。 遅延を均等にするためのデータ。」
混乱しています。 USBスティックのストールによってシステム全体がハングしたのはなぜですか?
2011年にマージされたコード(Linux 3.2)について説明している以前の記事を読んだため、混乱しています。これは、カーネルがデバイスごとにダーティページキャッシュを制御している必要があることを示しています。
No-I / Oダーティスロットル– LWN.net、2011
そこでFengguangのパッチセットが登場します。彼は、各プロセスがいつでもダーティになることを許可するページ数を決定できる制御ループを作成しようとしています。制限を超えたプロセスは、ライトバックシステムがそれらに追いつくことができるように、単にしばらくスリープ状態にされます。
[…]
システムの目標は、ダーティページの数を設定値に保つことです。物事がラインから外れた場合、物事を本来あるべき場所に戻すために、より多くの力が加えられます。
[…]
ただし、この比率は、バッキングデバイス(BDI)を考慮せずに実際に計算することはできません。プロセスが特定のBDIに保存されているページをダーティにしている可能性があり、システムには現時点でダーティページが大量にある可能性がありますが、そのプロセスを抑制する知恵は、そのBDIにダーティページがいくつ存在するかにも依存します。 […]ダーティページが少ないBDIは、バックログをすばやくクリアできるため、システムが希望よりも多少ダーティであっても、おそらくもう少し余裕があります。そのため、パッチセットは、特定のBDIがそれ自体の設定値と観測された帯域幅からどれだけ離れているかを調べる複雑な式を使用して、特定のBDIの計算されたpos_ratioを微調整します。最終結果は、システムが特定のBDIによって裏付けられたページをダーティするか、それとも少なくするか、およびその量を説明する変更されたpos_ratioです。
デバイスごとの制御は、これよりも前に追加されました:よりスマートな書き込みスロットリング、2007LWN.net。 [PATCH0/23]デバイスごとのダーティスロットル-v10。 Linuxバージョン2.6.24でマージされました。
承認された回答:
- 2013年の記事は間違っています
- LWNの間違い?よろしいですか?
- 「バックグラウンド」ライトバックによって作成されたI/Oデバイスの長いキュー
- 「I/Oなしのダーティスロットル」の制限はありますか?
- 「USBスティックストール」の問題に関する本物の報告
- ダーティ制限が正しく計算されていません[2014]
- IOでの大量のページ割り当てのブロック[2011]
- 「ダーティページがLRUの終わりに到達しています」? [2013年以前]
1。 2013年の記事は間違っています
「USBスティックストール」の記事は、非常に誤解を招く印象を与えます。元のレポートと一連の応答の両方を誤って伝えています。
Artemは、キャッシュされた書き込みをUSBスティックにフラッシュしたときに、システム全体がハングしていることを報告しませんでした。彼の元のレポートは、コマンド「sync」の実行に最大「数十分」かかる可能性があるとだけ不満を述べていました。この区別は、Linus Torvaldsの回答で明確にされています:
平均的なUSBキーを取得して書き込みを試みるだけで、実際に簡単に再現できます。
ランダムなISO
画像でやっただけで、苦痛です。 そして、バックグラウンドで他のほとんどのことを行うのが面倒なことではありませんが、
「同期」するもの(およびスクリプトで発生するもの)を実行した場合は、
きしむような停止になります。 数分間。
2。 LWNの間違い?よろしいですか?
Jon Corbetは15年の経験があり、Linuxカーネルの開発を毎週報告しています。記事は少なくとも近いと思っていました ある意味でそれを正しくするために。そこで、2つの異なるレコードを処理し、それらが同意または不同意となる詳細なポイントを探します。
lore.kernel.orgのアーカイブを使用して、元のディスカッションをすべて読みました。メッセージはかなり明確だと思います。
私はその記事が議論を誤解していると100%確信しています。記事の下のコメントでは、少なくとも2人の読者が自分の言葉で誤った主張を繰り返し、誰もそれらを修正しませんでした。この記事は、3番目の段落でこの混乱を続けています:
そのすべてのデータがI/Oキューを詰まらせ、他の操作を遅らせる可能性があります。そして、誰かがsync()を呼び出すとすぐに、そのキュー全体が書き込まれるまで処理が停止します。
これは、Linusが「物事はひどく止まる」と言っていることから混乱する可能性があります。 「モノ」とは、「sync
を実行するものすべて」を指します 「。しかし、Corbetは、「モノ」が「システム全体」を意味するかのように書いています。
Linusによると、これは現実の問題です。しかし、「もの」の大部分はしません システム全体のsync()操作を呼び出します。[1]
なぜCorbetはこれを「システム全体」と混同するのでしょうか。私は多くの問題があったと思います、そしてしばらくするとあなたの頭の中でそれらをすべて別々に保つのは難しくなります:-)。また、LWNは、デバイスごと(およびプロセスごと)のダーティスロットリングの開発について説明していますが、一般的に、そのような詳細についてはあまり書かれていないと思います。多くのドキュメントでは、グローバルなダーティ制限設定についてのみ説明しています。
3。 「バックグラウンド」ライトバックによって作成されたI/Oデバイスの長いキュー
Artemは、スレッドに2番目のレポートを投稿しました。このレポートでは、「サーバーがほとんど停止し、他のIOリクエストが完了するまでにかなりの時間がかかります」。
関連:Linux – iptablesを介したルーティング?この2番目のレポートは、USBスティックのハングに関する主張とは一致しません。 内部で10GBのファイルを作成した後に発生しました ディスク。これは別の問題です。
レポートは、ダーティ制限を変更することでこれを改善できるかどうかを確認していません。そして、このようなケースのより最近の分析があります。メインディスクのI/Oキューが詰まると、重大な問題が発生します。プログラムコードをオンデマンドでロードしたり、write()+ fsync()を使用してドキュメントやアプリデータを保存したりするために、常に依存しているディスクで長い遅延が発生する可能性があります。
煩わしさの少ないバックグラウンドライトバックに向けて— LWN.net、2016
メモリ管理コードがダーティデータの範囲を書き込むことを決定すると、結果はブロックサブシステムに送信されたI/O要求になります。そのリクエストはI/Oスケジューラーでしばらく時間がかかる場合がありますが、最終的には宛先デバイスのドライバーにディスパッチされます。
問題は、書き込むダーティデータがたくさんある場合、デバイスに対してキューに入れられるリクエストが膨大な数(数千の場合など)になる可能性があることです。適度に高速なドライブでさえ、その多くの要求を処理するのに時間がかかる場合があります。他のアクティビティ(たとえば、Webブラウザでリンクをクリックする、またはアプリケーションを起動する)が同じブロックデバイスでI / O要求を生成する場合、それらの要求はその長いキューの後ろに行き、しばらくの間処理されない可能性があります。複数の同期要求が生成された場合(たとえば、新しく起動されたアプリケーションからのページフォールト)、これらの各要求は、この長いキューを通過する必要があります。それは物事がただ止まっているように見えるポイントです。
[…]
ほとんどのブロックドライバーは、独自のキューも内部で維持しています。これらの下位レベルのキューは、リクエストがそこに到達するまでに、I / Oスケジューラの制御の対象ではなくなるため(I / Oスケジューラがある場合)、特に問題になる可能性があります。
2016年後半にこれを改善するためにパッチがマージされました(Linux4.10)。このコードは、「ライトバックスロットリング」またはWBTと呼ばれます。 Webでwbt_lat_usec
を検索する また、これについてさらにいくつかの話があります。 (最初のドキュメントはwb_lat_usec
について書いています 、しかしそれは時代遅れです)。ライトバックスロットリングは、CFQまたはBFQ I/Oスケジューラーでは機能しないことに注意してください。 CFQは、デフォルトのI / Oスケジューラーとして人気があり、Linuxv4.20までのデフォルトのカーネルビルドも含まれます。 CFQはカーネルv5.0で削除されました。
SSD(NVMeのように見えた)と「通常のハードドライブ」の両方で問題(およびプロトタイプソリューション)を説明するためのテストがありました。ハードドライブは、「非常にバースト性の高いIOがある、より深いキュー深度のデバイスほど悪くはありませんでした」。
キューに入れられたリクエストの「数千」についてはわかりませんが、少なくとも数百のリクエストをキューに入れることができるNVMeデバイスがあります。ほとんどのSATAハードドライブでは、32個の要求をキューに入れることができます(「NCQ」)。もちろん、ハードドライブは各リクエストを完了するのに時間がかかります。
4。 「I/Oなしのダーティスロットル」の制限はありますか?
「No-I/Oダーティスロットル」は、非常に複雑な設計システムです。また、時間の経過とともに調整されています。 いくつかあったと思いますが、今でもそうです。 このコード内の制限。
LWNの記述、コード/パッチのコメント、および詳細なプレゼンテーションのスライドは、多数のシナリオが検討されていることを示しています。これには、悪名高い低速USBスティックv.sが含まれます。高速メインドライブ。テストケースには、「1000の同時dd」(つまり、シーケンシャルライター)というフレーズが含まれています。
これまでのところ、ダーティなスロットリングコード内の制限を実証および再現する方法がわかりません。
ダーティなスロットリングコードの外にある問題修正の説明をいくつか見てきました。私が見つけた最新の修正は2014年でした–後続のセクションを参照してください。 LWNが報告しているスレッドでは、次のことを学びます。
過去数回のリリースでは、このような問題は
再生の問題が原因で発生しました。これは、ライトバックページの下に大量のダーティが表示されてうんざりし、IOが終了するのを待ってスタックしてしまいました。[…]systemtapスクリプトはこれらのタイプの領域をキャッチし、
それらは修正されたと思います。
メルゴーマンはまた、いくつかの「未解決の問題」があると述べました。
しかし、まだ問題があります。すべてのダーティページが低速のデバイスによってバックアップされている場合でも、ダーティ制限により、最終的にダーティページバランシングでストールが発生します[…]
この一節は、報告されたディスカッションスレッドで私が見つけた唯一のものであり、LWNの解釈を裏付けるところにあります。それが何を指しているのかを理解したいと思います:-(またはそれをどのように実証するか、そしてなぜそれがArtemとLinusが実行したテストで重要な問題として取り上げられなかったのか。
5。 「USBスティックストール」の問題に関する本物の報告
ArtemもLinuxも、システム全体に影響を与える「USBスティックストール」を報告していませんが、これに関するいくつかの報告は他の場所で見つけることができます。これには、最近のレポートが含まれます–最後の既知の修正のかなり後です。
違いはわかりません。テスト条件が何らかの形で異なっていたか、2013年以降にカーネルで新しい問題が発生した可能性があります…
- https://utcc.utoronto.ca/~cks/space/blog/linux/USBDrivesKillMyPerformance / https://utcc.utoronto.ca/~cks/space/blog/linux/FixingUSBDriveResponsiveness [2017] >
- ファイルをペンドライブにコピーしているときにPCがフリーズするのはなぜですか? [2014年1月]
- 外部ディスクで大規模なR/W操作を実行するとシステムが遅れる[2018]
- 重いディスクI/Oを実行すると、Linux GUIが非常に応答しなくなります–何を調整しますか? [2019]
6。ダーティリミットが正しく計算されていません[2014]
2014年1月に興味深い修正がありました(カーネルv3.14に適用されました)。質問では、デフォルトの制限がメモリの20%に設定されていると述べました。実際には、ダーティページキャッシュに使用できるメモリの20%に設定されています。たとえば、カーネルバッファはTCP/IPネットワークソケットのデータを送信しました。ソケットバッファを削除してダーティページキャッシュに置き換えることはできません:-)。
問題は、ダーティページキャッシュを優先してデータをスワップアウトできるかのように、カーネルがスワップ可能なメモリをカウントしていたことでした。これは理論的には可能ですが、カーネルはスワッピングを回避するように強くバイアスされており、代わりにページキャッシュをドロップすることを好みます。この問題は、低速のUSBスティックへの書き込みを含むテストによって説明され、システム全体でストールが発生したことに気づきました:-)
関連:Linux –出力を2>&1および1>&2にリダイレクトするのはなぜですか?Re:[patch 0/2] mm:重いアノンとダーティキャッシュを使用して再利用ストールを減らす
を参照してください。
修正はそのdirty_ratio
現在、ファイルキャッシュの一部としてのみ扱われます。
この問題を抱えたカーネル開発者によると、「トリガー条件は非常に妥当であるように思われます。大量のバッファIOとスワップが構成された状態での高いアノンメモリ使用量です。これは実際に発生している可能性が高いです。」したがって、これは一部を説明する可能性があります 2013年頃以前のユーザーレポート。
7。 IOでブロックされている巨大なページ割り当て[2011]
これは別の問題でした:巨大なページ、遅いドライブ、そして長い遅延(LWN.net、2011年11月)。巨大なページに関するこの問題は修正されるはずです。
また、記事の内容にも関わらず、現在のほとんどのLinuxPCは実際には巨大なページを使用していないと思います。これはDebian10から変更される可能性があります。ただし、Debian 10が可能な限り巨大なページの割り当てを開始しても、defrag
という別の設定を変更しない限り、遅延が発生しないことは明らかです。 「常に」に。
8。 「ダーティページがLRUの終わりに到達しました」[2013年以前]
私はこれを調べていませんが、面白いと思いました:
mgorman 2011:これは新しいタイプのUSB関連のストールです。これは、同期圧縮書き込みが原因であり、これまでのように大きな問題が汚れていた
ページがLRUの終わりに到達し、再利用によって書き込まれるためです。 。mgorman 2013:その一般的な領域での作業は、
LRUの終わりに到達するダーティページなどの問題に対処しました(CPUの過剰使用
)
これらが2つの異なる「LRUの終わりに到達する」問題である場合、最初の問題は非常に悪い可能性があるように聞こえます。ダーティページが最も使用頻度の低いページになると、そのダーティページの書き込みが完了するまで、メモリの割り当てが遅れる可能性があります。
それが何を意味するにせよ、彼は問題が今修正されたと言います。
[1] 1つの例外:しばらくの間、Debianパッケージマネージャーdpkg
sync()を使用してパフォーマンスを向上させました。 sync()に非常に長い時間がかかる可能性があるという正確な問題のため、これは削除されました。彼らはsync_file_range()
を使用するアプローチに切り替えました Linuxの場合。 Ubuntuのバグ#624877、コメント62を参照してください。
この質問に答える以前の試みの一部–これはほとんど冗長であるはずです:
Artemの両方のレポートは、「No-I/Oダーティスロットル」コードと一致していると説明できると思います。
ダーティスロットルコードは、各バッキングデバイスが「他のデバイスと比較した現在の平均書き込み速度に関連する」「合計ライトバックキャッシュ」の公平なシェアを可能にすることを目的としています。この言い回しは、/ sys / class /bdi/のドキュメントからのものです。[2]
最も単純なケースでは、1つのバッキングデバイスのみが書き込まれます。その場合、デバイスの公平なシェアは100%です。 write()呼び出しは、ライトバックキャッシュ全体を制御し、「セットポイント」に維持するために調整されます。
書き込みはdirty_background_ratio
の中間で抑制され始めます –バックグラウンドの書き込みを開始するポイント–およびdirty_ratio
–ライトバックキャッシュのハード制限。デフォルトでは、これらは使用可能なメモリの10%と20%です。
たとえば、メインディスクへの書き込みのみで最大15%を埋めることができます。 RAMの容量に応じて、ギガバイトのキャッシュ書き込みが可能です。その時点で、write()呼び出しは、ライトバック速度に一致するように抑制され始めますが、それは問題ではありません。ハングの問題は、大量の無関係なIOの背後でスタックするread()およびfsync()呼び出しにあると思います。これは、「ライトバックスロットリング」コードによって対処される特定の問題です。一部のWBTパッチの提出には、問題の説明が含まれており、これが引き起こす恐ろしい遅延を示しています。
同様に、15%をUSBスティックへの書き込みで完全に埋めることができます。 USBへのそれ以上のwrite()は抑制されます。しかし、メインディスクはその公平なシェアを使用していません。メインファイルシステムでwrite()の呼び出しを開始すると、スロットルされないか、少なくとも遅延が大幅に少なくなります。そして、2人のライターのバランスをとるために、USB write()はさらに抑制されると思います。
全体的なライトバックキャッシュが一時的に設定値を超える可能性があると思います。より要求の厳しいケースでは、ライトバックキャッシュ全体のハード制限に達する可能性があります。ハード制限は、デフォルトで使用可能なメモリの20%に設定されています。構成オプションはdirty_ratio
です。 / dirty_bytes
。おそらく、デバイスの速度が低下する可能性があり(おそらく、よりランダムなI / Oパターンが原因で)、ダーティスロットルが速度の変化をすぐに認識しないため、これにぶつかる可能性があります。
[2]このドキュメントは、手動でできることを示唆していることに気付くかもしれません。 特定のパーティション/ファイルシステムに使用できるライトバックキャッシュの割合を制限します。この設定は/sys/class/bdi/*/max_ratio
と呼ばれます 。 「制限したいデバイスが現在書き込まれている唯一のデバイスである場合、制限は大きな影響を与えない」ことに注意してください。