1.问题环境基本信息
系统环境
物理机 / 虚拟机 / 云 / 容器:物理机
网络环境
外网 / 私有网络 / 无网络:私有网络
硬件环境
机型:Inspur CS5280H/CS5280H
处理器:Hygo
整机类型 / 架构:X86
软件环境
具体操作系统版本:V10-SP2-Server-0524
内核版本:4.19.90-24.4.v2101.ky10.x86_64
2. 问题描述
三台物理服务器异常重启,通过分析 messages 日志,主要内容是 audit 内存泄漏的输出,通过查看 sar。
日志查看内存空间还有剩余,查看 panic_on_oom 值是 0 。根据以上方式查看了三台机器的 sosreport ,结果都是相似的。目前的排查思路是 audit 占用内存导致的系统重启,但正常情况内存忽然升高 sar 没有记录内存不足,也不会导致系统重启,而应该是夯住。从 messages 日志中未发现有其他记录会导致系统重启。
问题截图
strace 打印 rsync –delete 命令执行的信息
3.问题分析
分析vmcore-dmesg.txt app0 5机器的vmcore-dmesg.txt
查看内核源码,可见split_swap_cluster函数原型如下,问题出在mm/swapfile.c的296行,调用的是函数 static inline void cluster_clear_huge(struct swap_cluster_info *info) ,由于是inline,所以被嵌入到split_swap_cluster。
分析cluster_clear_huge(struct swap_cluster_info *info)的函数参数结构体structswap_cluster_info,可见flags在swap_cluster_info中的偏移正好是7 ,如果cluster_clear_huge函数参数info为NULL,则info->flags正好为7。
crash> struct swap_cluster_info -ostruct swap_cluster_info {
[0] spinlock_t lock;
[4] unsigned int data : 24;
[7] unsigned int flags : 8;
}
SIZE: 8
查找网上资料,可见对该问题进行了修复 https://lkml.iu.edu/hypermail/linux/kernel/2009.2/09555.html ,需要cluster_clear_huge函数中对函数参数info进行非NULL判断。
4.问题根因如内核补丁
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/comm it/?h=linux-4.19.y&id=c4f9c701f9b44299e6adbc58d1a4bb2c40383494
查看hdp app 09机器的vmcore-dmesg.txt 和 hdpapp18机器的vmcore-dmesg.txt,堆栈打印相似都是RIP: 0010:split_swap_cluster+0x47/0x60, unable to handle kernel NULL pointer dereference at 0000000000000007,是同一个问题。
5.问题小结
static inline void cluster_clear_huge(struct swap_cluster_info *info) 函数需要对info进行非NULL判断,才能对info->flag进行赋值,否则如果info为NULL的时候,会触发空指针。
参考链接:
1、https://lkml.iu.edu/hypermail/linux/kernel/2009.2/09555.html
2、 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.19.y&;id=c4f9c701f9b44299e6adbc58d1a4bb2c40383494
3、https://access.redhat.com/solutions/5830301