preempt_count
定义
/** low level task data that entry.S needs immediate access to.* __switch_to() assumes cpu_context follows immediately after cpu_domain.*/
struct thread_info {unsigned long flags; /* low level flags */mm_segment_t addr_limit; /* address limit */struct task_struct *task; /* main task structure */struct exec_domain *exec_domain; /* execution domain */struct restart_block restart_block;int preempt_count; /* 0 => preemptable, <0 => bug */int cpu; /* cpu */
};
在支持可抢占的系统中,一个进程的therad_info信息定义如上。其中preempt_count代表的是该进程是否可以被抢占,根据注释的说明当peermpt_count等于0的时候当前进程就可以被抢占,当小于0存在bug,当不等于0也就是大于0说明当前进程不可以被抢占。不可抢占的原因很多,比如当前进程在中断上下文中或者使用了锁(spin_lock的过程中会disable掉抢占的)。至于当前是什么原因不能被抢占,就需要看peermpt_count每个字段的含义。
字段含义
<linux/include/preempt_mask.h>
------------------------------------------
/** We put the hardirq and softirq counter into the preemption* counter. The bitmask has the following meaning:** - bits 0-7 are the preemption count (max preemption depth: 256)* - bits 8-15 are the softirq count (max # of softirqs: 256)** The hardirq count could in theory be the same as the number of* interrupts in the system, but we run all interrupt handlers with* interrupts disabled, so we cannot have nesting interrupts. Though* there are a few palaeontologic drivers which reenable interrupts in* the handler, so we need more than one bit here.** PREEMPT_MASK: 0x000000ff* SOFTIRQ_MASK: 0x0000ff00* HARDIRQ_MASK: 0x000f0000* NMI_MASK: 0x00100000* PREEMPT_ACTIVE: 0x00200000*/
#define PREEMPT_BITS 8
#define SOFTIRQ_BITS 8
#define HARDIRQ_BITS 4
#define NMI_BITS 1
结合上述的示图和代码的定义可知,bit0-7代表的是抢占的次数,最大抢占深度为256次; bit8-15代表的是软中断的次数,最大也是256次; bit16-19表示硬件中断的次数,注释的大概意思是避免中断嵌套,但是也不能防止某些驱动中嵌套使用中断,所以嵌套16层也是最大次数了。bit20代表NMI中断,bit21代表当前抢占是否active。
相关宏定义
#define PREEMPT_SHIFT 0
#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) //0+8=8
#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) //8+8=16
#define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS) //16+4=20#define __IRQ_MASK(x) ((1UL << (x))-1)#define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
#define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
#define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
#define NMI_MASK (__IRQ_MASK(NMI_BITS) << NMI_SHIFT)#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) //1<<0
#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) //1<<8
#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) //1<<16
#define NMI_OFFSET (1UL << NMI_SHIFT) //1<<20#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET) //16#define PREEMPT_ACTIVE_BITS 1
#define PREEMPT_ACTIVE_SHIFT (NMI_SHIFT + NMI_BITS)
#define PREEMPT_ACTIVE (__IRQ_MASK(PREEMPT_ACTIVE_BITS) << PREEMPT_ACTIVE_SHIFT)#define hardirq_count() (preempt_count() & HARDIRQ_MASK) //硬中断count
#define softirq_count() (preempt_count() & SOFTIRQ_MASK) //软中断count
#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \| NMI_MASK)) //所有中断=硬+软+NMI
从上述的定义可以得出,如果想知道硬中断的次数就使用hardirq_count, 如果想知道软中断次数就使用softirq_count, 如果想知道所有中断的次数就使用irq_count。
各种上下文
/** Are we doing bottom half or hardware interrupt processing?* Are we in a softirq context? Interrupt context?* in_softirq - Are we currently processing softirq or have bh disabled?* in_serving_softirq - Are we currently processing softirq?*/
#define in_irq() (hardirq_count())
#define in_softirq() (softirq_count())
#define in_interrupt() (irq_count())
#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET)
其中in_irq用于判断当前进程是否在硬中断中; in_softirq用于判断是否当前进程在软件中断或者有别的进程disable了软中断
#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
使用上述的宏判断当前进程是否处于原子操作中。
preempt_count相关推荐
- preempt_count详解
当从内核态返回到用户态的时候,要检查是否进行调度,而调度要看两个条件: 1.preempt_count是否为0 2.rescheduled是否置位 ret_from_exception: preem ...
- preempt_count分析
kernel通过preempt_count变量来判断是否处于中断(soft/hard/nmi)上下文,是否可以抢占,先看示例 #define in_irq() (hardirq_count()) #d ...
- Kernel: x86: preempt_count, per-cpu(每个CPU一份的变量)
文章目录 源码位置 preempt_count 使用的地方 saved_preempt_count 源码位置 arch/x86/include/asm/preempt.h 在include/asm-g ...
- [Linux内核]软中断与硬中断
转自:http://blog.csdn.net/zhangskd/article/details/21992933 本文主要内容:硬中断 / 软中断的原理和实现 内核版本:2.6.37 Author: ...
- Linux内核跟踪之trace框架分析【转】
转自:http://blog.chinaunix.net/uid-20543183-id-1930846.html ------------------------------------------ ...
- Linux进程管理 (7)实时调度
关键词:RT.preempt_count.RT patch. 除了CFS调度器之外,还包括重要的实时调度器,有两种RR和FIFO调度策略.本章只是一个简单的介绍. 更详细的介绍参考<Linux进 ...
- 使用 ftrace 调试 Linux 内核【转】
转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...
- 关于might_sleep的一点说明【转】
转自:http://blog.csdn.net/chen_chuang_/article/details/48462575 这个函数我在看代码时基本上是直接忽略的(因为我知道它实际上不干什么事),不过 ...
- linux --- 进程调度
2019独角兽企业重金招聘Python工程师标准>>> Linux进程调度笔记 一:Linux进程的四大要素 1:一段供进程执行的程序,该程序可以被多个进程执行. 2:独立的内核堆栈 ...
- Linux内核抢占实现机制分析【转】
Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...
最新文章
- 蓝牙模块与电脑无线通信--AD测量大电压
- 语音基础知识-基本语音知识,声谱图,log梅普图,MFCC,deltas详解
- 转载:Pixhawk源码笔记七:姿态控制预览
- 【mysql安装】阿里云centos7环境mysql安装
- Win10设置防火墙,使局域网能访问此电脑的Tomcat服务
- python带我起飞 百度云_CentOS/Debian安装人人影视客户端,下载资源并自动上传到OneDrive网盘...
- Java的throws Exception
- 产品经理职场面试35个经典问题
- 2008最火爆的十大网络流行语
- 编程比赛三大赛制介绍(ACM赛制、OI赛制、IOI赛制)
- VSCode格式化JS自动添加或去掉分号
- python学习笔记——语法基础
- 网络 随笔 1-再补充一丢丢常识
- 知乎高赞的7个顶级资源网站,记住了帮你减少一半的搜索时间
- WinEdt Latex 在字母上加两个点
- 最高补贴1000元/kW,山东光伏补贴来了
- 追源索骥:透过源码看懂Flink核心框架的执行流程--来自GitHub
- 【web渗透思路】框架敏感信息泄露(特点、目录、配置)
- XXX测试用例设计?XXX怎么测试?(行李箱、电梯、水杯、笔、椅子)
- java源码模拟面试解析指南,快手支付中台java面试题