Xen Credit调度算法详细说明

Xen虚拟机调度实质上是虚拟CPU的调度。在Xen中,虚拟机通过其拥有的虚拟CPU运行任务,而虚拟CPU需要由Xen调度至物理CPU执行。对应用程序而言CPU调度分成两个层次:首先VMM的虚拟CPU调度将物理CPU时间分配给各虚拟机的虚拟CPU;然后各虚拟机的进程调度负责将虚拟CPU的时间分给虚拟机内的各应用程序。Xen采用策略和机制分离的思想来简化Xen的调度框架设计,并允许用户通过实现调度框架的接口来满足特定的需求。

Xen虚拟CPU调度将通用机制实现为调度框架,而具体的调度策略则允许用户根据需求在调度算法中实现。Xen曾先后采用过Borrowed Virtual Time(BVT)、Simple Earliest Deadline First(SEDF、Credit等调度算法,在较新的Xen版本中也正在不断优化Credit2调度算法,为其发展做铺垫,本文主要还是针对现今默认的Credit调度算法进行介绍。

Credit调度算法按照权重共享CPU时间。Credit调度算法的参数主要包括表示权重的Weight和表示CPU时间上限的CAPWeight是一个相对值,Xen根据每个虚拟机的Weight值计算其应获得的Credit值。Xen默认所有虚拟机的Weight值为256,而CAP值初始化为无上限限制的-1。管理员可以通过特权域0设置每一个虚拟机的这两个参数。

  Credit1调度器基本框架如下如所示。


为了便于理解上图,先介绍几个基本概念:

  csched_pcpu:物理cpu的调度信息,它主要是就绪的vcpu队列,ticker计时器,用于每个tick周期计算当前运行的vcpu的credit值。

csched_vcpu:vcpu的调度信息,它位于pcpu的就绪队列上,也位于活动vcpu列表上,可以得到它所属的domain的调度信息,可以得到它的credit值与优先级

csched_dom:domain的调度信息,例如活动的vcpu列表,活动domain列表,domain的weight和cap值。

csched_private:credit调度算法的总体信息,例如调度锁,cpu个数,主ticker计时器,用于每3个tick周期计算一次所有的credit值,当前总的weight值和credit值。

Credit1调度器的基本流程如下:

(1)在启动xen时会初始化credit调度算法,创建一个idle_domain,它有和物理cpu个数相同的vcpu,每个vcpu位于对应的物理cpu上,用于占位和空跑,相对于其它domain的vcpu,idle_domain的vcpu优先级是最低的。

(2)在初始化时__start_xen-->init_idle_domain-->scheduler_init中会将软中断和schedule()绑定,并设置每个pcpu的用于schedule的s_timer,其处理函数是s_timer_fn,主要是触发软中断SCHEDULE_SOFTIRQ。schedule()会在每3个tick周期(30ms,即一个vcpu得到调度后运行的时间片)执行一次,该过程的结果为该pcpu找出合适的vcpu和时间片,用于该vcpu在此pcpu上的运行,然后进行上下文切换。这个schedule过程是根据选择的调度算法来确定的。

(3)在初始化domain时调度模块会初始化其vcpu的调度信息,vcpu的初始化主要是把vcpu插入到其pcpu的运行就绪队列runq上和活动vcpu列表中。如果发现其对应的pcpu还没初始化,则按照下面的方法初始化该pcpu。

 (4)在初始化每个pcpu时会设置它的tick的timer,每个tick周期(10ms)会执行一次csched_tick,来更新该pcpu上运行的当前vcpu的credit值,减去credit_per_tick,该值是100。当活动vcpu列表为空时说明所有vcpu的credit都为负,则重新计算credit值。否则通过pick后pcpu是否变化来检查是否需要进行vcpu的迁移,如果需要则触发软中断,执行schedule算法。

  (5)credit算法在执行schedule时,会首先获得该pcpu的就绪队列runq上队首vcpu,即snext,检查其credit值有没有用完,如果没有用完直接返回。如果用完表明该pcpu的就绪队列上没有under或boost状态的vcpu,则进行负载均衡,查找其它pcpu上优先级较高的vcpu,执行run_steal把它偷过来运行。如果还没有找到合适的,就返回之前得到的snext

  (6)主ticker的master_timer由csched_priv持有,在csched_start_tickers里初始化,它每3个tick周期通过csched_acct来计算所有domain的vcpu的credit值,主要是根据当前credit总值,每个domain占用的权重weight和比例上限cap,计算出每个domain分得的credit值,然后再平均分配到每个vcpu上,vcpu的credit值就等于原有的credit值和新分到的credit之和。根据vcpu最新的credit值来确定vcpu的调度优先级是over还是under,如果是over且cap有设置,则执行sleep,把自己调度出来,等待下次判断和调度。

Credit算法中,每个物理CPU上的虚拟CPU均保存在运行队列中,并按照其优先级顺序排列。虚拟CPU的状态共有四种,分别是IDLE、OVER、UNDER以及BOOST,其中IDLE状态表示该虚拟CPU属于idle_domain,具有最低的优先级;用完其Credit值的虚拟CPU会进入OVER状态并且无法被调度;UNDER状态下的虚拟CPU按照循环轮转算法周期性的被调度;当虚拟CPU因I/O操作被唤醒后,进入BOOST状态,BOOST状态的虚拟CPU具有最高优先级,Xen会优先调度处于BOOST状态的虚拟CPU。

Xen的Credit以公平共享资源著称,但是其I/O性能很容易受到计算密集型应用的干扰,尤其是系统中VCPU数目很多,并且运行了计算密集型应用时,延时增长非常迅速,在如今的Credit2调度器设计中,充分的考虑了I/O型负载的特性,优化了时间片,I/O权重,调度队列等,相比于Credit调度器大大地改善了I/O性能。但是如今Credit2还在进一步改进与测试中,还没有被设定为默认的调度器!






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章