SMP/NUMA/PER_CPU

  • why
  • what
  • how

PER_CPU

从上图中我们可以看到,各种源文件中通过DEFINE_PER_CPU的方式,定义了很多percpu变量,这些变量根据vmlinux.lds.S中的相关定义,会被linker聚合在一起,然后放到最终vmlinux文件的,一个名叫.data...percpu的section里。

这些变量的地址也是被特殊处理过的,它们从零开始依次递增,这样一个变量的地址,就是该变量在整个vmlinux的.data...percpu区里的位置,有了这个位置,然后再知道某个cpu的percpu内存块的起始地址,就可以很方便的计算出该cpu对应的该变量的运行时内存地址。

linux内核在启动时,会先把vmlinux文件加载到内存中,然后根据cpu的个数,为每个cpu都分配一块用于存放percpu变量的内存区域,之后把vmlinux中的.data...percpu section里的内容,拷贝到各个cpu的percpu内存块的static区域里,最后将各percpu内存块的起始地址放到对应cpu的gs寄存器里。

到这里有关percpu变量的初始化工作就已经结束了。

当我们在访问percpu变量时,只需要将gs寄存器里的地址,加上我们想要访问的percpu变量的地址,就能得到在该cpu上,该percpu变量真实的内存地址。

有了这个地址,我们就可以方便的操作这个percpu变量了。

  • 上图中重点描述的是那些,在内核编译期就已经确定的percpu变量,这些变量是静态的,是不会随着时间的推移而动态的增加或减少的,所以它们在内核初始化时,就直接被拷贝到了各个percpu内存块的static区。

  • 除了这种静态percpu变量,还有另外两种percpu变量, 其中一种是内核模块中的静态percpu变量,它虽然也是在编译期就能确定的,但由于内核模块动态加载的特性,它不是完全静态的,内核为这种percpu变量在percpu内存块中单独开辟了一个区域,叫reserved区,当内核模块被加载到内存时,其静态percpu变量就会在这个区域分配内存。

  • 另外一种percpu变量就是纯动态的percpu变量,它是在运行时动态分配的,它使用的内存是上图中的dynamic区。

    • static区的大小是在编译期就算好的,是固定不变的.
    • reserved区也是固定不变的,但其大小是预估的.
    • dynamic区是可以动态增加的。
  • 虽然这三种percpu变量的分配方式不同,但它们的内在机制本质上都是一样的,所以这里我们只讲内核里的静态percpu变量

  • 参考文章

相关推荐
头发还没掉光光21 小时前
HTTP协议从基础到实战全解析
linux·服务器·网络·c++·网络协议·http
小白同学_C21 小时前
Lab2-system calls && MIT6.1810操作系统工程【持续更新】
linux·c/c++·操作系统os
物理与数学21 小时前
linux内核 struct super_block
linux·linux内核
Getgit21 小时前
Linux 下查看 DNS 配置信息的常用命令详解
linux·运维·服务器·面试·maven
zhangrelay1 天前
Linux(ubuntu)如何锁定cpu频率工作在最低能耗模式下
linux·笔记·学习
_OP_CHEN1 天前
【Linux系统编程】(二十)揭秘 Linux 文件描述符:从底层原理到实战应用,一篇吃透 fd 本质!
linux·后端·操作系统·c/c++·重定向·文件描述符·linux文件
chem41111 天前
玩客云 边缘AI模型 本地搭建部署 llama.cpp qwen
linux·人工智能·llama
一个平凡而乐于分享的小比特1 天前
Linux内核中的BogoMIPS详解
linux·bogomips
橘颂TA1 天前
【Linux 网络】TCP 拥塞控制与异常处理:从原理到实践的深度剖析
linux·运维·网络·tcp/ip·算法·职场和发展·结构与算法
zbguolei1 天前
CentOS 7.6离线安装Nginx
linux·nginx·centos