linux系統(tǒng)報(bào)tcp_mark_head_lost錯(cuò)誤的處理方法
問題說明
近期一臺(tái)主機(jī)報(bào)以下 kernel 信息:
Jul 8 10:47:42 cztest kernel: ------------[ cut here ]------------ Jul 8 10:47:42 cztest kernel: WARNING: at net/ipv4/tcp_input.c:2269 tcp_mark_head_lost+0x113/0x290() Jul 8 10:47:42 cztest kernel: Modules linked in: 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 a megaraid_sas i2c_core fjes [last unloaded: ip_tables] Jul 8 10:47:42 cztest kernel: CPU: 10 PID: 0 Comm: swapper/10 Tainted: G W ------------ 3.10.0-514.16.1.el7.x86_64 #1 Jul 8 10:47:42 cztest kernel: Hardware name: Dell Inc. PowerEdge R630/02C2CP, BIOS 2.3.4 11/08/2016 Jul 8 10:47:42 cztest kernel: 0000000000000000 dd79fe633eacd853 ffff88103e743880 ffffffff81686ac3 Jul 8 10:47:42 cztest kernel: ffff88103e7438b8 ffffffff81085cb0 ffff8806d5c57800 ffff88010a4e6c80 Jul 8 10:47:42 cztest kernel: 0000000000000001 00000000f90e778c 0000000000000001 ffff88103e7438c8 Jul 8 10:47:42 cztest kernel: Call Trace: Jul 8 10:47:42 cztest kernel: <IRQ> [<ffffffff81686ac3>] dump_stack+0x19/0x1b Jul 8 10:47:42 cztest kernel: [<ffffffff81085cb0>] warn_slowpath_common+0x70/0xb0 Jul 8 10:47:42 cztest kernel: [<ffffffff81085dfa>] warn_slowpath_null+0x1a/0x20 Jul 8 10:47:42 cztest kernel: [<ffffffff815c3663>] tcp_mark_head_lost+0x113/0x290 Jul 8 10:47:42 cztest kernel: [<ffffffff815c3f47>] tcp_update_scoreboard+0x67/0x80 Jul 8 10:47:42 cztest kernel: [<ffffffff815c964d>] tcp_fastretrans_alert+0x6dd/0xb50 Jul 8 10:47:42 cztest kernel: [<ffffffff815ca49d>] tcp_ack+0x8dd/0x12e0 Jul 8 10:47:42 cztest kernel: [<ffffffff815cb3a8>] tcp_rcv_established+0x118/0x760 Jul 8 10:47:42 cztest kernel: [<ffffffff815d5f8a>] tcp_v4_do_rcv+0x10a/0x340 Jul 8 10:47:42 cztest kernel: [<ffffffff812a84c6>] ? security_sock_rcv_skb+0x16/0x20 Jul 8 10:47:42 cztest kernel: [<ffffffff815d76d9>] tcp_v4_rcv+0x799/0x9a0 Jul 8 10:47:42 cztest kernel: [<ffffffffa0140036>] ? iptable_filter_hook+0x36/0x80 [iptable_filter] Jul 8 10:47:42 cztest kernel: [<ffffffff815b1094>] ip_local_deliver_finish+0xb4/0x1f0 Jul 8 10:47:42 cztest kernel: [<ffffffff815b1379>] ip_local_deliver+0x59/0xd0 Jul 8 10:47:42 cztest kernel: [<ffffffff815b0fe0>] ? ip_rcv_finish+0x350/0x350 Jul 8 10:47:42 cztest kernel: [<ffffffff815b0d1a>] ip_rcv_finish+0x8a/0x350 Jul 8 10:47:42 cztest kernel: [<ffffffff815b16a6>] ip_rcv+0x2b6/0x410 Jul 8 10:47:42 cztest kernel: [<ffffffff815700d2>] __netif_receive_skb_core+0x582/0x800 Jul 8 10:47:42 cztest kernel: [<ffffffff815dc694>] ? tcp4_gro_receive+0x134/0x1b0 Jul 8 10:47:42 cztest kernel: [<ffffffff811dc861>] ? __slab_free+0x81/0x2f0 Jul 8 10:47:42 cztest kernel: [<ffffffff81570368>] __netif_receive_skb+0x18/0x60 Jul 8 10:47:42 cztest kernel: [<ffffffff815703f0>] netif_receive_skb_internal+0x40/0xc0 Jul 8 10:47:42 cztest kernel: [<ffffffff81571578>] napi_gro_receive+0xd8/0x130 Jul 8 10:47:42 cztest kernel: [<ffffffffa018b237>] igb_clean_rx_irq+0x387/0x700 [igb] Jul 8 10:47:42 cztest kernel: [<ffffffff8155e862>] ? skb_release_data+0xf2/0x140 Jul 8 10:47:42 cztest kernel: [<ffffffffa018b933>] igb_poll+0x383/0x770 [igb] Jul 8 10:47:42 cztest kernel: [<ffffffff815d3120>] ? tcp_write_timer_handler+0x200/0x200 Jul 8 10:47:42 cztest kernel: [<ffffffff81570c00>] net_rx_action+0x170/0x380 Jul 8 10:47:42 cztest kernel: [<ffffffff8108f63f>] __do_softirq+0xef/0x280 Jul 8 10:47:42 cztest kernel: [<ffffffff81698c1c>] call_softirq+0x1c/0x30 Jul 8 10:47:42 cztest kernel: [<ffffffff8102d365>] do_softirq+0x65/0xa0 Jul 8 10:47:42 cztest kernel: [<ffffffff8108f9d5>] irq_exit+0x115/0x120 Jul 8 10:47:42 cztest kernel: [<ffffffff816997b8>] do_IRQ+0x58/0xf0 Jul 8 10:47:42 cztest kernel: [<ffffffff8168e86d>] common_interrupt+0x6d/0x6d Jul 8 10:47:42 cztest kernel: <EOI> [<ffffffff81514a22>] ? cpuidle_enter_state+0x52/0xc0 Jul 8 10:47:42 cztest kernel: [<ffffffff81514b69>] cpuidle_idle_call+0xd9/0x210 Jul 8 10:47:42 cztest kernel: [<ffffffff810350ee>] arch_cpu_idle+0xe/0x30 Jul 8 10:47:42 cztest kernel: [<ffffffff810e82a5>] cpu_startup_entry+0x245/0x290 Jul 8 10:47:42 cztest kernel: [<ffffffff8104f07a>] start_secondary+0x1ba/0x230 Jul 8 10:47:42 cztest kernel: ---[ end trace 6bc65b0c591c1794 ]---
主機(jī)環(huán)境如下:
System | Dell Inc.; PowerEdge R620;
Platform | Linux
Kernel | Centos 3.10.0-514.16.1.el7.x86_64
Total Memory | 64G
處理說明
堆棧的打印過程類似于xfs 告警處理 , 大致的過程為內(nèi)核開啟 sack, fack 功能后, 網(wǎng)絡(luò)傳輸過程中需要的快速重傳和選擇性重傳會(huì)通過 tcp_input.c 文件的 tcp_mark_head_lost 函數(shù)進(jìn)行處理, 其主要標(biāo)記傳輸過程中丟失的報(bào)文的數(shù)量, 如下所示, 系統(tǒng)報(bào)的 kernel 堆棧信息由 tcp_mark_head_lost 函數(shù)中的 tcp_verify_left_out 函數(shù)調(diào)用觸發(fā):
// source/include/net/tcp.h
#define tcp_verify_left_out(tp) WARN_ON(tcp_left_out(tp) > tp->packets_out)
static inline unsigned int tcp_left_out(const struct tcp_sock *tp)
{
return tp->sacked_out + tp->lost_out;
}
// source/include/asm-generic/bug.h
#define __WARN() warn_slowpath_null(__FILE__, __LINE__)
#ifndef WARN_ON
#define WARN_ON(condition) ({ \
__WARN(); \
})
#endif
// source/net/ipv4/tcp_input.c
/* Detect loss in event "A" above by marking head of queue up as lost.
* For FACK or non-SACK(Reno) senders, the first "packets" number of segments
* are considered lost. For RFC3517 SACK, a segment is considered lost if it
* has at least tp->reordering SACKed seqments above it; "packets" refers to
* the maximum SACKed segments to pass before reaching this limit.
*/
static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
{
struct tcp_sock *tp = tcp_sk(sk);
....
tcp_verify_left_out(tp); // trigger dump_stack
}
...
static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
{
struct tcp_sock *tp = tcp_sk(sk);
if (tcp_is_reno(tp)) {
tcp_mark_head_lost(sk, 1, 1);
} else if (tcp_is_fack(tp)) {
int lost = tp->fackets_out - tp->reordering;
if (lost <= 0)
lost = 1;
tcp_mark_head_lost(sk, lost, 0);
} else {
int sacked_upto = tp->sacked_out - tp->reordering;
if (sacked_upto >= 0)
tcp_mark_head_lost(sk, sacked_upto, 0);
else if (fast_rexmit)
tcp_mark_head_lost(sk, 1, 1);
}
}
從 redhat-536483 中描述的來看, 這種錯(cuò)誤信息一般是 tcp bug 引起的, 在內(nèi)核使用已經(jīng)釋放的 tcp socket buffer 鏈表的時(shí)候就可能觸發(fā):
Root Cause
A use after free issue related to the TCP kernel socket buffer linked list. Thus it is a bug in the TCP kernel code. Although the bug is in TCP kernel code, but it could get triggered in multiple ways. It could get triggered due to NFS, or due to even an application(say java process).
處理方式
升級(jí) kernel
如下所示, redhat 在 3.10.0-520 版本可能修復(fù)了 tcp_* 相關(guān)函數(shù)的 use after free 相關(guān)的 bug, 可以嘗試升級(jí)處理該問題:
centos 7.x changelog
* Thu Nov 03 2016 Rafael Aquini <aquini@redhat.com> [3.10.0-520.el7]
- [net] tcp: fix use after free in tcp_xmit_retransmit_queue() (Mateusz Guzik) [1379531] {CVE-2016-6828}
關(guān)閉 fack/sack 功能
從紅帽知識(shí)庫的文檔來看, tcp_mark_head_lost 函數(shù)主要用來標(biāo)記快速重傳和選擇確認(rèn)的過程中丟失的報(bào)文數(shù)量, 所以或許可以臨時(shí)關(guān)閉 fack/sack 參數(shù)避免該問題的出現(xiàn):
sysctl -w net.ipv4.tcp_fack=0 sysctl -w net.ipv4.tcp_sack=0
可以優(yōu)先嘗試第二種方式, 如果還有問題再考慮升級(jí) kernel 版本.
參考
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
linux根據(jù)進(jìn)程號(hào)PID查找啟動(dòng)程序的全路徑
工作環(huán)境中遇到網(wǎng)絡(luò)不正常,檢測(cè)是某服務(wù)器異常往外發(fā)送數(shù)據(jù)包,使用netstat命令查看,發(fā)現(xiàn)有程序。這篇文章主要介紹了linux根據(jù)進(jìn)程號(hào)PID查找啟動(dòng)程序的全路徑,需要的朋友可以參考下2019-08-08
CentOS 7.3配置Nginx虛擬主機(jī)的方法步驟
這篇文章主要介紹了CentOS 7.3配置Nginx虛擬主機(jī)的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02
Linux實(shí)現(xiàn)數(shù)據(jù)庫定時(shí)備份方式
這篇文章主要介紹了Linux實(shí)現(xiàn)數(shù)據(jù)庫定時(shí)備份方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
CentOS 8設(shè)置自動(dòng)更新的完整步驟
這篇文章主要給大家介紹了關(guān)于CentOS 8設(shè)置自動(dòng)更新的完整步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用CentOS 8具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
apache將不帶www域名301重定向到帶www的域名的配置方法
這篇文章主要介紹了apache將不帶www域名301重定向到帶www的域名的配置方法,需要的朋友可以參考下2014-04-04
Centos7 mysql數(shù)據(jù)庫安裝及配置實(shí)現(xiàn)教程
這篇文章主要介紹了Centos7 mysql數(shù)據(jù)庫安裝及配置實(shí)現(xiàn)教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
CentOS 7 搭建ntp時(shí)鐘服務(wù)器的步驟詳解
架設(shè)NTP服務(wù)器,是個(gè)相對(duì)比較簡(jiǎn)單的事情, 架設(shè)NTP服務(wù)器目的就是使各個(gè)工作站的時(shí)間統(tǒng)一,下面這篇文章主要給大家介紹了CentOS 7中搭建ntp時(shí)鐘服務(wù)器的步驟,需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。2017-01-01
linux文件系統(tǒng)調(diào)整大小的方法(linux調(diào)整分區(qū)大小)
本文歸納了在不破快文件系統(tǒng)數(shù)據(jù)的前提下對(duì)文件系統(tǒng)大小進(jìn)行調(diào)整的方法.這里采用的是"拆東墻, 補(bǔ)西墻"的方法, 當(dāng)然, 如果你的磁盤中有未分區(qū)的空閑空間, 你就不用減小某個(gè)分區(qū)的空間了2014-01-01

