0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

StratoVirt 中的 balloon 设备介绍

openEuler 来源:openEuler 作者:openEuler 2021-12-21 14:56 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

StratoVirt 是计算产业中面向云数据中心的企业级虚拟化 VMM,实现了一套架构统一支持虚拟机、容器、Serverless 三种场景。StratoVirt 在轻量低噪、软硬协同、Rust 语言级安全等方面具备关键技术竞争优势。

背景介绍:

通常,在同一台服务器上存在着不同的用户,而多数用户对内存的使用情况是一种间断性的使用。也就是说用户对内存的使用率并不是很高。在服务器这种多用户的场景中,如果很多个用户对于内存的使用率都不高的话,那么会存在服务器实际占用的内存并不饱满这样一种情况。实际上各个用户使用内存的分布图可能如下图所示(黄色部分表示 used 部分,绿色部分表示 free 的部分)。

解决方案:

为了解决上述服务器上内存使用率低的问题,可以将虚拟机中暂时不用的内存回收回来给其他虚拟机使用。而当被回收内存的虚拟机需要内存时,由 host 再将内存归还回去。有了这样的内存伸缩能力,服务器便可以有效提高内存的使用率。在 StratoVirt 中,我们使用 balloon 设备来对虚拟机中的空闲内存进行回收和释放。下面详细了解一下 StratoVirt 中的 balloon 设备。

balloon 设备简介:

由于 StratoVirt 只是负责为虚拟机分配内存,只能感知到每个虚拟机总的内存大小。但是在每个虚拟机中如何使用内存,内存剩余多少。StratoVirt 是无法感知的,也就无法得知该从虚拟机中回收多少内存了。为此,需要在虚拟机中放置一个“气球(balloon)”设备。该设备通过 virtio 半虚拟化框架来实现前后端通信。当 Host 端需要回收虚拟机内部的空闲内存时,balloon 设备“充气”膨胀,占用虚拟机内部内存。而将占用的内存交给 Host 使用。如果虚拟机的空闲内存被回收后,虚拟机内部由于业务要求突然需要内存时。位于虚拟机内部的 balloon 设备可以选择“放气”缩小。释放出更多的内存空间给虚拟机使用。

balloon 实现:

balloon 的具体代码实现位于 StratoVirt 项目的/virtio/src/balloon.rs 文件中,相关细节可阅读代码理解。代码架构如下:

virtio
├──Cargo.toml
└──src
├──balloon.rs
├──block.rs
├──console.rs
├──lib.rs
├──net.rs
├──queue.rs
├──rng.rs
├──vhost
│├──kernel
││├──mod.rs
││├──net.rs
││└──vsock.rs
│└──mod.rs
├──virtio_mmio.rs
└──virtio_pci.rs

由于 balloon 是一个 virtio 设备,所以在前后端通信时也使用了 virtio 框架提供的 virtio queue。当前 StratoVirt 支持两个队列:inflate virtio queue(ivq)和 deflate virtio queue(dvq)。这两个队列分别负责 balloon 设备的“充气”和“放气”。

气球的充放气时,前后端的信息是通过一个结构体来传递。

structVirtioBalloonConfig{
///NumberofpageshostwantsGuesttogiveup.
pubnum_pages:u32,
///Numberofpageswe'veactuallygotinballoon.
pubactual:u32,
}

因此后端向前端要内存的时候,只需要修改这个结构体中的 num_pages 的数值,然后通知前端。前端读取配置结构体中的 num_pages 成员。并与本身结构体中的 actual 对比,判断是进行 inflate 还是 deflate。

inflate

如果是 inflate,那么虚拟机以 4k 页为单位去申请虚拟机内存,并将申请到的内存地址保存在队列中。然后通过 ivq 将保存了分配好的页面地址的数组分批发往后端处理(virtio queue 队列长度最大 256,也就是一次最多只能传输 1M 内存信息,对于大于 1M 的内存只能分批传输)。后端通过得到信息后,找到相应的 MemoryRegion,将对应的 page 标记为”WILLNEED“。然后通知前端,完成配置。

deflate

如果是 deflate 则从保存申请到的内存地址队列中弹出一部分内存的地址。通过 dvq 分批次传输给后端处理。后端将 page 标记为“DONTNEED"。

下面结合代码进行说明:

定义 BalloonIoHandler 结构体作为处理 balloon 事件的主体。

structBalloonIoHandler{
///Thefeaturesofdriver.
driver_features:u64,
///Addressspace.
mem_space:Arc,
///Inflatequeue.
inf_queue:Arc>,
///InflateEventFd.
inf_evt:EventFd,
///Deflatequeue.
def_queue:Arc>,
///DeflateEventFd.
def_evt:EventFd,
/*省略*/
}

