LINUX内核故障问题之SKB DROP

   关键词

  • Red Hat Enterprise Linux (RHEL) 7.6
  • SKB linearization failed
  • vm.min_free_kbytes

一、问题现象 

一台业务主机dmesg 日志中频繁有以下报错:

[qede_ start_ xmit :1289(p1p2)]SKB linearization failed - silently dropping this SKB。

二、问题分析

1、基础概念

Packet:通过网卡收发的报文,包括链路层、网络层、传输层的协议头和携带的数据

Data Buffer:用于存储 packet 的内存空间

SKB:struct sk_buffer 的简写

Struct sk_buffer (SKB)是 linux TCP/IP stack 中,用于管理Data Buffer的结构。Sk_buffer 在数据包的发送和接收中起着重要的作用。为了提高网络处理的性能,应尽量避免数据包的拷贝。Linux 内核开发者们在设计 sk_buffer 结构的时候,充分考虑到这一点。目前 Linux 协议栈在接收数据的时候,需要拷贝两次:数据包进入网卡驱动后拷贝一次,从内核空间递交给用户空间的应用时再拷贝一次。

2、源码查错

The qede_start_xmit() 源码的 1287-1290行指向了本次报错内容

1256 /* Main transmit function */

1257 netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev)

1258 {

1259         struct qede_dev *edev = netdev_priv(ndev);

1260         struct netdev_queue *netdev_txq;

1261         struct qede_tx_queue *txq;

1262         struct eth_tx_1st_bd *first_bd;

1263         struct eth_tx_2nd_bd *second_bd = NULL;

1264         struct eth_tx_3rd_bd *third_bd = NULL;

1265         struct eth_tx_bd *tx_data_bd = NULL;

1266         u16 txq_index, val = 0;

1267         u8 nbd = 0;

1268         dma_addr_t mapping;

1269         int rc, frag_idx = 0, ipv6_ext = 0;

1270         u8 xmit_type;

1271         u16 idx;

1272         u16 hlen;

1273         bool data_split = false;

1274                                     

1275         /* Get tx-queue context and netdev index */

1276         txq_index = skb_get_queue_mapping(skb);

1277         WARN_ON(txq_index >= QEDE_TSS_COUNT(edev));

1278         txq = edev->fp_array[edev->fp_num_rx + txq_index].txq;

1279         netdev_txq = netdev_get_tx_queue(ndev, txq_index);

1280                        

1281         WARN_ON(qed_chain_get_elem_left(&txq->tx_pbl) < (MAX_SKB_FRAGS + 1));

1282         

1283         xmit_type = qede_xmit_type(skb, &ipv6_ext);

1284

1285 #if ((MAX_SKB_FRAGS + 2) > ETH_TX_MAX_BDS_PER_NON_LSO_PACKET)

1286         if (qede_pkt_req_lin(skb, xmit_type)) {

>1287                 if (skb_linearize(skb)) {

>1288                         DP_NOTICE(edev,

>1289                                   "SKB linearization failed - silently dropping this SKB\n");

>1290                         dev_kfree_skb_any(skb);

1291                         return NETDEV_TX_OK;

1292                 }

1293         }

1294 #endif

 从qede_start_xmit() 源码可以看到drop发生在skb_linearize() 函数
继续看skb_linearize()函数说明了和内存有关

2925 /**

2926  *      skb_linearize - convert paged skb to linear one

2927  *      @skb: buffer to linarize

2928  *      

2929  *      If there is no free memory -ENOMEM is returned, otherwise zero

2930  *      is returned and the old skb data released.

2931  */

2932 static inline int skb_linearize(struct sk_buff *skb)

2933 {

2934         return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;

2935 }

2920 static inline int __skb_linearize(struct sk_buff *skb)

2921 {                                   

2922         return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;

2923 }    

__pskb_pull_tail 说明了skb与buffer reallocate有关,怀疑最小KB数(vm.min_free_kbytes)较低导致用于存储 packet 的内存空间不足,出现丢失SKB情况。

1654 /**                                 

1655  *      __pskb_pull_tail - advance tail of skb header

1656  *      @skb: buffer to reallocate

1657  *      @delta: number of bytes to advance tail

1658  *      

1659  *      The function makes a sense only on a fragmented &sk_buff,

1660  *      it expands header moving its tail forward and copying necessary

1661  *      data from fragmented part.

1662  *      

1663  *      &sk_buff MUST have reference count of 1.

1664  *

1665  *      Returns %NULL (and &sk_buff does not change) if pull failed

1666  *      or value of new tail of skb in the case of success.

1667  *

1668  *      All the pointers pointing into skb header may change and must be

1669  *      reloaded after call to this function.

1670  */

1671

1672 /* Moves tail of skb head forward, copying data from fragmented part,

1673  * when it is necessary.

1674  * 1. It may fail due to malloc failure.

1675  * 2. It may change skb pointers.

1676  *

1677  * It is pretty complicated. Luckily, it is called only in exceptional cases.

1678  */

1679 void *__pskb_pull_tail(struct sk_buff *skb, int delta)

三、处理过程

vm.min_free_kbytes参数调优

什么是vm.min_free_kbytes?

官方释义是:这用于强制 Linux VM 保持最小数量的可用千字节。VM 使用这个数字来计算系统中每个 lowmem 区域的 watermark[WMARK_MIN] 值。每个 lowmem 区域都会根据其大小按比例获得一些保留的空闲页面。满足 PF_MEMALLOC 分配需要一些最小的内存量;如果您将其设置为低于 1024KB,您的系统将被巧妙地破坏,并且在高负载下容易死锁。设置得太高会立即 OOM 你的机器。

 所以设定这个参数时请小心,因为该值过低和过高都有问题。min_free_kbytes太低可防止系统重新利用内存。这可导致系统挂起并让 OOM 杀死多个进程。但将这个参数值设定太高(占系统总内存的 5-10%)会让您的系统很快会内存不足。Linux 的设计是使用所有可用 RAM 缓存文件系统数据。设定高min_free_kbytes值的结果是在该系统中花费太多时间重新利用内存。

min_free_kbytes这个参数不仅仅是影响Linux内存回收中的water_mark(尤其是direct reclaim回收方式,Linux有两种内存回收方式:一种是kswapd后台回收,在早期的内核版本kswapd是周期性唤醒,因此又叫周期回收,但是没有必要,所以在现代Linux内核版本中已经不再是周期唤醒,而是在分配内存的时候会基于zone的water_mark来唤醒做后台回收内存;另一种就是direct reclaim,这种又叫同步回收,因为此时系统可用内存到了water_mark_min,意味着系统内存非常紧张,所以allocate page申请内存的进程会被阻塞直到回收可用内存。当然,如果经历了内存回收流程仍旧没有回收到足够的内存,那么在allocate page函数中会走out_of_memory函数的oom流程),还会影响系统的可用内存available memory。

设置了/proc/sys/vm/min_free_kbytes之后,通过water_mark_min计算water_mark_low和water_mark_high的默认公式:

watermark[min] = per_zone_min_free_pages (min_free_kbytes换算为page单位)

watermark[low] = watermark[min] * 5 / 4

watermark[high] = watermark[min] * 3 / 2

min 和 low的区别:

1、min下的内存是保留给内核使用的;当到达min,会触发内存的direct reclaim
2、low水位比min高一些,当内存可用量小于low的时候,会触发 kswapd回收内存,当kswapd慢慢的将内存 回收到high水位,就开始继续睡眠

内存回收方式有两种,主要对应low ,min

1、direct reclaim : 触发min水位线时执行
2、kswapd reclaim : 触发low水位线时执行

四、经验总结

  如果发现系统因为direct reclaim而导致卡顿、延迟(此时IO相关的指标会比较异常,并且系统负载会增加),那么就需要调高min_free_kbytes,可以通过sar -B命令观测pgscand和%vmeff来慢慢调整。这是为什么呢?因为min=min_free_kbytes,low=1.25min,high=1.5min,到low会唤醒kswapd做内存的后台回收,这时候即便是刷脏页、swap out等虽然会消耗磁盘io性能,但是绝大多数情况下不会影响进程;但是到了min,所有此时申请物理内存的进程都会被阻塞做direct reclaim,直到回收满足申请的内存。如果min_free_kbytes太小,那么就意味着kswapd后台回收启动没多久就进入direct reclaim,如果能把两者的时间间隔拉长,让后台回收有充分的时间来回收内存,那么就会降低direct reclaim的影响。

对于线上128G的内存的机器,可以考虑将min设置为512M左右。因为太大了,可能会导致内存的浪费;如果只有40G的物理机,更不要考虑把min设置超过1G了,这样会导致频繁的触发内存回收;具体优化也要根据业务来看。

关键是在于调整内存的内核参数的时候, 调大的风险远大于调小的风险! 如果有人想将vm.min_free_kbytes 调大,千万要注意当前的水位,如果一旦调大vm.min_free_kbytes 立刻触发direct reclaim,可能会导致机器hang住,ping的通,ssh不上,影响业务。hang住的原因是当vm.min_free_kbytes 是512M的时候, free只有1G,此时正常运行,如果调大vm.min_free_kbytes 到5G,将会direct reclaim失败。  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/301668.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爆肝整理,性能测试-交易系统升级压测思路,一篇不走弯路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 交易系统性能是体…

【性能测试】JMeter分布式测试及其详细步骤

性能测试概要 性能测试是软件测试中的一种&#xff0c;它可以衡量系统的稳定性、扩展性、可靠性、速度和资源使用。它可以发现性能瓶颈&#xff0c;确保能满足业务需求。很多系统都需要做性能测试&#xff0c;如Web应用、数据库和操作系统等。 性能测试种类非常多&#xff0c…

QT应用篇:QT自定义最小化托盘显示和操作

将应用程序最小化到托盘任务栏中,可以使用Qt框架中的QSystemTrayIcon类。该类允许应用程序在关闭窗口后最小化到系统托盘,保持在后台运行,同时可以显示应用程序图标、添加右键菜单功能以及发送消息通知等。通过学习这些技术,能够为自己的Qt应用程序增加更多的交互性和便利性…

C++ TinyWebserver 部署到Linux下,并运行(使用的是Vmware的虚拟机运行Ubuntu20.04)

环境&#xff1a;VmwareUbuntu20.04 1. Tinyweb server项目地址&#xff1a;https://github.com/qinguoyi/TinyWebServer 2. 首先进行mysql5.7的安装&#xff1a; 参考教程 &#xff1a; Ubuntu20.04安装MySQL5.7-实测3种方法&#xff08;保姆级教程&#xff09;&#xff1a;…

《软件项目接口安全设计规范》

1.token授权机制 2.https传输加密 3.接口调用防滥用 4.日志审计里监控 5.开发测试环境隔离&#xff0c;脱敏处理 6.数据库运维监控审计 软件全套文档&#xff1a;软件开发全套资料-CSDN博客

Python武器库开发-武器库篇之C段扫描器开发(四十三)

Python武器库开发-武器库篇之C段扫描器开发(四十三) 在我们进行渗透过程中的信息收集的步骤时&#xff0c;收集资产目标的C段也是非常重要的一部分。 C段是指互联网中的一类IP地址。IP地址是互联网上每台设备的唯一标识符。IP地址由一系列数字组成&#xff0c;通常以点分十进…

Pytorch种torch.cat与torch.stack的区别

torch.cat 和 torch.stack 是 PyTorch 中用于拼接张量的两个不同的函数&#xff0c;它们的主要区别在于拼接的方式和创建的维度。 torch.cat&#xff1a; 拼接方式&#xff1a; torch.cat 是按照给定的维度&#xff08;dim 参数&#xff09;将多个张量沿着该维度拼接。在拼接的…

科技云报道:“存算一体”是大模型AI芯片的破局关键?

科技云报道原创。 在AI发展历史上&#xff0c;曾有两次“圣杯时刻”。 第一次发生在2012年10月&#xff0c;卷积神经网络&#xff08;CNN&#xff09;算法凭借比人眼识别更低的错误率&#xff0c;打开了计算机视觉的应用盛世。 第二次是2016年3月&#xff0c;DeepMind研发的…

Python 面向对象知识点补充

Python 面向对象知识点补充 【一】Mixins机制 【1】概念 Mixins&#xff1a;是一种在面向对象编程中&#xff0c;通过组合多个类的特称来创建一个新类的技术核心机制&#xff1a;就是在多继承的背景下尽可能地提升多继承的可读性通过命名规范来满足人的思维习惯&#xff08;…

【微机原理与接口技术】期末模拟卷(2)

有不会的题可以后台问我的哦&#xff0c;看见了就会回。 本文章主要是微机的模拟卷&#xff0c;最后祝大家期末心想事成 1、微处理器为8086数据总线和地址总线为 ()位 A.16 16 B.16 32 C.16 20 D.32 32 8086是16位寄存器&#xff0c;即需要16位数据线 2、微型计算机硬件系…

小程序实现绘制图片 保存到手机

HTML <template><view><canvas canvas-id"myCanvas" :style"{height:380px,width:wWidthpx,background:#FFFFFF}"></canvas><view class"textCenter"><button click"saveCanvas">保存图片</b…

uniapp获取手机当前信息及应用版本

appVersion 是app端查询的数据信息 appWgtVersion 是浏览器端查询的数据信息 onLoad() {const systemInfo uni.getSystemInfoSync();console.log(systemInfo);// #ifdef H5const uniAppVersion systemInfo.appVersion;// #endif// #ifndef H5const uniAppVersion systemIn…

报文大小限制、请求体类型总结

文章目录 1. 各节点请求体有无限制1.1 http协议1.2 TCP/IP层限制1.3 浏览器1.4 nginx1.5 gateway1.6 tomcat1.7 springboot1.8 内存、磁盘处理不了一切白搭 2. 请求体类型2.1 application/x-www-form-urlencoded2.2 multipart/form-data2.3 application/json2.4 text/plain2.5 …

从贝索斯、英伟达们手里又融了7000万美元,Perplexity还真奔着取代Google去了

AI应用千千万&#xff0c;到底哪些才真正值得你花钱花时间&#xff1f; 对于这个问题&#xff0c;埃森哲人工智能高级顾问、《哈佛商业评论》播客频道主持人Azeem Azhar给出的答案是&#xff1a;“如果必须选择一个&#xff0c;我不会选ChatGPT或Claude&#xff0c;而是Perple…

神经网络的核心:简单易懂理解 PyTorch 非线性激活函数

目录 torch.nn子函数非线性激活详解 nn.Softmin Softmin 函数简介 函数工作原理 参数详解 使用技巧与注意事项 示例代码 nn.Softmax Softmax 函数简介 函数工作原理 参数详解 使用技巧与注意事项 示例代码 nn.Softmax2d Softmax2d 函数简介 函数工作原理 输入…

数据摆渡会遇到哪些风险?要如何应对?

数据摆渡&#xff08;Data Shuttle&#xff09;是一种在不同网络环境之间安全、可控地传输数据的过程。在企业环境中&#xff0c;这通常涉及到将数据从内部网络&#xff08;内网&#xff09;传输到外部网络&#xff08;外网&#xff09;&#xff0c;或者在多个隔离的内部网络之…

安恒2023全球高级威胁态势研究报告(网盘下载)

《2023全球高级威胁态势研究报告》 2023 年&#xff0c;一系列新兴威胁的不断涌现&#xff0c;使得网络安全面临着前所未有的挑战。过去一年&#xff0c;我们目睹了地缘政治动荡、科技进步和人类活动的交织&#xff0c;进一步深刻地塑造了数字时代的未来。 在此背景下&#xff…

java 体育明星管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web 体育明星管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…

3.2 MAPPING THREADS TO MULTIDIMENSIONAL DATA

1D、2D或3D线程组织的选择通常基于数据的性质。图片是2D像素阵列。使用由2D块组成的2D网格通常可以方便地处理图片中的像素。图3.2显示了处理7662图片P的这种安排&#xff08;水平或x方向为76像素&#xff0c;垂直或y方向为62像素&#xff09;。假设我们决定使用16 x 16块&…

MyBatis实战指南(一):从概念到特点,助你快速上手,提升开发效率!

嗨~ 今天的你过得还好吗&#xff1f; 如果命运是世界上最烂的编剧 你就要争取做你人生最好的演员 &#x1f31e; - 2024.01.08 - MyBatis是一个优秀的持久层框架&#xff0c;它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取…