内存管理实战案例分析2:KSM和NUMA引发的虚拟机宕机

本文分析了一起因KSM(Kernel Samepage Merging)和NUMA(Non-Uniform Memory Access)导致的虚拟机宕机问题。在Ubuntu 16.04服务器上,KSM内核线程、khugepaged内核线程及QEMU进程因争夺mm->mmap_sem锁而发生死锁,由numad进程长时间持有该锁造成。解决方案包括升级到Linux 4.4.0-96以上内核版本。
摘要由CSDN通过智能技术生成

微信公众号:奔跑吧linux社区
本文节选自《奔跑吧linux内核》第二版卷1第6.3.2章

1.问题描述

对于RHEL发行版以及Ubuntu服务器版本,客户都报告了这样的问题。在一台至强服务器(使用x86_64处理器)上发现好几个正在运行的虚拟机发生了死锁,即虚拟机没有响应。这台服务器是基于NUMA架构的服务器,内建多个CPU节点和内存节点。在主机的Linux中开启了KSM机制和numad监控程序。虚拟机是基于KVM和QEMU构建的。
主机的Linux发行版是Ubuntu 16.04。主机的Linux内核版本是4.4.0-47-generic。
在虚拟机的Linux内核中发现softlockup的如下日志信息。

CPU: 3 PID: 22468 Comm: kworker/u32:2 Not tainted 4.4.0-47-generic #68-Ubuntu 
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
Ubuntu-1.8.2-1ubuntu1 04/01/2014 
Workqueue: writeback wb_workfn (flush-252:0) 
[<ffffffff81104388>] smp_call_function_many+0x1f8/0x260 
[<ffffffff810727d5>] native_flush_tlb_others+0x65/0x150 
[<ffffffff81072b35>] flush_tlb_page+0x55/0x90

2.问题分析

从虚拟机的Linux内核日志信息可知,虚拟机的vCPU3正在运行kworker内核线程,这个线程调用flush_tlb_page()函数刷新TLB,并调用smp_call_function_many()函数给其他vCPU发送IPI广播,最后一直在等待其他vCPU回应。smp_call_function_many()函数实现在kernel/smp.c中,其代码片段如下。

<kernel/smp.c>

void smp_call_function_many(const struct cpumask *mask,
                smp_call_func_t func, void *info, bool wait)
{
     ...
    for_each_cpu(cpu, cfd->cpumask) {
        csd_lock(csd);
        csd->func = func;
        csd->info = info;
        if (llist_add(&csd->llist, &per_cpu(call_single_queue, cpu)))
            __cpumask_set_cpu(cpu, cfd->cpumask_ipi);
    }

    /* 给所有vCPU发送IPI广播*/
    arch_send_call_function_ipi_mask(cfd->cpumask_ipi);

    /* 等待其他vCPU返回*/
    if (wait) 
        for_each_cpu(cpu, cfd->cpumask) 
            csd_lock_wait(csd);
}

我们在虚拟机的Linux内核中找不到特别多的有用信息,但是为什么vCPU会一直在等待TLB刷新呢?我们需要结合主机的Linux内核日志信息一起分析。
接下来分析主机Linux内核中的日志信息。我们可以使用kdump工具来抓取主机Linux发生的死锁或者softlockup中的内存快照(vmcore)。从主机的vmcore里,我们发现有几个线程一直在等待一个读写信号量。
下面是ksmd内核线程的函数调用栈,从第2个栈帧可以发现ksmd内核线程尝试申请一个读者类型的信号量,但是一直没有成功。对照其源代码,我们发现它在scan_get_next_rmap_item()函数中尝试申请一个读者类型的mm→mm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值