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

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

3天内不再提示

Linux内核中的jump label原理与逻辑及运行过程

Linux阅码场 来源:CSDN技术社区 作者:dog250 2021-03-25 14:02 次阅读

jump label机制进入Linux内核已经很多很多年了,它的目的是 消除分支。 为了达到这个目的,jump label的手段是 修改分支处的代码。

~把代码当做数据,代码和数据在冯诺伊曼计算机中得到了统一~

本质上,jump label作用于下面的逻辑:

e0bbcc26-8cdd-11eb-8b86-12bb97331649.png

静态拆分成了下面的两个逻辑,其一是:

e0e058fc-8cdd-11eb-8b86-12bb97331649.png

或者,其二是:

e12ea246-8cdd-11eb-8b86-12bb97331649.png

但二者不能同时共存。显然,这破坏了通用性和灵活性,带来了高效!

这相当于一个硬熔断,具体详情参见:

本文来一点可以看得见的东西,演示一下真实的jump label & static key。

先看下面的C代码:

e1519dc8-8cdd-11eb-8b86-12bb97331649.png

很简单的代码,也很正确。然而, 如果main函数是一个高频调用的函数,并且在E1,E2是不随着代码逻辑而发生变化,仅仅参数设定的情况下, 那么if语句尽量消除以消除不必要的分支预测,而这正是jump label的用武之地!

我们下面用jump label机制来重写上面的代码,请看:

e18ee192-8cdd-11eb-8b86-12bb97331649.png

e1e3bc44-8cdd-11eb-8b86-12bb97331649.png

e22b2692-8cdd-11eb-8b86-12bb97331649.png

e26cc53e-8cdd-11eb-8b86-12bb97331649.png

e2a16848-8cdd-11eb-8b86-12bb97331649.png

定义JUMP_LABEL宏编译之,看看效果:

e2c8bb50-8cdd-11eb-8b86-12bb97331649.png

如何做到的呢?static_branch_true内联函数是如何判断true or false的呢?

事实上,jump label逻辑修改了代码段,取消了条件判断!这一切都是在update_branch中发生的。我们看下update_branch调用之前,main函数的汇编码:

e31df26e-8cdd-11eb-8b86-12bb97331649.png

在执行了update_branch之后,main函数发生了变化:

e338ed80-8cdd-11eb-8b86-12bb97331649.png

e39d2124-8cdd-11eb-8b86-12bb97331649.png

看样子就是这么回事!

之所以这件事可以发生得如此简单,多亏了一个新的section,即__jump_table,我们通过objdump看看__jump_table的内容:

e3e7c74c-8cdd-11eb-8b86-12bb97331649.png

通过jump_label_demo.c的struct entry结构体,我们直到这个section中包含了多个3元组,包含3个字段:

需要修改的代码地址。

需要jmp到的代码地址。

匹配健。

我们看67064000 00000000按照小端就是0x400667,它就是需要修改的代码地址,而6e064000 00000000按照小端则是0x40066e:

e41fa0e0-8cdd-11eb-8b86-12bb97331649.png

看来,这个__jump_table的item会将jmpq 40066c修改为jmpq 40066e,从而实现了 永久静态分支。

最后,__jump_table的内容就是在每一个内联的static_branch_true函数中被填充的,该参数的参数是一个key,它指示了branch entry三元组中的最后一个字段。

static_branch_true函数的内联非常重要,它实现了将branch entry三元组数据直接插入到__jump_table section,而不是共享同一个函数体。

总之,如果你看代码还是觉得别扭,手敲一遍我上面的示例程序,就理解了,内核里面的也就这么回事,总结一句话:

依靠运行时修改代码而不是依靠状态数据来控制执行流。

我不知道这对于所谓的 通用计算机程序设计 是不是反其道而行之,但在效果上,它确实是一匹好马。不禁感叹, 硬编码读起来是丑陋的,但执行起来却是高效的!

灵活性换高效率,得不偿失,我是这样以为。jump label的本质在于, 将同时刻存在的一套代码沿着时间线在可预期的固定时间点上分割成逻辑相反的两套代码。

硬件性能的提升将会证明jump label就是个笑话。

说两句好话,Linux内核参数,sysctl变量基本上就可以通过jump label来运作,从而替代if判断。

原文链接:https://blog.csdn.net/dog250/article/details/106715700
编辑:lyn

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

    关注

    8

    文章

    7193

    浏览量

    89819
  • 逻辑
    +关注

    关注

    2

    文章

    833

    浏览量

    29519
  • 代码
    +关注

    关注

    30

    文章

    4841

    浏览量

    69196
  • LINUX内核
    +关注

    关注

    1

    文章

    316

    浏览量

    21767

