摘要:阿里提出里面提供機制,即在退出前先等會兒,這樣可以減少退出次數(shù)。優(yōu)點性能較阿里好缺點只適用于獨占物理核場景狀態(tài)社區(qū)討論中,比較大可能被接受。針對不同的業(yè)務(wù)模型,采用不同的機制最大化業(yè)務(wù)性能。
本文由作者朱益軍授權(quán)網(wǎng)易云社區(qū)發(fā)布。
簡介
在實際業(yè)務(wù)中,guest執(zhí)行HLT指令是導(dǎo)致虛擬化overhead的一個重要原因。如[1].
KVM halt polling特性就是為了解決這一個問題被引入的,它在Linux 4.3-rc1被合入主干內(nèi)核,其基本原理是當guest idle發(fā)生vm-exit時,host 繼續(xù)polling一段時間,用于減少guest的業(yè)務(wù)時延。進一步講,在vcpu進入idle之后,guest內(nèi)核默認處理是執(zhí)行HLT指令,就會發(fā)生vm-exit,host kernel并不馬上讓出物理核給調(diào)度器,而是poll一段時間,若guest在這段時間內(nèi)被喚醒,便可以馬上調(diào)度回該vcpu線程繼續(xù)運行。
polling機制帶來時延上的降低,至少是一個線程調(diào)度周期,通常是幾微妙,但最終的性能提升是跟guest內(nèi)業(yè)務(wù)模型相關(guān)的。如果在host kernel polling期間,沒有喚醒事件發(fā)生或是運行隊列里面其他任務(wù)變成runnable狀態(tài),那么調(diào)度器就會被喚醒去干其他任務(wù)的事。因此,halt polling機制對于那些在很短時間間隔就會被喚醒一次的業(yè)務(wù)特別有效。
代碼流程
guest執(zhí)行HLT指令發(fā)生vm-exit后,kvm處理該異常,在kvm_emulate_halt處理最后調(diào)用kvm_vcpu_halt(vcpu)。
int kvm_vcpu_halt(struct kvm_vcpu *vcpu){
++vcpu->stat.halt_exits; if (lapic_in_kernel(vcpu)) { vcpu->arch.mp_state = KVM_MP_STATE_HALTED; return 1; } else { vcpu->run->exit_reason = KVM_EXIT_HLT; return 0; }
}
將mp_state的值置為KVM_MP_STATE_HALTED,并返回1。
static int vcpu_run(struct kvm_vcpu vcpu){ int r; struct kvm kvm = vcpu->kvm;
vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); for (;;) { if (kvm_vcpu_running(vcpu)) { r = vcpu_enter_guest(vcpu); } else { r = vcpu_block(kvm, vcpu); } if (r <= 0) break; //省略 }
}
由于kvm處理完halt異常后返回1,故主循環(huán)不退出,但在下一個循環(huán)時kvm_vcpu_running(vcpu)返回false,所以進入vcpu_block()分支,隨機調(diào)用kvm_vcpu_block()。
通用的halt polling代碼在virt/kvm/kvm_main.c文件中的額kvm_vcpu_block()函數(shù)中實現(xiàn)。
ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns);do { /*
* This sets KVM_REQ_UNHALT if an interrupt * arrives. */ if (kvm_vcpu_check_block(vcpu) < 0) { ++vcpu->stat.halt_successful_poll; if (!vcpu_valid_wakeup(vcpu)) ++vcpu->stat.halt_poll_invalid; goto out; } cur = ktime_get();
} while (single_task_running() && ktime_before(cur, stop));
情況一:如果當前物理核上沒有其他task處于running狀態(tài),而且在polling時間間隔內(nèi),那么就一直等著,直到kvm_vcpu_check_block(vcpu) < 0,即vcpu等待的中斷到達,便跳出循環(huán)。
out:
block_ns = ktime_to_ns(cur) - ktime_to_ns(start); if (!vcpu_valid_wakeup(vcpu)) shrink_halt_poll_ns(vcpu); else if (halt_poll_ns) { if (block_ns <= vcpu->halt_poll_ns) ; /* we had a long block, shrink polling */ else if (vcpu->halt_poll_ns && block_ns > halt_poll_ns) shrink_halt_poll_ns(vcpu); /* we had a short halt and our poll time is too small */ else if (vcpu->halt_poll_ns < halt_poll_ns && block_ns < halt_poll_ns) grow_halt_poll_ns(vcpu); } else vcpu->halt_poll_ns = 0; trace_kvm_vcpu_wakeup(block_ns, waited, vcpu_valid_wakeup(vcpu)); kvm_arch_vcpu_block_finish(vcpu);
這段代碼主要用于調(diào)整下一次polling的等待時間。若block_ns大于halt_poll_ns,即vcpu halt時間很短就被喚醒了,則把下一次的halt_poll_ns調(diào)長;否則,減短。
情況二:如果當前物理核上其他task變成running態(tài),或polling時間到期,則喚醒調(diào)度器,調(diào)度其他任務(wù),如下代碼。
for (;;) {
prepare_to_swait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE); if (kvm_vcpu_check_block(vcpu) < 0) break; waited = true; schedule(); }
模塊參數(shù)說明
Module Parameter Description default Value
halt_poll_ns The global max polling interval which defines the ceiling value which defines the ceiling value which defines the ceiling value of the polling interval for each vcpu. KVM_HALT_POLL_NS_DEFAULT (per arch value)
halt_poll_ns_grow The value by which the halt polling interval is multiplied polling interval is multiplied polling interval is multiplied in the grow_halt_poll_ns() function. 2
halt_poll_ns_shrink The value by which the halt polling interval is divided in the shrink_halt_poll_ns() function. 0
kvm用這3個參數(shù)來動態(tài)調(diào)整最大halt polling時長。debugfs下/sys/module/kvm/parameters/存放著這3個模塊參數(shù)的默認值。X86架構(gòu)下,KVM_HALT_POLL_NS_DEFAULT默認值為400000。 grow一次,值乘以halt_poll_ns_grow:
static void grow_halt_poll_ns(struct kvm_vcpu *vcpu){
unsigned int old, val, grow; old = val = vcpu->halt_poll_ns; grow = READ_ONCE(halt_poll_ns_grow); /* 10us base */ if (val == 0 && grow) val = 10000; else val *= grow; if (val > halt_poll_ns) val = halt_poll_ns; vcpu->halt_poll_ns = val; trace_kvm_halt_poll_ns_grow(vcpu->vcpu_id, val, old);
}
shrink一次,值除以halt_poll_ns_shrink,當前系統(tǒng)該參數(shù)為0,說明在設(shè)定的polling時長下虛擬機未被喚醒,那么下一次polling時長降到基準值10us:
static void shrink_halt_poll_ns(struct kvm_vcpu *vcpu){
unsigned int old, val, shrink; old = val = vcpu->halt_poll_ns; shrink = READ_ONCE(halt_poll_ns_shrink); if (shrink == 0) val = 0; else val /= shrink; vcpu->halt_poll_ns = val; trace_kvm_halt_poll_ns_shrink(vcpu->vcpu_id, val, old);
}
值得注意幾點
該機制有可能導(dǎo)致物理CPU實際空閑的情況下占用率表現(xiàn)為100%。因為如果guest上業(yè)務(wù)模型是隔一段時間被喚醒一次來處理很少量的流量,并且這個時間間隔比kvm halt_poll_ns短,那么host將poll整個虛擬機的block時間,cpu占用率也會沖上100%。
halt polling是電源能耗和業(yè)務(wù)時延的一個權(quán)衡。為了減少進入guest的時延,idle cpu時間轉(zhuǎn)換為host kernel時間。
該機制只有在CPU上沒有其他running任務(wù)的情況得以應(yīng)用,不然polling動作被立馬終止,喚醒調(diào)度器,調(diào)度其他進程。
延伸閱讀
業(yè)界針對虛擬機idle這個課題有比較多的研究,因為它帶來了比較大的overhead。主要可以歸結(jié)為以下幾種:
idle=poll,即把虛擬機idle時一直polling,空轉(zhuǎn),不退出。這樣不利于物理CPU超線程的發(fā)揮。
阿里提出guest里面提供halt polling機制,即在VM退出前先等會兒,這樣可以減少VM退出次數(shù)。 --- 優(yōu)點:性能較社區(qū)halt polling機制好;缺點:需要修改guest內(nèi)核;狀態(tài):社區(qū)尚未接收 https://lwn.net/Articles/732236/
AWS及騰訊考慮guest HLT指令不退出。 --- 優(yōu)點:性能較阿里好;缺點:只適用于vcpu獨占物理核場景;狀態(tài):社區(qū)討論中,比較大可能被接受。https://patchwork.kernel.org/...
idle等于mwait及mwait不退出。 --- 需要高版本kvm及高版本guest內(nèi)核支持。
總結(jié)
如何高效地處理虛擬機idle是提升虛擬化性能的研究點。針對不同的業(yè)務(wù)模型,采用不同的機制最大化業(yè)務(wù)性能。后續(xù)將在考拉及其他業(yè)務(wù)上逐個驗證這些方案。
參考文檔
https://www.linux-kvm.org/ima...
http://events17.linuxfoundati...
http://events17.linuxfoundati...
https://www.kernel.org/doc/Do...
免費領(lǐng)取驗證碼、內(nèi)容安全、短信發(fā)送、直播點播體驗包及云服務(wù)器等套餐
更多網(wǎng)易技術(shù)、產(chǎn)品、運營經(jīng)驗分享請訪問網(wǎng)易云社區(qū)。
文章來源: 網(wǎng)易云社區(qū)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/25360.html
摘要:和的云計算功能特點對比正式這個戰(zhàn)爭或者說趨勢的一個生動寫照??偠灾?,目前調(diào)度器將只會對部署虛擬機環(huán)節(jié)有影響。目前有一個孵化項目其作用是為提供虛擬機級別高可用支持。容錯在中沒有針對于容錯的功能,并且截至目前也沒有計劃去完成這些功能。 OpenStack中國社區(qū)編者按:在云計算生態(tài)系統(tǒng)中,有兩種類型的用戶需要使用云計算資源:傳統(tǒng)型(Traditional IT applications)和在互...
摘要:分析惡意軟件有很多方法。這是一個虛擬化環(huán)境下的惡意軟件分析系統(tǒng)。整體上,基于虛擬機技術(shù),使用中央控制系統(tǒng)和模塊設(shè)計,結(jié)合的自動化特征,已經(jīng)是頗為自動化的惡意軟件行為研究環(huán)境。加密的通訊幾乎不可能直接分析。 分析惡意軟件(malicious ware)有很多方法。請容我不自量力推薦兩個開放源代碼的免費系統(tǒng) Cuckoo 和 MalWasm 。這是一個虛擬化環(huán)境下的惡意軟件分析系統(tǒng)。 基...
閱讀 3776·2021-09-22 15:34
閱讀 1285·2019-08-29 17:25
閱讀 3478·2019-08-29 11:18
閱讀 1466·2019-08-26 17:15
閱讀 1844·2019-08-23 17:19
閱讀 1308·2019-08-23 16:15
閱讀 790·2019-08-23 16:02
閱讀 1412·2019-08-23 15:19