Linux システムによって報告される tcp_mark_head_lost エラーの処理方法

Linux システムによって報告される tcp_mark_head_lost エラーの処理方法

問題の説明

最近、ホストから次のカーネル情報が報告されました。

7月8日 10:47:42 cztest カーネル: ------------[ここでカット]------------
7月8日 10:47:42 cztestカーネル: 警告: net/ipv4/tcp_input.c:2269 tcp_mark_head_lost+0x113/0x290()
7 月 8 日 10:47:42 cztest カーネル: リンクされているモジュール: iptable_filter ip_tables binfmt_misc cdc_ether usbnet mii xt_multiport dm_mirror dm_region_hash dm_log dm_mod intel_powerclamp coretemp intel_rapl iosf_mbi kvm_intel kvm irqbypass crc32_p
clmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper cryptd ipmi_ssif ipmi_devintf ipmi_si mei_me pcspkr iTCO_wdt mxm_wmi iTCO_vendor_support dcdbas mei sg sb_edac edac_core ipmi_msghandler shpchp lpc_ich wmi acpi_p
ower_meter xfs libcrc32c sd_mod crc_t10dif crct10dif_generic mgag200 drm_kms_helper crct10dif_pclmul crct10dif_common syscopyarea crc32c_intel sysfillrect sysimgblt fb_sys_fops igb ttm ptp drm ahci pps_core libahci dca i2c_algo_bit libat
megaraid_sas i2c_core fjes [最後にアンロードされたもの: ip_tables]
7月8日 10:47:42 cztest カーネル: CPU: 10 PID: 0 通信: swapper/10 汚染: GW ------------ 3.10.0-514.16.1.el7.x86_64 #1
7月8日 10:47:42 cztestカーネル: ハードウェア名: Dell Inc. PowerEdge R630/02C2CP、BIOS 2.3.4 2016年11月8日
7月8日 10:47:42 cztest カーネル: 00000000000000000 dd79fe633eacd853 ffff88103e743880 ffffffff81686ac3
7月8日 10:47:42 cztest カーネル: ffff88103e7438b8 ffffffff81085cb0 ffff8806d5c57800 ffff88010a4e6c80
7月8日 10:47:42 cztest カーネル: 0000000000000001 00000000f90e778c 00000000000000001 ffff88103e7438c8
7月8日 10:47:42 cztestカーネル: コールトレース:
7月8日 10:47:42 cztestカーネル: <IRQ> [<ffffffff81686ac3>] dump_stack+0x19/0x1b
7月8日 10:47:42 cztestカーネル: [<ffffffff81085cb0>] warn_slowpath_common+0x70/0xb0
7月8日 10:47:42 cztestカーネル: [<ffffffff81085dfa>] warn_slowpath_null+0x1a/0x20
7月8日 10:47:42 cztestカーネル: [<ffffffff815c3663>] tcp_mark_head_lost+0x113/0x290
7月8日 10:47:42 cztestカーネル: [<ffffffff815c3f47>] tcp_update_scoreboard+0x67/0x80
7月8日 10:47:42 cztestカーネル: [<ffffffff815c964d>] tcp_fastretrans_alert+0x6dd/0xb50
7月8日 10:47:42 cztestカーネル: [<ffffffff815ca49d>] tcp_ack+0x8dd/0x12e0
7月8日 10:47:42 cztestカーネル: [<ffffffff815cb3a8>] tcp_rcv_established+0x118/0x760
7月8日 10:47:42 cztestカーネル: [<ffffffff815d5f8a>] tcp_v4_do_rcv+0x10a/0x340
7月8日 10:47:42 cztestカーネル: [<ffffffff812a84c6>] ? security_sock_rcv_skb+0x16/0x20
7月8日 10:47:42 cztestカーネル: [<ffffffff815d76d9>] tcp_v4_rcv+0x799/0x9a0
7月8日 10:47:42 cztestカーネル: [<ffffffffa0140036>] ? iptable_filter_hook+0x36/​​0x80 [iptable_filter]
7月8日 10:47:42 cztestカーネル: [<ffffffff815b1094>] ip_local_deliver_finish+0xb4/0x1f0
7月8日 10:47:42 cztestカーネル: [<ffffffff815b1379>] ip_local_deliver+0x59/0xd0
7月8日 10:47:42 cztestカーネル: [<ffffffff815b0fe0>] ? ip_rcv_finish+0x350/0x350
7月8日 10:47:42 cztestカーネル: [<ffffffff815b0d1a>] ip_rcv_finish+0x8a/0x350
7月8日 10:47:42 cztestカーネル: [<ffffffff815b16a6>] ip_rcv+0x2b6/0x410
7月8日 10:47:42 cztestカーネル: [<ffffffff815700d2>] __netif_receive_skb_core+0x582/0x800
7月8日 10:47:42 cztestカーネル: [<ffffffff815dc694>] ? tcp4_gro_receive+0x134/0x1b0
7月8日 10:47:42 cztestカーネル: [<ffffffff811dc861>] ? __slab_free+0x81/0x2f0
7月8日 10:47:42 cztestカーネル: [<ffffffff81570368>] __netif_receive_skb+0x18/0x60
7月8日 10:47:42 cztestカーネル: [<ffffffff815703f0>] netif_receive_skb_internal+0x40/0xc0
7月8日 10:47:42 cztestカーネル: [<ffffffff81571578>] napi_gro_receive+0xd8/0x130
7月8日 10:47:42 cztestカーネル: [<ffffffffa018b237>] igb_clean_rx_irq+0x387/0x700 [igb]
7月8日 10:47:42 cztestカーネル: [<ffffffff8155e862>] ? skb_release_data+0xf2/0x140
7月8日 10:47:42 cztestカーネル: [<ffffffffa018b933>] igb_poll+0x383/0x770 [igb]
7月8日 10:47:42 cztestカーネル: [<ffffffff815d3120>] ? tcp_write_timer_handler+0x200/0x200
7月8日 10:47:42 cztestカーネル: [<ffffffff81570c00>] net_rx_action+0x170/0x380
7月8日 10:47:42 cztestカーネル: [<ffffffff8108f63f>] __do_softirq+0xef/0x280
7月8日 10:47:42 cztestカーネル: [<ffffffff81698c1c>] call_softirq+0x1c/0x30
7月8日 10:47:42 cztestカーネル: [<ffffffff8102d365>] do_softirq+0x65/0xa0
7月8日 10:47:42 cztestカーネル: [<ffffffff8108f9d5>] irq_exit+0x115/0x120
7月8日 10:47:42 cztestカーネル: [<ffffffff816997b8>] do_IRQ+0x58/0xf0
7月8日 10:47:42 cztestカーネル: [<ffffffff8168e86d>] common_interrupt+0x6d/0x6d
7月8日 10:47:42 cztestカーネル: <EOI> [<ffffffff81514a22>] ? cpuidle_enter_state+0x52/0xc0
7月8日 10:47:42 cztestカーネル: [<ffffffff81514b69>] cpuidle_idle_call+0xd9/0x210
7月8日 10:47:42 cztestカーネル: [<ffffffff810350ee>] arch_cpu_idle+0xe/0x30
7月8日 10:47:42 cztestカーネル: [<ffffffff810e82a5>] cpu_startup_entry+0x245/0x290
7月8日 10:47:42 cztestカーネル: [<ffffffff8104f07a>] start_secondary+0x1ba/0x230
7月8日 10:47:42 cztestカーネル: ---[ トレース終了 6bc65b0c591c1794 ]---

