kvm steal 溯源

  1. 背景

一般我们通过 kvm guest 中的%steal 指标来看 CPU 的争抢。但是目前在Host上并没有相关的手段或者指标来监控Guest 是否发生了争抢。

本文主要介绍如何在Host 判断争抢的发生,及 steal time的产生的内核代码分析。

  1. CPU Steal Time

Sar manual中对 %steal 的描述如下。

Steal time is the percentage of time a virtual CPU waits for a real CPU while the hypervisor is servicing another virtual processor.

当kvm/xen这些hypervisor进行VCPU之间调度时,VCPU用于等待PCPU的时间所占的百分比,就是CPU Steal Time。 VCPU 本质上是一个线程,所以可以认为是线程的调度延迟导致的。

Steal time是一个PV(ParaVirtual)实现,所以编译内核需要CONFIG_PARAVIRT=y 选项打开。

下面针对Centos_6.3的内核源码进行分析。

    1. 测试

环境:

Kernel version

HT

CPUs

Mem

Host

3.10.0-693.25.4.el7.x86_64

ON

24

125G

Gues

2.6.32-279.19.1.el6_sn.62.x86_64

/

8

16G

Guest Benchmark

# lookbusy -m 12GB -d 20GB -b 8KB -f /opt/test.data

 Guest 各个vcpu 加50% 负荷, 内存占用12GB,同时以100ms间隔8KB写文件 。

Pattern 1:

# cat /proc/sys/kernel/sched_domain/cpu*/domain*/flags

687

4655

25647

# cat /proc/sys/kernel/sched_domain/cpu*/domain*/flags

4143

No.

负荷Guest数

vCPUs

Host(avg)

Guest(avg)

%usr

%sys

%guest

%idle

%usr

%sys

%idle

%steal

1

4

32

0.02

5.03

67.69

27.25

49.91

0.31

46.63

3.13

2

5

40

0.01

6.02

83.73

10.23

49.07

0.23

40.67

10.01

  1. Steal time 的计算

在kvm_vcpu_arch 结构体中有steal的一个结构体。

Kvm_steal_time结构体如下:

下面主要依次介绍下面三个函数。

No.

函数名

作用

1

kvm_register_steal_time

用于注册各个vcpu steal time 到虚拟寄存器MSR_KVM_STEAL_TIME

2

accumulate_steal_time

用于累加steal time

3

record_steal_time

用于记录 steal time

    1.  kvm_register_steal_time (注册steal time)

kvm内核代码调用路径如下

setup_arch -> kvmclock_init -> kvm_register_steal_time -> kvm_guest_init

其中 kvmclock_init 将kvm_steal clock注册进steal_clock

时steal_time的内存地址写入到MSR_KVM_STEAL_TIME中,kvm中初始化部分完成。

    1.  accumulate_steal_time(计算函数)

在kvm_arch_vcpu_load 和 kvm_set_msr_common 两个函数中都会调用accumulate_steal_time。即,在VM_Entry/VM_Exit时都会计算steal time。

  1. kvm_arch_vcpu_load 会调用kvm_guest_enter函数,所以可以认为是VM_Entry时的调用。

kvm_vcpu_ioctl->kvm_arch_vcpu_ioctl_run-> vcpu_load-> kvm_arch_vcpu_load->vm_x86_ops->vcpu_load(vcpu, cpu)-> accumulate_steal_time

  1. kvm_set_msr_common 是处理寄存器VM_Exit的通用函数。

[EXIT_REASON_MSR_WRITE]= handle_wrmsr-> vmx_set_msr-> kvm_set_msr_common

accum_steal的计算代码非常简单,就是 run_delay 的delta。代码中run_delay 的解释是 “time spent waiting on a runqueue”花在等待运行队列的时间。也就是在vcpu 线程调度等待消耗的时间。有4个地方会修改run_delay 的值。

    1.  run_delay 的来源
  1. run_delay 的来源之一是由于interactive tasks 可能会直接重新给运行队列排队(通过nice值等),会造成原本从expired 队列进入空闲的Active 队列的线程产生延迟。

dequeue_task -> sched_info_dequeued -> rq_sched_info_dequeued

  1. run_delay 的另一个来源离开CPU后等待CPU运行task的时间。

schedule -> __sched_info_switch -> sched_info_arrive -> rq_sched_info_arrive

   Last_queued 是在sched_info_queued 中计算的,也就是离开CPU的时间。调用路径是,

schedule -> __sched_info_switch -> sched_info_depart -> sched_info_queued

    1.  record_steal_time(记录函数)

说完accumulate_steal_time,我们再来说record_steal_time。调用路径如下。kvm_vcpu_ioctl->kvm_arch_vcpu_ioctl_run-> __vcpu_run-> vcpu_enter_guest->record_steal_time-> kvm_guest_enter

kvm_arch_vcpu_ioctl_run中运行完vcpu_load 再执行__vcpu_run 。所以先计算accum_steal 。

注意 Centos7.3 3.10.9-693 中accumulate_steal_time 和 record_steal_time 合并成了一个函数record_steal_time 。

steal_account_process_tick 则是用来计算 /proc/stat 中的steal 。

  1. Host 监控指标

知道了steal time 本质上就是来源于cpu 调度系统的task 的run_delay 。

那么我们只要去监控KVM 中 VCPU 对应的线程号的 run_delay 即可。

/proc/PID/schedstat 中的第二个参数正好是run_delay 。

/proc/PID/schedstat中有3个值

NO.

Value

描述

sum_exec_runtime

  1. 顾名思义,进程总的运行时间
  2. /proc/PID/sched  也有这个值se.sum_exec_runtime

run_delay

  1. 因为进程离开队列等原因导致的延迟时间,用于计算KVM cpu steal time。
  2. 和/proc/pid/sched 中se.statistics->wait_sum 相等。

pcount

  1. 和/proc/PID/sched  中 nr_switches 相等,可以认为是这个线程的switch次数。
  2. pcount = nr_switches = nr_voluntary_switches + nr_involuntary_switches
  3. 运行在这个CPU上的CPU时间片。<- 内核代码中的描述可能有误。

具体监控某个VCPU 的 steal time 可以通过latency.c 计算。

# gcc –o lat tatency.c

# ./lat –s 1 –c 5 $vcpupid

  1. ref

KVM下steal_time源代码分析 | OenHan

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值