其中包含上述的两个 virtio 队列inf_queue和def_queue,以及对应的触发事件描述符(EventFd)inf_evt和def_evt。两个队列均使用了Mutex锁,保证了队列在同一时刻只有一个使用者对该队列进行操作。保证了多线程共享的数据安全。

fnprocess_balloon_queue(&mutself,req_type:bool)->Result<()>{
letqueue=ifreq_type{
&mutself.inf_queue
}else{
&mutself.def_queue
};//获得对应的队列
letmutunlocked_queue=queue.lock().unwrap();
whileletOk(elem)=unlocked_queue
.vring
.pop_avail(&self.mem_space,self.driver_features)
{
matchRequest::parse(&elem){
Ok(req)=>{
if!self.mem_info.has_huge_page(){
//进行内存标记
req.mark_balloon_page(req_type,&self.mem_space,&self.mem_info);
}
/*省略*/
}
Err(e)=>{
/*省略错误处理*/
}
}
}
/*省略*/
}

当相应的EventFd被触发后process_balloon_queue函数将会被调用。通过判断请求类型确定是“充气”还是”放气“,然后再从相应的队列中取数据进行内存标记。其中while let是 Rust 语言提供的一种循环模式匹配机制。借助该语法可以将队列中 pop 出来的所有数据遍历取出到elem中。

内存标记及优化:

标记内存在mark_balloon_page函数中进行实现,起初的实现思路为:将虚拟机传送过来的地址逐个进行标记。即,从队列中取出一个元素,转化为地址后立即进行标记。后来经过测试发现:balloon 设备在对页地址进行一页一页标记内存时花费时间巨大。而同时也发现通过虚拟机传回来的地址中有大段的连续内存段。于是通过改变标记方法:由原来的一页一页标记改为将这些连续的内存统一标记。大大节省了标记时间。下面代码为具体实现:

fnmark_balloon_page(
&self,
req_type:bool,
address_space:&Arc,
mem:&BlnMemInfo,
){
letadvice=ifreq_type{
libc::MADV_DONTNEED
}else{
libc::MADV_WILLNEED
};
/*略*/
foriovinself.iovec.iter(){
letmutoffset=0;
letmuthvaset=Vec::new();
whileletSome(pfn)=iov_to_buf::(address_space,iov,offset){
offset+=std::()asu64;
letgpa:GuestAddress=GuestAddress((pfnasu64)<< VIRTIO_BALLOON_PFN_SHIFT);
                let hva = match mem.get_host_address(gpa) {
                    Some(addr) =>addr,
None=>{
/*略*/
}
};
//将hva地址保存在hvaset的vec中
hvaset.push(hva);
}
//对hvaset进行从小到大排序。
hvaset.sort_by_key(|&b|Reverse(b));
/*略*/
//将hvaset中连续的内存段进行标记
whileletSome(hva)=hvaset.pop(){
iflast_addr==0{
free_len+=1;
start_addr=hva;
}elseifhva==last_addr+BALLOON_PAGE_SIZE{
free_len+=1;
}else{
memory_advise(
start_addras*constlibc::c_voidas*mut_,
(free_len*BALLOON_PAGE_SIZE)asusize,
advice,
);
free_len=1;
start_addr=hva;
}

ifcount_iov==iov.iov_len{
memory_advise(
start_addras*constlibc::c_voidas*mut_,
(free_len*BALLOON_PAGE_SIZE)asusize,
advice,
);
}
count_iov+=std::()asu64;
last_addr=hva;
}
/*略*/
}
}
}

首先将 virtio 队列中的地址全部取出,并保存在 vec 中,然后将该 vec 进行从小到大的排序。有利于快速找出连续的内存段并进行标记。由于 hvaset 中的地址是按照从小到大排列的,因此可以从头开始遍历 hvaset,遇到不连续的地址后将前面的连续段进行标记。这样就完成了由原来逐页标记到连续内存段统一标记的优化。

经过测试,StratoVirt 的 balloon 速度也有了极大的提高。

原文标题:StratoVirt 基于 Rust 的 balloon 功能实践

文章出处:【微信公众号:openEuler】欢迎添加关注!文章转载请注明出处。

审核编辑:彭菁

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    14

    文章

    10451

    浏览量

    91859
  • 虚拟机
    +关注

    关注

    1

    文章

    976

    浏览量

    30769
  • 数据安全
    +关注

    关注

    2

    文章

    806

    浏览量

    30905

原文标题:StratoVirt 基于 Rust 的 balloon 功能实践

