
它不仅决定了系统的抢占行为,还直接影响系统在不同上下文(如进程上下文、中断上下文等)中的行为表现
本文将详细解析`preempt_count`变量的定义、作用及其在不同体系结构下的实现,以及如何通过它判断和管理系统上下文,如内核抢占、软中断和硬中断等
一、`preempt_count`变量的定义与作用 Linux系统在运行时,总会处于某一种特定的上下文中,如进程上下文、中断上下文等
为了判断系统当前运行的上下文状态,内核提供了`preempt_count`变量来记录当前系统运行的上下文信息
`preempt_count`变量使用不同的位来标识系统上下文状态,包括抢占状态、硬中断上下文、软中断上下文、NMI(非屏蔽中断)上下文等
具体来说,`preempt_count`变量包含以下几个部分: - preempt:用于抢占计数
Linux内核支持进程的抢占调度,但在很多情况下需要禁止抢占
每禁止一次,这个数值就加1,在使能抢占时减1
系统支持的最大嵌套次数为256次
- softirq:记录软中断的嵌套次数
由于软中断在单个CPU上不会嵌套执行,因此仅第8位就可以用来判断当前是否处于软中断上下文中,而其他的9~15位用于表示是否禁用了中断下半部
- hardirq:记录硬中断嵌套次数
在最新版本内核中,由于不再支持中断嵌套,实际只用到了1位,为1则表示处于硬中断上下文中
- NMI:用于指示NMI中断,实际只使用到了1位,因此仅涉及两个状态:发生并处理NMI中断置1,退出中断清除
二、`preempt_count`在不同体系结构下的实现 `preempt_count`变量的意义在各个体系结构上是类似的,但实现方式可能存在差异
以下介绍在x86和ARMv8体系下的实现方式
1. x86体系 在x86体系中,`preempt_count`定义为一个名为`__preempt_count`的Per-CPU变量
这意味着每个CPU都有自己的`preempt_count`变量,以确保多线程环境下的线程安全
DECLARE_PER_CPU(int,__preempt_count); 2. ARMv8体系 在ARMv8体系下,`preempt_count`为定义在`thread_info`结构中的一个变量
`thread_info`结构包含了线程的底层标志位、地址范围、进程核心结构等信息
struct thread_info{ ... union{ u64preempt_count;- / 0 => preemptible, <0 => bug / struct{ ifdefCONFIG_CPU_BIG_ENDIAN u32need_resched; u32 count; else u32 count; u32 need_resched; endif } preempt; }; ... }; 在ARMv8体系下,访问`preempt_count`信息需要通过`thread_info`结构
static inline int preempt_count(void) { returnREAD_ONCE(current_thread_info()->preempt.count); } 三、使用`preempt_count`判断系统上下文 Linux内核定义了一系列的宏,用于判断系统当下所处的上下文,这些宏都基于`preempt_count`变量实现
- `#define hardirq_count()(preempt_count() & HARDIRQ_MASK)` - `#define in_irq() (hardirq_count())` 这些宏使得系统能够方便地判断当前是否处于硬中断上下文、软中断上下文等
四、系统上下文的设置与操作 设置系统上下文其实就是对`preempt_count`变量的相应字段进行配置
针对不同上下文,Linux内核提供了常用的接口定义
1. 内核抢占操作 - 使能抢占:通过preempt_enable()宏实现
如果`preempt_count`减1后为0,并且TIF_NEED_RESCHED标志位被置位,则进行调度抢占
definepreempt_enable() do { if(unlikely(preempt_count_dec_and_test())) __preempt_schedule(); } while(0) - 禁止抢占:通过preempt_disable()宏实现
每调用一次,`preempt_count`加1
definepreempt_disable() do { preempt_count_inc(); barrier(); } while(0) 2. 软中断上下文 - 进入软中断上下文:通过`__local_bh_disable_ip()`函数实现,该函数将`preempt_count`增加一定的值,并关闭中断
- 退出软中断上下文:通过`__local_bh_enable()`函数实现,该函数将`preempt_count`减少相应的值,并重新开启中断
3. 硬中断上下文 硬中断上下文的设置与软中断上下文类似,但由于硬中断在最新版本内核中不再支持嵌套,因此硬中断的处理相对简单
五、`preempt_count`在系统调度中的应用 在支持可抢占内核中,如果唤醒动作发生在系统调用或者异常处理上下文中,在下一次调用`preempt_enable()`时会检查是否需要抢占调度
Hyper-V中文件读取操作指南
Linux系统:深入解析Preempt Count
Xshell5字体大小调整技巧揭秘
VMware虚拟机网络连接全攻略:轻松实现网络互通
VMware vSCA安装指南:轻松上手教程
Hyper-V速度:虚拟化技术的极速之旅
Linux系统:为何离不开localhost?
Linux系统:为何离不开localhost?
Linux系统位数快速查询指南
手机也能装Linux?跨界新体验揭秘
Mac上利用Linux函数绘图技巧
VMware虚拟机中搭建Linux系统详细教程指南
普华Linux:发展历程与未来展望
农行手机银行Linux版尝鲜指南
Linux技巧:高效搜索与换行处理
Linux系统下文件夹快速改名技巧
Fedora系统下安装VMware教程
Linux高效取参技巧大揭秘
Linux系统内存信息打印技巧