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 の応用について議論する

推薦する

vue の v-for ディレクティブはリストのレンダリングを完了します

目次1. リストの走査2. Vueにおけるキーの役割3. リストフィルタリングこの記事では、Vue ...

CSS3 とテーブルタグを使用して円軌道アニメーションを実装するためのサンプルコード

html: 実際には、テーブルタグに従っていくつかの実線の円 div を正六角形に配置し、div コ...

MySQL データのバックアップと復元のサンプル コード

1. データのバックアップ1. mysqldumpコマンドを使用してバックアップするmysqldum...

Vue.jsは画像切り替え機能を実装する

この記事では、画像切り替え機能を実装するためのVue.jsの具体的なコードを参考までに共有します。具...

Vue Element-ui フォーム検証ルールの実装

目次1. はじめに2. ルール検証の入力モード2.1 サンプルコード2.2、フォーム項目2.3. 小...

MySQL テーブル フィールドの時間設定のデフォルト値

アプリケーションシナリオデータ テーブルでは、アプリケーションは各データがいつ作成されたかを記録する...

HTMLはフォームタグを使用して登録ページのサンプルコードを実装します。

ケースの説明: - ページ効果を実現するためにテーブルを使用する- ハイパーリンクを機能させたくない...

MySQLデータベースにパスワードを入力した後にフラッシュバックする問題の解決策

パスワード入力後にMySQLデータベースがクラッシュする問題と解決策1 ケースの説明最近、基本的な機...

CSSポジションの5つの異なる値の使い方の詳細な説明

位置プロパティposition プロパティは、要素に使用する配置方法のタイプ (静的、相対的、固定、...

MySQL の int、char、varchar のパフォーマンスを比較する

インターネットには、真実のように見える「噂」がたくさんあります。もちろん、悪意のあるものではありませ...

Nginx リクエスト制限の設定方法

Nginx は、多くの優れた機能を備えた強力で高性能な Web およびリバース プロキシ サーバーで...

VUE + OPENLAYERSがリアルタイムポジショニング機能を実現

目次序文1. ラベルスタイルを定義する2. GeoJSONデータのシミュレーション3. Vercto...

altとtitleの違いの詳しい説明

これら 2 つの属性はよく使用されますが、その違いはまとめられていません。それでは、その使い方をまと...

vue2 vue3 での Echarts の詳細な使用方法

目次1. インストール2. vue2でEchartsを使用するmain.jsファイル内コンテナが与え...

MySQLチュートリアルではストアドプロシージャを徹底的に理解します

目次1. ストアドプロシージャに関連する概念2. ストアドプロシージャの使用1) ストアドプロシージ...