原文标题:Linux内核jump label与static key的原理与示例

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    腾讯云内核团队修复Linux关键Bug

    Maintainer深感棘手的关键内核bug。 这一改进方案经过严格评审和测试,最终被合并进入后续的Linux LTS(长期支持)版本,标志着腾讯云在操作系统内核领域的技术实力得到了
    的头像 发表于 12-31 10:58 316次阅读

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    及时,在遇到一些内核问题时就可以到linux官网的源码查一下是不是有相关的提交记录。获取芯片原厂的linux源码每个芯片原厂都有自己的git仓库,他们会把已经开发完成的
    发表于 12-13 09:03

    嵌入式工程师都在找的【Linux内核调试技术】建议收藏!

    ,调试过程中被调试的内核运行在目标机上,GDB调试器运行在开发机上。 使用KDB进行Linux内核
    发表于 11-28 15:37

    Linux系统shell命令解析

    shell是Linux系统的用户界面,提供了用户与内核交互的一种接口,它接收用户输入的命令并到送到内核去执行,因此也被称为Linux的命令解释器。
    的头像 发表于 11-05 15:40 397次阅读

    deepin社区亮相第19届中国Linux内核开发者大会

    中国 Linux 内核开发者大会,作为中国 Linux 内核领域最具影响力的峰会之一,一直以来都备受瞩目。
    的头像 发表于 10-29 16:35 595次阅读

    linux内核通用HID触摸驱动

    linux内核,为HID触摸面板实现了一个通用的驱动程序,位于/drivers/hid/hid-multitouch.c文件。hid触摸驱动是以struct hid_driver
    的头像 发表于 10-29 10:55 1067次阅读
    <b class='flag-5'>linux</b><b class='flag-5'>内核</b><b class='flag-5'>中</b>通用HID触摸驱动

    Linux根文件系统的挂载过程

    Linux根文件系统(rootfs)是Linux系统中所有其他文件系统和目录的起点,它是内核启动时挂载的第一个文件系统。
    的头像 发表于 10-05 16:50 559次阅读

    linux系统下,TLV320ADC3101可以在设备运行过程中,可以实时修改CODEC的采样率吗?

    请问:在linux系统下,TLV320ADC3101可以在设备运行过程中,可以实时修改CODEC的采样率吗? 采样位数,增益这些呢
    发表于 09-30 06:45

    详解linux内核的uevent机制

    linux内核,uevent机制是一种内核和用户空间通信的机制,用于通知用户空间应用程序各种硬件更改或其他事件,比如插入或移除硬件设备(如USB驱动器或网络接口)。uevent表示
    的头像 发表于 09-29 17:01 1047次阅读

    linux驱动程序如何加载进内核

    Linux系统,驱动程序是内核与硬件设备之间的桥梁。它们允许内核与硬件设备进行通信,从而实现对硬件设备的控制和管理。 驱动程序的编写 驱动程序的编写是
    的头像 发表于 08-30 15:02 627次阅读

    linux驱动程序运行在什么空间

    Linux 驱动程序是操作系统的一部分,负责管理硬件设备与操作系统之间的交互。驱动程序运行在内核空间(Kernel Space),这是操作系统的核心部分,与用户空间(User Space)相对。内核
    的头像 发表于 08-30 14:37 547次阅读

    Linux内核测试技术

    Linux 内核Linux操作系统的核心部分,负责管理硬件资源和提供系统调用接口。随着 Linux 内核的不断发展和更新,其复杂性和代码规
    的头像 发表于 08-13 13:42 625次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>测试技术

    Linux内核的页面分配机制

    Linux内核是如何分配出页面的,如果我们站在CPU的角度去看这个问题,CPU能分配出来的页面是以物理页面为单位的。也就是我们计算机中常讲的分页机制。本文就看下Linux
    的头像 发表于 08-07 15:51 368次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b><b class='flag-5'>中</b>的页面分配机制

    欢创播报 华为宣布鸿蒙内核已超越Linux内核

    1 华为宣布鸿蒙内核已超越Linux内核   6月21日,在华为开发者大会上, HarmonyOS NEXT(鸿蒙NEXT)——真正独立于安卓和iOS的鸿蒙操作系统,正式登场。这是HarmonyOS
    的头像 发表于 06-27 11:30 928次阅读

    使用 PREEMPT_RT 在 Ubuntu 构建实时 Linux 内核

    盟通技术干货构建实时Linux内核简介盟通技术干货Motrotech如果需要在Linux实现实时计算性能,进而有效地将Linux转变为RT
    的头像 发表于 04-12 08:36 2875次阅读
    使用 PREEMPT_RT 在 Ubuntu <b class='flag-5'>中</b>构建实时 <b class='flag-5'>Linux</b> <b class='flag-5'>内核</b>