今天遇到了一个问题。
用cgroup限制虚拟机(qemu-kvm)的CPU占比为宿主机的50%时。发现虚拟里centos7系统,用top显示一个死循环的进程,这个进程的占比是50%。而我所认知时虚拟机对限制应该不感知。应该显示100%才对。
我又用qemu-kvm启动了一个ubuntu的系统,发现ubuntu里用top看一个死循环,这个进程显示的是100%。
问题排查:
1 一开始我以为时top的工具统计的问题,我下载了top的源代码。在两个虚拟机里测试,发现新编译的top和虚拟机里自带的top结果相同。排除了top统计引起的问题。
2 这时候,内核版本可疑性就比较大了。我在ubuntu和centos用两个系统中boot下面默认的config编译。结果还是和原生的一样。排除内核问题。
3 这个时候,怀疑内核配置选项问题了。我在ubuntu的系统里用centos的config编译内核。然后装载重启系统后,发现ubuntu的系统用top看之前的死循环的进程占比变成了50%。
4 通过多次的ubuntu和centos原生的config对比和验证后,发现内核的配置选项CONFIG_PARAVIRT_TIME_ACCOUNTING导致了centos和ubuntu在cgroup限制后,用top看虚拟机的死循环进程的cpu使用率不同。Centos7使能了这个。
分析如下:
相关的内核的代码
static void update_rq_clock_task(struct rq *rq, s64 delta)
{
...此处省去xx行...
#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
if (static_key_false((¶virt_steal_rq_enabled))) {
steal = paravirt_steal_clock(cpu_of(rq));
steal -= rq->prev_steal_time_rq;
if (unlikely(steal > delta))
steal = delta;
rq->prev_steal_time_rq += steal;
delta -= steal;
}
#endif
rq->clock_task += delta;
...此处省去xx行...
}
进程的运行的物理时间是由rq->clock_task计算的,delta是进程在切换之前计算当前执行了多少时间。
当使能了CONFIG_PARAVIRT_TIME_ACCOUNTING后,delta会将cgroup限制的时间减去。导致在虚拟机里用top看while进程不是100%。
后来,在网上搜到了一篇文章解释的很好。
http://oenhan.com/kvm-steal-time
用cgroup限制虚拟机(qemu-kvm)的CPU占比为宿主机的50%时。发现虚拟里centos7系统,用top显示一个死循环的进程,这个进程的占比是50%。而我所认知时虚拟机对限制应该不感知。应该显示100%才对。
我又用qemu-kvm启动了一个ubuntu的系统,发现ubuntu里用top看一个死循环,这个进程显示的是100%。
问题排查:
1 一开始我以为时top的工具统计的问题,我下载了top的源代码。在两个虚拟机里测试,发现新编译的top和虚拟机里自带的top结果相同。排除了top统计引起的问题。
2 这时候,内核版本可疑性就比较大了。我在ubuntu和centos用两个系统中boot下面默认的config编译。结果还是和原生的一样。排除内核问题。
3 这个时候,怀疑内核配置选项问题了。我在ubuntu的系统里用centos的config编译内核。然后装载重启系统后,发现ubuntu的系统用top看之前的死循环的进程占比变成了50%。
4 通过多次的ubuntu和centos原生的config对比和验证后,发现内核的配置选项CONFIG_PARAVIRT_TIME_ACCOUNTING导致了centos和ubuntu在cgroup限制后,用top看虚拟机的死循环进程的cpu使用率不同。Centos7使能了这个。
分析如下:
相关的内核的代码
static void update_rq_clock_task(struct rq *rq, s64 delta)
{
...此处省去xx行...
#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
if (static_key_false((¶virt_steal_rq_enabled))) {
steal = paravirt_steal_clock(cpu_of(rq));
steal -= rq->prev_steal_time_rq;
if (unlikely(steal > delta))
steal = delta;
rq->prev_steal_time_rq += steal;
delta -= steal;
}
#endif
rq->clock_task += delta;
...此处省去xx行...
}
进程的运行的物理时间是由rq->clock_task计算的,delta是进程在切换之前计算当前执行了多少时间。
当使能了CONFIG_PARAVIRT_TIME_ACCOUNTING后,delta会将cgroup限制的时间减去。导致在虚拟机里用top看while进程不是100%。
后来,在网上搜到了一篇文章解释的很好。
http://oenhan.com/kvm-steal-time
本文探讨了使用cgroup限制虚拟机CPU占用时遇到的问题,即CentOS 7与Ubuntu系统显示的CPU使用率差异。通过对top工具、内核版本及配置的排查,最终定位到CONFIG_PARAVIRT_TIME_ACCOUNTING配置项的影响。
75

被折叠的 条评论
为什么被折叠?