ホスト環境は次のとおりです。

システム | Dell Inc.; PowerEdge R620;
プラットフォーム | Linux
カーネル | Centos 3.10.0-514.16.1.el7.x86_64
合計メモリ | 64G

処理命令

スタック印刷プロセスは、xfs アラーム処理に似ています。一般的なプロセスは、カーネルが sack および fack 機能をオンにした後、ネットワーク伝送中に必要な高速再送信と選択的再送信が、tcp_input.c ファイルの tcp_mark_head_lost 関数によって処理されることです。主に、伝送中に失われたパケットの数をマークします。以下に示すように、システムによって報告されるカーネル スタック情報は、tcp_mark_head_lost 関数の tcp_verify_left_out 関数呼び出しによってトリガーされます。

// ソース/include/net/tcp.h 

#define tcp_verify_left_out(tp) WARN_ON(tcp_left_out(tp) > tp->packets_out)

静的インライン符号なし int tcp_left_out(const struct tcp_sock *tp)
{
  tp->sacked_out + tp->lost_out を返します。
}

// ソース/include/asm-generic/bug.h 

#define __WARN() warn_slowpath_null(__FILE__, __LINE__)

#ifndef 警告オン
#define WARN_ON(条件) ({\
    __警告(); \
})
#終了



// ソース/net/ipv4/tcp_input.c

/* キューの先頭を損失としてマークすることで、上記のイベント「A」での損失を検出します。
 * FACKまたは非SACK(Reno)送信者の場合、最初の「パケット」セグメント数
 * は失われたとみなされます。RFC3517 SACKの場合、セグメントが失われたとみなされるのは、
 * 少なくともtp->reordering SACKedシーケンスが上に存在します。「パケット」とは
 * この制限に達する前に通過する最大の SACK セグメント数。
 */
静的 void tcp_mark_head_lost(構造体 sock *sk, int パケット, int mark_head)
{
  構造体 tcp_sock *tp = tcp_sk(sk);
  ....
  tcp_verify_left_out(tp); // dump_stack をトリガーする
}

...
静的 void tcp_update_scoreboard(構造体 sock *sk, int fast_rexmit)
{
  構造体 tcp_sock *tp = tcp_sk(sk);

  tcp_is_reno(tp) の場合 {
    tcp_mark_head_lost(sk, 1, 1);
  } そうでない場合 (tcp_is_fack(tp)) {
    int 失われた = tp->fackets_out - tp->reordering;
    (損失 <= 0)の場合
      失われた = 1;
    tcp_mark_head_lost(sk, 失われた, 0);
  } それ以外 {
    int sacked_upto = tp->sacked_out - tp->reordering;
    (sacked_upto >= 0)の場合
      tcp_mark_head_lost(sk, sacked_upto, 0);
    そうでない場合 (fast_rexmit)
      tcp_mark_head_lost(sk, 1, 1);
  }
}

