StratoVirt地址空間管理-基於Rust的實現與優化
AddressSpace
完成。如下是 StratoVirt 地址空間管理模組的組成,以及其在 StratoVirt 中的位置。
stratovirt
├── acpi
├── address_space
│ ├── Cargo.toml
│ └── src
│ ├── address.rs
│ ├── address_space.rs
│ ├── host_mmap.rs
│ ├── lib.rs
│ ├── listener.rs
│ ├── region.rs
│ └── state.rs
├── boot_loader
├── Cargo.lock
├── Cargo.toml
├── cpu
├── devices
├── docs
├── hypervisor
├── license
├── machine
├── machine_manager
├── Makefile
├── migration
├── migration_derive
├── ozone
├── pci
├── README.ch.md
├── README.md
├── src
├── sysbus
├── tests
├── util
├── vfio
└── virtio
StratoVirt 地址空間模組整體設計
上圖中的主要結構含義如下:
-
AddressSpace
地址空間:為地址空間模組的管理結構, 負責整個虛擬機器的地址空間管理
-
Region
代表一段地址區間,根據這段地址區間的使用者,可以分為以下型別:
-
RAM:虛擬機器記憶體使用該段地址區間。 -
IO:虛擬機器裝置使用該段地址區間。 -
Container :作為容器使用,可以包含多個子 Region
。如描述 PCI 匯流排域的地址管理就可以使用型別為Container
的Region
,它可以包含 PCI 匯流排域下的 PCI 裝置使用的地址區間。該型別的Region
可以幫助管理並區分儲存器域、PCI 匯流排域的地址管理。
FlatView
,則是根據這些
Region
的地址範圍和優先順序屬性形成的線性檢視。在通過地址空間管理結構
AddressSpace
訪問裝置或者記憶體時, 使用平坦檢視
FlatView
可以更加方便快捷地找到對應的
Region
。
Region
都會對應一個優先順序
priority
屬性,如果低優先順序的
Region
佔用的地址區間和高優先順序的
Region
佔用的地址區間重疊,則低優先順序的
Region
的重疊部分,將會被覆蓋,即在平坦檢視
FlatView
中不可見。
FlatView
的更新。一些裝置或者模組需要獲取最新的平坦檢視,並相應的執行一些操作。例如 Vhost 裝置,需要將平坦檢視中的全部記憶體資訊同步到核心 Vhost 模組,以便通過共享記憶體方式完成訊息通知的流程。另外,我們也需要將已經分配並對映好的虛擬機器實體地址和宿主機虛擬地址資訊註冊到 KVM 模組,這樣可以藉助硬體輔助虛擬化加速記憶體訪問的效能。基於以上需求,我們引入上圖中的地址空間監聽函式連結串列,該連結串列在平坦檢視
FlatView
更新後被依次呼叫,可以方便的完成資訊同步。該連結串列允許其他模組新增一個自定義的監聽回撥函式。
地址空間優化
拓撲結構更新優化
Region
的介面,並設定
AddressSpace
結構負責管理整個資料結構並生成更新後的
FlatView
結構。
Region
的方式為, 呼叫
Region
結構的
add_subregion
介面,注意父
Region
必須是
Container
型別。這樣會帶來一個問題,如果向樹狀結構中的某個
Region
中新增或者刪除子
Region
,並引起樹狀結構的拓撲發生變化,負責生成並更新平坦檢視的
FlatView
的
AddressSpace
結構體如何得知已經發生變化呢?
Region
結構中新增成員並指向自己所屬的
AddressSpace
,如上圖所示。熟悉 Rust 語言的同學應該知道,這種實現方式會引入資源相互引用的問題,導致
AddressSpace
和
Region
兩者因相互引用而在生命週期結束時無法釋放記憶體資源的問題。因此,在地址空間模組的樹狀結構中,所有
Region
對自己所屬的
AddressSpace
的指標都使用
std::sync::Weak
類指標,
Weak
指標不會增加所指向物件的引用計數,可確保在生命週期結束時對應結構的析構和資源釋放。
pub struct Region {
region_type: RegionType,
priority: Arc<AtomicI32>,
size: Arc<AtomicU64>,
offset: Arc<Mutex<GuestAddress>>,
mem_mapping: Option<Arc<HostMemMapping>>,
ops: Option<RegionOps>,
io_evtfds: Arc<Mutex<Vec<RegionIoEventFd>>>,
space: Arc<RwLock<Weak<AddressSpace>>>,
subregions: Arc<RwLock<Vec<Region>>>,
}
鎖優化
鎖粒度最小化
AddressSpace
結構體如下。可以看到,
AddressSpace
的關鍵成員都以
Arc<Mutex<..>>
的方式保證了多執行緒共享的安全性。
pub struct AddressSpace {
root: Region,
flat_view: ArcSwap<FlatView>,
listeners: Arc<Mutex<Vec<Box<dyn Listener>>>>,
ioeventfds: Arc<Mutex<Vec<RegionIoEventFd>>>,
}
鎖效能優化
// AddressSpace優化前結構
pub struct AddressSpace {
root: Region,
flat_view: Arc<RwLock<FlatView>>,
listeners: Arc<Mutex<Vec<Box<dyn Listener>>>>,
ioeventfds: Arc<Mutex<Vec<RegionIoEventFd>>>,
}
FlatView
具有重要作用。其一,在樹狀拓撲結構發生變化時,例如新增和刪除
Region
,會引起平坦檢視
FlatView
發生變化,因此應該獲取
AddressSpace
中
flat_view
成員的
寫鎖,用於更新平坦檢視;其二,裝置訪問記憶體、VCPU 退出到 StratoVirt 訪問裝置,都要通過
AddressSpace
的
flat_view
成員,獲取
讀鎖,找到對應的
Region
,然後進行讀寫操作。
RwLock
仍然存在兩個問題:其一,經過測試,Rust 讀寫鎖的效能比互斥鎖差。而讀寫鎖和互斥鎖的效能均比原子型別差;其二,在某些場景下,地址空間管理模組需要實現
函式可重入的支援,即 在持有
FlatView
讀鎖的情況下,仍可以對樹狀拓撲結構和平坦檢視
FlatView
更新(例如,PCI bar 空間更新,需要通過
AddressSpace
訪問裝置暫存器來設定地址,並將確定好地址的 PCI bar 空間新增到
AddressSpace
中)。
arc_swap
第三方庫的 RCU-like 的機制,不但可以滿足可重入性的要求,而且通過地址空間模組訪問記憶體的效能可以提升 20%以上。
pub struct AddressSpace {
root: Region,
flat_view: ArcSwap<FlatView>,
listeners: Arc<Mutex<Vec<Box<dyn Listener>>>>,
ioeventfds: Arc<Mutex<Vec<RegionIoEventFd>>>,
}
關注我們
StratoVirt 當前已經在 openEuler 社群開源。後續我們將開展一系列主題分享,如果您對 StratoVirt 的使用和實現感興趣,歡迎您圍觀和加入。
專案地址:https://gitee.com/openeuler/stratovirt
專案 wiki:https://gitee.com/openeuler/stratovirt/wikis
您也可以訂閱郵件列表:https://mailweb.openeuler.org/postorius/lists/virt.openeuler.org/
如有疑問,也歡迎提交 issue:https://gitee.com/openeuler/stratovirt/issues
入群
本文分享自微信公眾號 - openEuler(openEulercommunity)。
如有侵權,請聯絡 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。
「其他文章」
- openGauss企業版安裝
- 使用gsql連線資料庫
- 重磅丨生態共榮——萬里資料庫推動GreatSQL攜手openEuler 共建資料庫產業生態
- CLA:減少開源社群合規風險的銀彈?
- 華為江大勇:openEuler 尤拉系統累計裝機超 130 萬套,已跨越生態拐點
- StratoVirt 的 virtio 裝置模擬是如何實現的
- openGauss開源資料庫二次開發指導手冊(下)
- 20國學生參與,社群增長159%,暑期2021亮點回顧
- openEuler 尤拉開源社群聯合中國移動完成全棧國產根社群基礎軟體搬遷實踐
- StratoVirt 的中斷處理是如何實現的?
- 聯想開天加入尤拉開源社群,加速 openEuler 在各行業的應用
- 劉壽永:openEuler將著力四大應用場景構建數字經濟生態底座
- 華雲資料將hostha開源到openEuler尤拉社群
- 華雲資料將 hostha 開源到 openEuler 尤拉社群
- openEuler結合ebpf提升ServiceMesh服務體驗的探索
- 中國電信子公司“天翼數字生活”加入 openEuler 尤拉開源社群
- openEuler 尤拉開源社群 Log4j 高危安全漏洞修復完成,建議所有使用者升級
- 江民科技加入openEuler尤拉開源社群
- 中國俄羅斯合作開發作業系統,包括鴻蒙、尤拉 openEuler 及極光 AuroraOS
- StratoVirt vCPU管理Rust執行緒同步的實現