1. 程式人生 > >cgroup 限制虛擬機器頻寬後,虛擬機器裡top統計問題分析

cgroup 限制虛擬機器頻寬後,虛擬機器裡top統計問題分析

今天遇到了一個問題。
用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((&paravirt_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