redhat-536483 の説明によると、このエラー メッセージは通常、TCP バグによって発生し、カーネルが解放された TCP ソケット バッファー リストを使用するときにトリガーされる可能性があります。

根本的な原因
TCP カーネル ソケット バッファ リンク リストに関連する、解放後使用の問題です。したがって、これは TCP カーネル コードのバグです。このバグは TCP カーネル コードにありますが、複数の方法でトリガーされる可能性があります。NFS が原因でトリガーされる場合もありますし、アプリケーション (Java プロセスなど) が原因でトリガーされる場合もあります。

処理

カーネルのアップグレード

以下に示すように、RedHat はバージョン 3.10.0-520 で tcp_* 関連関数の解放後使用バグを修正した可能性があります。この問題を解決するには、アップグレードを試みることができます。
Centos 7.x の変更履歴

* 2016 年 11 月 3 日 (木) Rafael Aquini <[email protected]> [3.10.0-520.el7]
- [net] tcp: tcp_xmit_retransmit_queue() の解放後使用を修正 (Mateusz Guzik) [1379531] {CVE-2016-6828}

ファック/サック機能を無効にする

Red Hat ナレッジベースのドキュメントによると、tcp_mark_head_lost 関数は主に高速再送信と選択確認中に失われたパケットの数をマークするために使用されるため、この問題を回避するために fack/sack パラメータを一時的に無効にできる可能性があります。

sysctl -w net.ipv4.tcp_fack=0
sysctl -w net.ipv4.tcp_sack=0

まず 2 番目の方法を試してみて、問題が解決しない場合はカーネル バージョンのアップグレードを検討してください。

参照する

レッドハット-536483

バグ 1367091

CVE-2016-6828

カーネルコミット

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。

以下もご興味があるかもしれません:
  • Linux システムによって報告される xfs_vm_releasepage 警告問題に対処する方法

<<:  MySQL グリーン解凍バージョンのインストールと設定手順

>>:  Vue での mixin の応用について議論する

推薦する

CSS3 のテキストとフォントの新しい設定

テキストシャドウテキストシャドウ: 水平オフセット 垂直オフセット ぼかし色互換性: IE10+ &...

docker compose を使用してハーバープライベートウェアハウスをインストールする詳細なチュートリアル

概要港とは何ですか?英語の単語の意味は「港」です。 Harborはコンテナ(貨物)を保管するために使...

シームレスなカルーセル効果を実現するネイティブ js

参考までに、ネイティブjsでカルーセル効果(シームレススクロール)を実現しています。具体的な内容は以...

シンプルなタブバー切り替えケースを実現するJavaScript

この記事では、タブバーの切り替え効果を簡単に実現するためのJavaScriptの具体的なコードを参考...

jsのディープコピーを理解しましょう

目次js ディープコピーデータ保存方法浅いコピー/深いコピーとは何か一般的なディープコピーの実装1....

JavaScriptを使用してSMS認証コード間隔を送信する機能を実装する

多くのアプリやウェブサイトでは、ログインやアカウント登録の際にSMS認証コード1を送信する場所があり...

すべてのブラウザとの完全な互換性を実現するために最適なプリセットを選択してください

各ブラウザの select タグのプロパティと各ブラウザのサポートが多少異なるため、各ブラウザでの選...

コピー&ペーストはパッケージングの敵です

OO、デザイン パターン、および多くのオブジェクト指向の原則について話す前に、まず 1 つのことを習...

さまざまなSQL結合を簡単に学ぶ

SQL JOIN 句は、テーブル間の共通フィールドに基づいて 2 つ以上のテーブルの行を結合するため...

MySQLの一般クエリログとスロークエリログの分析

MySQL のログには、エラー ログ、バイナリ ログ、一般クエリ ログ、スロー クエリ ログなどが含...

VueのID認証管理とテナント管理の詳細な説明

目次概要ボタンレベルの権限アイデンティティ認証管理R/U 権限権限の更新テナント管理テナント切り替え...

Linux(中心OS7)は、Java Webプロジェクトの実行環境を構築するためにJDK、Tomcat、MySQLをインストールします。

1. JDKをインストールする1. 古いバージョンまたはシステム独自のJDKをアンインストールする...

ドロップダウンメニューを実装するためのネイティブ js

ドロップダウン メニューも実生活では非常に一般的です。実装に使用される js コードは、タブ選択やア...

英語のシングルクォーテーション「''」を含むSQLの記述の失敗について徹底解説

問題が発生しました。情報の編集をテストする際、編集した内容に一重引用符 (') が含まれてい...

HTML要素を非表示にするいくつかの方法

1. CSSを使用するコードをコピーコードは次のとおりです。スタイル="display:n...