linux -- per-CPU变量

2024-01-31 10:52
文章标签 linux 变量 cpu per

本文主要是介绍linux -- per-CPU变量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

per-CPU变量

per-CPU变量是一种存在与每个CPU本地的变量,对于每一种per-CPU变量,每个CPU在本地都有一份它的副本。

per-CPU变量的优点

  • 多处理器系统(smp)中无需考虑与其他处理器的竞争问题(并非绝对的)
  • 可以利用处理器本地的cache硬件,提高访问速度

per-CPU变量的分类

按照分配内存空间的类型来看,有两种:

  • 静态per-CPU变量
  • 动态per-CPU变量
    静态的per-CPU变量在编译期就静态分配,动态per-CPU变量在程序运行时动态分配。

per-CPU变量的实现机制

静态per-CPU变量

相关宏

  90 #ifndef PER_CPU_BASE_SECTION91 #ifdef CONFIG_SMP92 #define PER_CPU_BASE_SECTION ".data..percpu"93 #else94 #define PER_CPU_BASE_SECTION ".data"95 #endif96 #endif

定义和声明

   4/*5 * Base implementations of per-CPU variable declarations and definitions, where6 * the section in which the variable is to be placed is provided by the7 * 'sec' argument.  This may be used to affect the parameters governing the8 * variable's storage.9 *
/* 
per-CPU变量声明和定义的基础实现,变量被放置的section由sec参数提供,这被用于影响管理参数变量的存储方式注意!用于声明和定义的sections必须匹配,以免由于编译器生成错误的代码来访问该节而发生链接错误。
*/10 * NOTE!  The sections for the DECLARE and for the DEFINE must match, lest11 * linkage errors occur due the compiler generating the wrong code to access12 * that section.13 */14#define __PCPU_ATTRS(sec)                                               \15        __percpu __attribute__((section(PER_CPU_BASE_SECTION sec)))     \16        PER_CPU_ATTRIBUTES1718#define __PCPU_DUMMY_ATTRS                                              \19        __attribute__((section(".discard"), unused))20#ifdef HAVE_MODEL_SMALL_ATTRIBUTE21# define PER_CPU_ATTRIBUTES     __attribute__((__model__ (__small__)))22#endif73 * Normal declaration and definition macros.74 */75#define DECLARE_PER_CPU_SECTION(type, name, sec)                        \76        extern __PCPU_ATTRS(sec) __typeof__(type) name7778#define DEFINE_PER_CPU_SECTION(type, name, sec)                         \79        __PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES                        \80        __typeof__(type) name81#endif83/*84 * Variant on the per-CPU variable declaration/definition theme used for85 * ordinary per-CPU variables.86 */87#define DECLARE_PER_CPU(type, name)                                     \88        DECLARE_PER_CPU_SECTION(type, name, "")90#define DEFINE_PER_CPU(type, name)                                      \91        DEFINE_PER_CPU_SECTION(type, name, "")

这么多宏,最后其实就是DEFINE_PER_CPU和DECLARE_PER_CPU最重要。
举个例子:

DECLARE_PER_CPU(int, python);
DEFINE_PER_CPU(int, python);  

被展开为:

extern __percpu __attribute__((section("data..percou"))) int python;
__percpu __attribute__((section("data..percou"))) int python;

这里的定义实际把python变量放到.data…percpu段里。

看链接脚本:kernel/vmlinux.lds

定义了percpu区域的输出段,简单版本,需要对齐
所有percpu变量都会放到这个段里,__per_cpu_start和__per_cpu_end分别用于标识该区域的起始地址与终止地址。
在C代码中使用外部变量:extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];来引用他们。

 108        INIT_TEXT_SECTION(PAGE_SIZE)109        . = ALIGN(16);110        INIT_DATA_SECTION(16)111        PERCPU(4)676/**677 * PERCPU - define output section for percpu area, simple version678 * @align: required alignment679 *680 * Align to @align and outputs output section for percpu area.  This681 * macro doesn't maniuplate @vaddr or @phdr and __per_cpu_load and682 * __per_cpu_start will be identical.683 *684 * This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except685 * that __per_cpu_load is defined as a relative symbol against686 * .data.percpu which is required for relocatable x86_32687 * configuration.688 */689#define PERCPU(align)                                                   \690        . = ALIGN(align);                                               \691        .data.percpu    : AT(ADDR(.data.percpu) - LOAD_OFFSET) {        \692                VMLINUX_SYMBOL(__per_cpu_load) = .;                     \693                VMLINUX_SYMBOL(__per_cpu_start) = .;                    \694                *(.data.percpu.first)                                   \695                *(.data.percpu.page_aligned)                            \696                *(.data.percpu)                                         \697                *(.data.percpu.shared_aligned)                          \698                VMLINUX_SYMBOL(__per_cpu_end) = .;                      \699        }

per-CPU变量使用案例

一个非常典型的案例:计数器
per-CPU变量非常适合做统计计数,内核专门有一个给予per-CPU变量设计的计数器(lib/percpu-counter.c)
比如在网络子系统中,要计算系统接受到的各类网络包的数量,这些包更新的频率是极快的,这就需要percpu的支持,系统中每个处理器都有这么一个对网络包数量进行计量的副本,变量更新时无需考虑多处理器竞争问题,想算出总数是只需将所有处理器的同一percpu副本相加即可。

这篇关于linux -- per-CPU变量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/663516

相关文章

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

linux系统中java的cacerts的优先级详解

《linux系统中java的cacerts的优先级详解》文章讲解了Java信任库(cacerts)的优先级与管理方式,指出JDK自带的cacerts默认优先级更高,系统级cacerts需手动同步或显式... 目录Java 默认使用哪个?如何检查当前使用的信任库?简要了解Java的信任库总结了解 Java 信

Linux命令rm如何删除名字以“-”开头的文件

《Linux命令rm如何删除名字以“-”开头的文件》Linux中,命令的解析机制非常灵活,它会根据命令的开头字符来判断是否需要执行命令选项,对于文件操作命令(如rm、ls等),系统默认会将命令开头的某... 目录先搞懂:为啥“-”开头的文件删不掉?两种超简单的删除方法(小白也能学会)方法1:用“--”分隔命

Python之变量命名规则详解

《Python之变量命名规则详解》Python变量命名需遵守语法规范(字母开头、不使用关键字),遵循三要(自解释、明确功能)和三不要(避免缩写、语法错误、滥用下划线)原则,确保代码易读易维护... 目录1. 硬性规则2. “三要” 原则2.1. 要体现变量的 “实际作用”,拒绝 “无意义命名”2.2. 要让