网站更新前知道内容青岛官网优化
检查麒麟系统 /var/log/dmesg 、var/crash/vmcore /var/log/messages,发现以下信息
1、[10416833.187406] Tasks state (memory values in pages):
标记内存任务状态信息的开始,后续会列出各进程的内存使用等状态数据(以页为单位统计) ,用于排查内存相关问题时,查看系统中进程的内存占用、分配等情况。
2、[10416833.187438] Out of memory and no killable processes...
3、[10416833.187440] Kernel panic - not syncing: System is deadlocked on memory
Out of memory and no killable processes...
:表示系统发生内存耗尽,且没有可被内核杀死(释放内存)的进程。通常内核在内存不足时,会尝试杀掉一些低优先级进程回收内存,这里连可杀进程都没有,说明内存紧张到极致。
Kernel panic - not syncing: System is deadlocked on memory
:触发内核崩溃(Kernel panic) ,原因是 “系统因内存出现死锁” 。内存死锁意味着内存分配、回收等机制陷入相互等待的僵局,系统无法正常调配内存资源,严重到让内核无法继续稳定运行,只能抛出崩溃信息。
4、[10416833.191763] CPU: 3 PID: 1 Comm: systemd Kdump: loaded Tainted: G OEL 4.19.90-23.48.v2101.ky10.x86_64 #1
- 指明崩溃发生时,涉及的
CPU
核心是 3 号,进程PID
为 1(这里是systemd
进程,它是系统初始化和服务管理的关键进程 ),还提到Kdump
已加载(用于内核崩溃时转储内存等调试信息)、内核 “tainted” 状态(表示内核可能被非官方模块修改等,影响调试纯净度 ),以及内核版本等信息。
5、检查messages 文件
在触发OOM之前内核已经在频繁出现软锁告警,grep "soft lockup" /var/log/messages
6、软死锁的检测原理看门狗中断处理函数中当前的时间减去上一次发生进程调度的时间如果大于20S,就会触发软死锁,所以这个时间是大于20S的,且看门狗定时器中断20/5=4s一次,所以触发软死锁的时间在20s到24s之间都有可能。
7、排查分析
使用4.19.90-23.40内核版本未出现过此问题,安装补丁后,发现虚拟网卡驱动在4.19.90-23.42版本合入一个上游补丁
补丁链接:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=31c03aef9bc22a64a8324d650ca4198819ef3a33),该补丁启用了napi_tx功能。
8、结论
1,内核panic是因为内存不足触发OOM,但是之前内核日志中已经频繁在报软锁告警,因此软锁告警才是问题的根本原因。
2,应用进程通过系统调用执行tpacket_snd函数发包,底层virtio_net网卡驱动未能将发送完成的skb数据进行释放清理,pending_refcnt计数没有清零,导致CPU在tpacket_snd函数do-while循环中无法退出,触发软锁告警。
3,在23.42版本之上的内核中,开启了napi_tx,tpacket_snd函数发送数据包,只能在软中断中执行tpacket_destruct_skb对pending_refcnt减1,在这之前CPU会陷入do-whlie循环中,而循环退出的条件又只能在软中断处理中去执行,刚好软中断也是在同一个CPU上,而且对应的ksoftirqd进程又被调度唤醒(实际得不到执行),在硬中断irq_exit中也无法执行软中断处理,即此CPU上的软中断永远得不到调度执行了,从而就卡死在这里了。
9、解决方法
方案1:后续在新版本内核中撤掉使能napi_tx的补丁,升级到新版本系统内核解决。
方案2:更改应用发包模式,从堵塞改为非堵塞。
加点 非相关知识
KVM、QEMU和Libvirt三者之间的关系
在虚拟化技术中,KVM、QEMU和Libvirt是三个重要的组件,它们各自承担不同的角色,并相互协作实现完整的虚拟化解决方案。
1、KVM(Kernel-based Virtual Machine)是Linux内核中的一个模块,它利用硬件辅助虚拟化技术(如Intel VT和AMD-V)实现CPU和内存的虚拟化。KVM通过/dev/kvm接口提供虚拟化功能,用户态程序可以通过ioctl函数访问这个接口
2、QEMU是一个开源的模拟器和虚拟机管理程序,它可以模拟各种硬件设备,如CPU、网卡和磁盘等。QEMU与KVM结合使用时,QEMU负责模拟I/O设备,而KVM负责CPU和内存的虚拟化。这种组合被称为QEMU-KVM,它能够实现高性能的虚拟化,因为KVM直接利用硬件虚拟化技术,而QEMU则处理其他设备的模拟。
3、Libvirt是一个开源的虚拟化管理工具和API,它提供了对KVM虚拟机的管理功能。Libvirt通过调用QEMU-KVM来操作虚拟机,简化了虚拟机的管理过程。Libvirt的守护进程libvirtd可以被本地或远程的virsh命令调用,从而实现对虚拟机的管理。
总的来说,KVM、QEMU和Libvirt三者之间的关系可以总结如下:
KVM:提供CPU和内存的虚拟化。
QEMU:模拟I/O设备,与KVM结合实现完整的虚拟化。
Libvirt:管理工具和API,通过调用QEMU-KVM简化虚拟机的管理。
通过这三者的协作,用户可以实现高效、灵活的虚拟化解决方案。