401 Star 1.4K Fork 1.3K

GVPopenEuler / kernel

 / 详情

热补丁激活流程优化(WO_FTRACE实现)

已完成
需求
创建于  
2022-06-16 10:28

【特性描述】

功能

本特性是基于CONFIG_LIVEPATCH_WO_FTRACE实现下的热补丁激活流程优化,对基于CONFIG_LIVEPATCH_FRACE的实现不影响。特性通过在被打补丁函数入口插入断点异常,引流对旧函数的调用,提升栈检查通过概率,进而提升热补丁激活成功率。

方案

下面描述基于CONFIG_LIVEPATCH_WO_FTRACE实现。

内核热补丁提供了force选项,以调整激活(enable)热补丁时栈检查的宽松程度,当前支持如下设置:

  • force = 0: 保证旧函数(需要被打补丁的函数)不在所有任务的栈上,会严格检查旧函数的每一条指令,有最强的一致性保证,对比较热点的函数,打补丁成功率低
  • force = 1:不进行栈检查,强制激活补丁,此时旧函数指令替换区(插入跳转指令时原函数会被覆盖的指令)的某个pc在栈上,强制指令替换可能会造成系统crash,并且没有一致性保证
  • force = 2:只检查旧函数指令替换区的指令是否在栈上,只要指令替换区不在栈上就进行指令替换。因为指令替换区通常在函数的prologue中,而prologue中一般不会生成函数调用,所以指令替换区不会处于调用栈的中间,优化后激活成功率会有提升,并且能避免上面描述的force=1时造成系统crash的情况。但这样会允许系统中同时存在旧函数与新函数调用,即便是同一任务的调用栈,也可能出现新旧两个版本的函数,安全性有所降低。

force=2时热补丁激活流程:
force=2时热补丁激活流程

基于force=2的实现,可以进一步进行激活流程优化。在某些架构下指令替换区会有几条指令,比如ppc64有8条指令、arm开启module_plt支持时有4条指令等。如果热点函数被反复调用,stop machine时任务可能反复在指令替换区被抢占,热补丁就会反复激活失败。针对这个问题,可先在旧函数入口插一条breakpoing指令,此后内核再调用到旧函数时就会触发breakpoint,breakpoint的handler中拦截执行流,避免反复进入旧函数。此时整体流程大致如下:
插入breakpoint引流旧函数时热补丁激活流程

同时,要求对需要打补丁的函数全部设置force=2才启用特性优化。

【硬件架构】
x86、arm64、arm32、ppc64、ppc32

评论 (2)

lihuafei 创建了需求

Hi lihuafei1, welcome to the openEuler Community.
I'm the Bot here serving you. You can find the instructions on how to interact with me at Here.
If you have any questions, please contact the SIG: Kernel, and any of the maintainers: @YangYingliang , @pi3orama , @成坚 (CHENG Jian) , @jiaoff , @zhengzengkai , @Qiuuuuu , @刘勇强 , @Xie XiuQi

openeuler-ci-bot 添加了
 
sig/Kernel
标签
lihuafei 修改了描述
zhengzengkai 通过src-openeuler/kernel Pull Request !680任务状态新建 修改为已完成

这个特性有没有测试方法或者脚本之类的?

登录 后才可以发表评论

状态
负责人
项目
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(3)
5329419 openeuler ci bot 1632792936 9250373 gou hao 2021 1623390923
C
1
https://gitee.com/openeuler/kernel.git
git@gitee.com:openeuler/kernel.git
openeuler
kernel
kernel

搜索帮助

344bd9b3 5694891 D2dac590 5694891