文章出处:【微信号:openEulercommunity,微信公众号:openEuler】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    initrd 没有带有自编译内核的 nvme 设备

    你好!我使用 nvme 的 -starfive 内核在 visionfive2 上运行 debian。当我根据内核升级我总是在缺少 root 设备的情况下进入 initrd。 因此,从本质上讲
    发表于 02-10 06:40

    半导体制造晶圆清洗设备介绍

    在半导体制造过程,晶圆清洗是一道至关重要的工序。晶圆经切割后,表面常附着大量由聚合物、光致抗蚀剂及蚀刻杂质等组成的颗粒物,这些物质会对后续工序芯片的几何特征与电性能产生不良影响。随着半导体
    的头像 发表于 01-27 11:02 1069次阅读
    半导体制造<b class='flag-5'>中</b>晶圆清洗<b class='flag-5'>设备</b><b class='flag-5'>介绍</b>

    太诱产品在通用电子设备的使用指南及技术剖析

    ,我们需要全面了解相关的注意事项、产品规格以及性能特点等内容,以确保设计出的设备能够稳定、高效地运行。本文将基于太诱产品的相关文档,为大家详细介绍其在通用电子设备的使用要点。 文件下
    的头像 发表于 01-18 16:55 1290次阅读

    觐嘉-客户考察无人自助洗宠机和医疗检测设备-产品介绍

    检测设备
    觐嘉科学仪器上海
    发布于 :2026年01月05日 16:29:26

    如何在Linux列出USB设备

    Linux操作系统提供了许多命令来列出系统连接的USB设备,这些命令非常有用,无论是查看已连接设备的信息,还是进行系统调试。 在本文中,我们将介绍一些常用的命令以及它们的使用方法,
    发表于 12-24 08:19

    能否详细介绍一下MOSFET在电机控制的作用是什么?

    能否详细介绍一下MOSFET在电机控制的作用?
    发表于 12-22 13:11

    触觉智能RK3506开发板配置USB复合设备(下)

    本文基于触觉智能RK3506开发板,为大家介绍配置USB复合设备,本章节将介绍UMS和ACM复合设备数据交互。UMSUMS是USB协议体系
    的头像 发表于 12-22 12:13 760次阅读
    触觉智能RK3506开发板配置USB复合<b class='flag-5'>设备</b>(下)

    ExpeditionPCB管脚交换介绍

    mentor PCB设计器件管脚网络交换介绍
    发表于 10-28 16:56 0次下载

    时间同步设备在复杂网络环境的调试要点

    时间同步设备是保障网络系统协同运行的基础设施,尤其在金融、电力、通信等领域对精度要求较高的场景,其稳定性直接影响业务连续性。在实际部署,网络环境的复杂性常给同步精度带来挑战。本文将分享几个调试过程
    的头像 发表于 08-13 15:48 692次阅读
    时间同步<b class='flag-5'>设备</b>在复杂网络环境<b class='flag-5'>中</b>的调试要点

    盲埋孔线路板在通信设备的应用

    盲埋孔线路板在通信设备的应用主要体现在以下几个方面: 提高抗干扰能力和稳定性 盲孔技术在通信设备可以提高设备的抗干扰能力和稳定性,确保通
    的头像 发表于 08-12 14:27 894次阅读
    盲埋孔线路板在通信<b class='flag-5'>设备</b><b class='flag-5'>中</b>的应用

    工业设备与管理系统之间的数据台是什么?

    在工业场景设备(如机床、生产线、传感器等)会产生海量实时数据(如运行状态、参数、故障信息等),而管理系统(如MES、ERP、SCADA等)则需要依赖这些数据实现生产调度、成本核算、运维决策等功能
    的头像 发表于 08-11 13:49 996次阅读

    SP系列连接器在呼吸机与麻醉设备的应用

    思特安SP系列连接器在医疗设备方面具体应用广泛,其设计特性与医疗场景需求高度契合,今天让我们来进一步介绍思特安SP系列连接器在呼吸机与麻醉剂相关医疗设备的应用,具体应用分析如文件
    发表于 08-07 17:46 1次下载

    微公司首台金属刻蚀设备付运

    近日,微半导体设备(上海)股份有限公司(以下简称“微公司”,股票代码:688012)宣布其刻蚀设备系列喜迎又一里程碑:Primo Menova12寸金属刻蚀
    的头像 发表于 06-27 14:05 1312次阅读

    SNMP协议在设备监控的使用

    介绍,并提供使用SNMP进行网络管理的基本指南。 1.简介 SNMP(Simple Network Management Protocol)是一个基于互联网协议族(IP)的网络管理标准,用于在IP网络的管理节点与被管理节点之间进行通信,以实现对网络
    的头像 发表于 06-27 11:48 825次阅读
    SNMP协议在<b class='flag-5'>设备</b>监控<b class='flag-5'>中</b>的使用

    CAN转PROFINET网关设备基本功能介绍

    设备简介 本研究介绍设备为一款集成了Profinet (PN) 和Controller Area Network (CAN) 通信协议的网关,其工作原理基于数据映射技术。在Profinet网络架构
    的头像 发表于 06-08 10:36 918次阅读
    CAN转PROFINET网关<b class='flag-5'>设备</b>基本功能<b class='flag-5'>介绍</b>