neo's profile十年一场梦 ..BlogListsGuestbookMore ![]() | Help |
|
|
8/6/2009 关于虚拟化项目中 播放音乐卡 (vt 架构性能 ),101 蓝屏 (smp 多核时钟同步 ) 及时钟变慢 ( 中断丢失 ) 的产生原因分析
播放音乐卡
我们先来看看guest访问真实硬件的几种方式
Guest之所以能在虚拟机之上运行,是因为虚拟机为其提供了看起来和真实硬件无异的模拟硬件环境。这些硬件环境包含有CPU,总线,时钟,以及各种可能的外设,如显卡,硬盘,光驱,网卡等等 分为以下几种方式; 1)qemu软件模拟--如时钟,PIT,PCI总线,中断控制器等。 这类设备完全由软件模拟,并不和真实的硬件打交道。之所以要将其和真实硬件脱离关系,是因为毕竟虚拟机作为软件需要运行于宿主操作系统(host os)之上,而宿主操作系统又必须独占性的使用某些硬件设备,比如系统时钟,总线,中断控制器等(这些设备不同声卡等外设,可以共享使用)。可以想象,如果虚拟机之上Guest 系统也对上述设备访问(比如写中断控制器),那么两个系统的状态就会发生“撞车”,宿主系统就会发生崩溃,Guest系统自然也不可幸免。所以无法将上述设备给Guest OS访问,因此必须完全模拟这些设备。至于具体有哪些设备需要软件模拟实现呢?这要看具体环境。原则上宿主系统独占使用的都应属于这类设备。(引申一下,宿主系统这里理解成直接操作硬件的最下端操作系统。除了传统的操作系统外,虚拟机监控程序(VMM)从某种意义上说也可看是一种宿主系统,不过一般不这么叫)。 2)前后端设备--如块设备(硬盘,以前的网卡,usb)。 在XEN环境中,在VMM之上还存在一个叫做domain 0的虚拟机用于管理硬件设备(该虚拟机是修改过的Linux操作系统,是特权系统,可以直接操作控制硬件设备),其它domain(称为domainU或叫guest,非特权)若要访问硬件,则需要经过domain0中qemu模拟设备或者通过一种被称为前后端机制的设备访问方式。这种机制的服务对象是那些需要在domain0和domainU中并发共享,而且要求高性能的设备。 前后端机制是指设备驱动分成后端(backend)和前端(frontend),后端处于domain0;而前端则处于domainU,作为后端的代理,并不需要接触具体硬件细节。前后端通讯通过共享内存等方法,前端设备驱动收到I/O请求后会将请求转发给后端设备,而后端设备会负责对以硬件最终操作的(准确的讲它也不直接操作,最后直接操作的应该是Linux自带的网卡驱动)。 其调用过程如下:dom1 front-end driver -> dom0 back-end driver -> dom0 e1000 driver。前后端程序都是驱动,运行在内核态直接截获,修改协议栈以达到高速(相比qemu网卡访问方式速度要高不少)。 3)dha设备(xen叫pass through)--如网卡,声卡,显卡等等。 这种技术出现在VT处理器面世之后,其特点是虚拟机不再需要提供设备模拟,而是让guset系统直接看到真实设备,并操作真实设备。这样做的优点有:1 由于不需要模拟设备进行请求转换,所以访问速度高;2 GUEST系统能根据最新硬件,加载对应驱动,可充分发挥硬件功能;而使用模拟设备时,只能加载模拟的驱动,如果模拟设备功能落后,显然无法充分利用真实硬件的全部潜能。当然缺点也很显然:真实设备只能供一个Guest系统使用 ,而且要注意VMM使用的设备无法pass through给guest系统。 从原理上来讲pass through方式是将PCI设备的资源(中断,IO,MMIO)直接暴露给GUEST OS并允许其直接访问。具体做法是,对于IO资源(irq中断 i/o地址),VT技术可以允许guest系统直接访问而不会被VMM捕获;对于MMIO(内存映射IO空间),则需要处理相对页表,使得GUEST能直接访问到物理设备真实的MMIO空间;中断则需要将真实中断注射到虚拟中断控制器中,以便GUEST能收到真实中断。 这里需要注意的是 目前的dha还不是完全的dha访问,guest访问真实硬件时仍然要经过hypervisor层的处理,因为所有与dha机制相关的i/o资源表,mmio表都在hypervisor层中。 说完设备访问方式 再来讲讲关于虚拟设备的 vmm截获(如硬盘读写操作)(对应访问模式2) VMM截获I/O操作是指:guest 系统发送的I/O访问请求被VMM拦截,而不是像native环境下那样被直接写入到物理设备中。原因是显而易见的,因为不能让guest系统直接修改硬件状态,否则有可能会造成系统故障(轻则影响其他guest运行,重则会让整个系统宕机)。所以VMM会将截获的I/O指令进行分析后模拟执行,也就是将“伪造”的数据返回给Guest系统。I/O请求或读或写在被VMM截获后都需要模拟执行。模拟即可以在VMM内部完成,也可以在d0中完成。VMM内部完成的好处是速度快,缺点是需要在VMM中实现模拟设备,工作量大;且使得VMM变的臃肿,降低了VMM的可靠性。在d0中完成虽然需要将I/O请求从VMM转发到host中的设备模拟进程,增加了上下文切换和调度时间。但是优点更突出:1 可以利用已存在的设备模拟代码(如qemu);2可以借助d0系统的设备驱动。3 保持了VMM尽量精简。鉴于以上原因多数虚拟化软件都采用将设备模拟纺在d0中进行。 Xen中完成I/O虚拟化的过程进行说明: 首先guest 系统执行I/O请求命令(如out xxx); 由于guest处于用户空间,I/O访问会引发trap,这时处于特权级运行的VMM会将捕获该trap,然后VMM可能在自己内部模拟执行该I/O请求(如对中断控制器的请求或简单的pit模拟等都实现在VMM内部),或者将I/O请求向上发送给处于Domain0中运行的Qemu进程模拟I/O操作(具体是通过event channel发送模拟中断通知domain0中的qemu)。Qemu进程当监听到上发的I/O请求后,会调对应端口注册的处理函数进行I/O模拟处理,并将模拟结果送回VMM,从而返回给guest系统。 说下关键的 无论是qemu,前后端还是dha方式 guest对真实硬件的访问(比如时钟中断,i/o中断请求),都需要通过vm entry/vm exit两个事件下发到hpyervisor完成,不同的是qemu\前后端需要vmm截获 经过一系列模拟完成,而dha查表直接访问硬件.(大致上可以认为vmm和hpyervisor是同一东西)显然通过qemu方式速度上要慢得多的多.
有了这些背景知识就可以分析下播放音乐卡的原因了;
考虑原因可能有2个; 1)声卡中断延迟. 在虚拟机环境下,将传统的“中断发生->中断处理”的同步方式改变成了异步方式。也就是中断发生后并非立刻被处理,而是要等到再次调度到目的guest os才能被处理,由于调度关系,中断处理时机存在很大的不确定行guest上的进程media player要想播放音乐 首先要做的就是从硬盘上加载部分音乐文件到他的进程用户空间中,这样就会带来大量的硬盘操作(同时系统中也有其他的硬盘操作比如说记录日志),因为硬盘的访问属于qemu方式,读写操作会使vmm占用大量的cpu时间进行设备模拟,而声卡的中断却没有时间去调度,从而造成了延迟,这种现象在系统overhead时尤其明显,想想咱们测试的时候拷贝文件时播放音乐听到的卡声相对较多,也是这个原因,目前的解决方法: 去掉硬盘buffer,并选择大批量cache,为的也是能尽量减少硬盘i/o 2)声卡中断丢失 这个可能基于内核的一个特性(与虚拟机无关),就是在系统硬件中断频繁的时,为了能够让该硬件中断造成的中断处理函数(软中断,调度级别比硬中断低)优先于之后的到来的硬中断 进行调度.而采用一种机制称为硬件中断临时频避的策略来实现,若不采用这种机制就会出现如下菪机现象;系统频繁调度硬中断,却没有时间去处理相应的中断处理函数,造成中断队列越来越多,最后 呵呵。。 上面说的只是一般内核的现象,在虚拟机上,连硬件中断都有延迟,都有不确定性,何况中断处理呢? 所以就会出现中断的大量丢失的现象,特别是高负载情况下.(关于中断丢失到101问题时还会详细说)
其实还有非常多类似问题 如 播放视频卡(特别是需要显卡GPU硬解压的高清视频---显卡 硬盘 声卡) 玩游戏卡(要求速度的--网卡 cpu 硬盘..)
-------------------------------------- 时间变慢问题
这个问题与101问题相互之间有一定联系,比较复杂 一点一点说 背景:
os时钟 操作系统的时钟处理按理来说应该是个早已成熟的技术。然而在虚拟环境下(不仅仅是xen,vmware这些虚拟机),对时钟的处理可绝非轻而易举,比如咱们的guest vista等,往往用眼睛就可发觉其wall clock走的不是那么的准确,有些飘?,时快时慢. 如果你运行某些性能测试工具,也会发现测试数据忽高忽低。(vycor项目中经常见到 估计也就张静见过 其他人做的时候时钟已经是dha方式了 dha后面再说) 先来谈谈操作系统的时钟源吧. 目前x86体系的操作系统中使用的时钟源有RTC , TSC ,PIT , CPU Local Timer , HPET , ACPI Power Management Timer 。其中pit 是操作系统传统上使用的timekeeping 时钟,其精度不是很高,因此很多操作系统(如vista/Linux)目前都使用或支持使用RTC中的周期性定时器来做timekeeping的时钟源。TSC不能产生中断,只能读取,因而多用来配合其它时钟做些校正等工作。至于其它几个时钟也可用timekeeping
我们再来谈timekeep吧!操作系统timekeeping体系大致包含下面几个部分:
1 更新系统启动后的时间流失 2 更新wall clock 3 计算进程的时间片 4 更新资源计数 5 处理软件定时器 上面说的wall clock不准,问题主要就出在”更新wall clock”这一过程中。该过程其实很简单,就是在每次时钟中断时刻更新系统的wall clock。然而要想wall clock准确,必须基于一个事实――系统的时钟中断准确送上来,且能及时被处理。别看这么简单,在传统环境下它不是个问题,然后在虚拟环境下可很难保证这个事实。因为传统的抢占式中断处理过程在虚拟环境下变成了类似信号处理的延迟执行方式了。 更确切的说就是虚拟环境下 1 模拟的时钟中断不能保证精确的按时发出,它有可能延迟;2 时钟中断的处理并非”抢占”式,只有到guest os获得运行时刻才可执行。上述两点便是时钟问题的根本症结。 XEN虚拟机中的时钟
xen的架构我就不多说了。 其中要说明一下:在Domain0(也被称作SOS)中有个模块叫 Device Mode, 硬件相关的模拟都由其完成(时钟也是),它运行于用户空间.GUEST OS能使用的时钟来自于Device Mode的模拟,而软件时钟中断的发现和处理时机则是每次发生VM Exit/Vm Entry的时刻.如果将该时刻比作进程调度的话,这点很象进程发现信号的过程. 总结重点:xen虚拟环境中系统时钟是使用软件模拟的,即使用软件模拟时钟中断.
就xen结构而言,我们知道多数设备的模拟都处于运行于用户空间的qemu程序进行模拟,时钟的模拟最初也是如此. 可是这样做存在一个隐蔽的问题 ---- 时钟模拟程序在某些情况下无法保证被及时调度,从而也就无法保证能及时准确的模拟时钟中断. 所谓的某些情况包括: 1 SOS(qmeu运行于SOS的用户空间)负载重,因而影响qemu被调度的机会,也就使得软件时钟中断无能及时产生----模拟代码没有机会调度自然无法产生软件时钟中断 模拟时钟的频率要求过高, 造成SOS无法模拟(如果模拟时钟的频率要求高于SOS的硬件时钟中断频率,则就无法模拟,比如SOS最高提供1000hz的时钟源,那么qmeu可模拟的软件时钟中断则不会超过1000hz) ,除了上述两条外, 高频时钟模拟也给系统带来很大的负载,从而影响虚拟机的整体性能. 上面说了xen虚拟环境下GUEST OS时钟不准的原因,那么lenovo用的什么方法解决或减轻该问题呢?
(下面是猜得 也可能不是) 1 将模拟时钟从SOS的qemu中移植到xen. 这样做可更好保证时钟模拟程序可得到运行.因为在xen中运行机会要比在qemu中更能保证(姑且管这个叫dha) 2 对时钟软件中断进行记录,并在Guest os从xen返回时刻将丢失的软件中断补回去,从而防止时钟中断丢失.(我猜想 声卡的中断丢失也要这样处理了) 3 在GUEST OS中调整wall clock, 这个做法很简单就是修改Guest OS的内核,做一个守护进程,让其不断修正wall clock,修正的依据可通过读取 xen的时钟,如果发现慢于xen的时钟则将自己的wall clock时钟按照xen时间设置.
有了这几点基本上就可以理解为什么reboot时间会变慢了.--- 不断reboot,时钟中断补偿没有能够及时运行,vista上的守护进程还未运行起来(同时也可以解释 为什么蓝屏的机器反而时间正常些)
--------------
101问题
当时测试的时候 时钟还是qemu方式,只知道时钟中断会延迟处理,特别是在高负载情况下,于是乎使用ltp压力测试工具 试图加大系统负载,没想到压力5分钟就出现了101蓝屏。当时并不知道根本原因是什么,以为是时钟延迟造成的,可后来才知道具体原因跟多核有关系: 背景知识: 传统系统硬件中存在诸如RTC/PIT/HPET/ACPI PM TIMER/TSC等许多时钟, 这些时钟按其特点来说可分成两类:以中断形式存在的周期性时钟, 如RTC/PIT/HPET等;另外一种是以COUNTER计数器存在的单步递增性时钟,如TSC。它们之间的区别在于,周期性时钟是通过周期性发送中断达到记时目的的,如同心跳。而单步递增时钟则不发送中断,而时需要软件主动去读取其COUNTER寄存器来获得时间的。 在传统环境下时钟同步不会出现任何问题,而在虚拟环境下时钟产生的条件出现了变化; RTC等周期性时钟不是由相应硬件产生而是通过软件定时器模拟而得,但是TSC的获得则不是通过模拟,还是读硬件的TSC的COUNTER 寄存器获得TSC值(正好和传统反着)。 我们已经清楚地知道在虚拟环境下软件模拟RTC等周期性时钟中断无法精确的触发和递交给GOS(虚拟环境下肯定会延迟且触发间隔不稳定),RTC计时和TSC时间就发生了失步(TSC会跑的快)。这样就需要TSC校正周期性时钟计时。intel vt技术所做的解决方法就是在GOS读取TSC时,返回结果是在原结果(硬件TSC COUNTER)上再加上一个可变化的偏移值tsc_offset的和,通过设置这个tsc_offset值,达到将GOS看到的TSC和其RTC维护的计时同步。 上面所讲的同步是针对单核系统而言的,对于多核SMP环境的同步除了上述要求之外,还需要多个核和上的时间同步――各个核上的TSC需要同步(每个核都有各自的TSC),TSC和系统周期性时钟需要同步。虚拟环境下多核同步有很多困难,想要完全同步要求多个模拟的核同步调度(同时被调度或被调出),否则有可能在给某个核提交周期时钟中断时,该核被调出,那么显然就会丢失时钟中断造成系统时间落后。 就Xen而言,为了提高整个系统性能各个核独立调度,因此会存上述丢失中断的可能。 为此xen将周期性时钟绑定到BSP核上。由于AP核不收到时钟中断,也就不会去做timekeep操作(timekeep是在收到时钟中断后进行),所以不会进行系统计时操作和校对时间操作,虽然此刻AP核上的TSC确实和RTC计时失步。------------说白了 我觉得就是xen为了避免作大量的工作来实现不如选择放弃实现多个核之间的同步,仅bsp核作时钟timekeep,ap核可以出现不同步的现象 这样做可能导致的问题是出现Timeout。因为xen只将时钟中断发向BSP核,所以如果AP核调度与BSP核不同步,那么会出现当ap核调入运行时,发现自己的时间等待队列上的有些定时器已经超时。原因在于当AP核调出时,BSP核已经接收了足够多的时钟中断使得系统计时前进了不少,在AP核看来计时跳跃了一大段,因此AP核上的定时器超时就不可避免。运行vista做Guest OS有时出现0x00000101蓝屏 ----------------- 后话: 虚拟化---从目前虚拟机来看尚无法完成实时任务,仅从性能角度讲,中断转发流程和效率,xen的调度,设备模拟效率,多核同步和自旋锁及高速缓存效率,任何一个在特定场合都可能成为影响系统性能的关键因素。 TrackbacksThe trackback URL for this entry is: http://sh-neo.spaces.live.com/blog/cns!1E3CA285E5F9E122!753.trak Weblogs that reference this entry
|
|
|