preempt_count分析
kernel通过preempt_count变量来判断是否处于中断(soft/hard/nmi)上下文,是否可以抢占,先看示例
#define in_irq() (hardirq_count())
#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
static __always_inline int preempt_count(void)
{return current_thread_info()->preempt_count;
}static inline struct thread_info *current_thread_info(void) __attribute_const__;struct thread_info {unsigned long flags; /* low level flags */int preempt_count; /* 0 => preemptable, <0 => bug */mm_segment_t addr_limit; /* address limit */struct task_struct *task; /* main task structure */__u32 cpu; /* cpu */__u32 cpu_domain; /* cpu domain */struct cpu_context_save cpu_context; /* cpu context */__u32 syscall; /* syscall number */__u8 used_cp[16]; /* thread used copro */unsigned long tp_value[2]; /* TLS registers */
#ifdef CONFIG_CRUNCHstruct crunch_state crunchstate;
#endifunion fp_state fpstate __attribute__((aligned(8)));union vfp_state vfpstate;
#ifdef CONFIG_ARM_THUMBEEunsigned long thumbee_state; /* ThumbEE Handler Base register */
#endif
};
preempt_count具体定义
linux/preempt.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_NEED_RESCHED: 0x80000000*/
#define PREEMPT_BITS 8
#define SOFTIRQ_BITS 8
#define HARDIRQ_BITS 4
#define NMI_BITS 1#define PREEMPT_SHIFT 0
#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS)
#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
#define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS)#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)
#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
#define NMI_OFFSET (1UL << NMI_SHIFT)#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET)/* We use the MSB mostly because its available */
#define PREEMPT_NEED_RESCHED 0x80000000/* preempt_count() and related functions, depends on PREEMPT_NEED_RESCHED */
#include <asm/preempt.h>#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \| NMI_MASK))/** Are we doing bottom half or hardware interrupt processing?** in_irq() - We're in (hard) IRQ context* in_softirq() - We have BH disabled, or are processing softirqs* in_interrupt() - We're in NMI,IRQ,SoftIRQ context or have BH disabled* in_serving_softirq() - We're in softirq context* in_nmi() - We're in NMI context* in_task() - We're in task context** Note: due to the BH disabled confusion: in_softirq(),in_interrupt() really* should not be used in new code.*/
#define in_irq() (hardirq_count())
#define in_softirq() (softirq_count())
#define in_interrupt() (irq_count())
#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET)
#define in_nmi() (preempt_count() & NMI_MASK)
#define in_task() (!(preempt_count() & \(NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET)))
NMI (Non Maskable Interrupt)
硬中断会有如下流程,如PPI和SPI
int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,bool lookup, struct pt_regs *regs)
{irq_enter();irq = irq_find_mapping(domain, hwirq);generic_handle_irq(irq);irq_exit();}void irq_enter(void){preempt_count_add(HARDIRQ_OFFSET);
}void irq_exit(void)
{preempt_count_sub(HARDIRQ_OFFSET);
}
软中断处理函数
asmlinkage __visible void __softirq_entry __do_softirq(void)
{__local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);
restart:........................................__local_bh_enable(SOFTIRQ_OFFSET);
}static __always_inline void __local_bh_disable_ip(unsigned long ip, unsigned int cnt)
{preempt_count_add(cnt);
}
static void __local_bh_enable(unsigned int cnt)
{preempt_count_sub(cnt);
}
#define preempt_disable() \
do { \preempt_count_inc(); \barrier(); \
} while (0)
#define preempt_enable() \
do { \barrier(); \if (unlikely(preempt_count_dec_and_test())) \__preempt_schedule(); \
} while (0)
preempt_count分析相关推荐
- Linux内核跟踪之trace框架分析【转】
转自:http://blog.chinaunix.net/uid-20543183-id-1930846.html ------------------------------------------ ...
- Linux内核抢占实现机制分析【转】
Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...
- linux lock函数,Linux lock_kernel()函数的分析。
这只是暂时的记录,以后会把它归类到start_kernel()函数的分析.在分析之前,我先要说说几个概念. 内核抢占:在2.6内核加入了抢占的能力,就是说调度程序有办法在一个内核级的任务正在执行的时候 ...
- Linux2.6 内核进程调度分析
Linux2.6 内核进程调度分析 进程的调度时机与引起进程调度的原因和进程调度的方式有关.在 2.6 中,除核心应用 主动调用调度器之外, 核心还在应用不完全感知的情况下在以下三种时机 ...
- kernel 3.10内核源码分析--中断--中断和异常返回流程
一.问题 1.内核调度与中断/异常/系统调用的关系如何? 2.信号处理与中断/异常/系统调用的关系如何? 3.内核抢占与中断/异常/系统调用的关系如何? 4.内核线程的调度有何特别之处?中断/异常/系 ...
- 2018-2019-1 20189201 《LInux内核原理与分析》第九周作业
那一天我二十一岁,在我一生的黄金时代.我有好多奢望.我想爱,想吃,还想在一瞬间变成天上半明半暗的云.那一年我二十一岁,在我一生的黄金时代.我有好多想法.我思索,想象,我不知该如何行动,我想知道一个城市 ...
- 内核进程切换实现分析
当我们在linux编写用户态程序时并不需要考虑进程间是如何切换的, 即使当我们编写驱动程序时也只需调用一些阻塞接口来让渡cpu. 但是cpu究竟是如何切换进程的, 在进程切换过程中需要做什么, 今天我 ...
- Linux内核态抢占机制分析
http://blog.sina.com.cn/s/blog_502c8cc401012pxj.html [摘要]本文首先介绍非抢占式内核(Non-Preemptive Kernel)和可抢占式内核( ...
- Linux Kernel Oops异常分析
0.linux内核异常常用分析方法 异常地址是否在0附近,确认是否是空指针解引用问题 异常地址是否在iomem映射区,确认是否是设备访问总线异常问题,如PCI异常导致的地址访问异常 异常地址是否在st ...
最新文章
- 什么?你还在使用fastjson,性能太差了
- Java程序设计第二次作业
- 3、 PPT合并形状
- 选购个人计算机小结,计算机实训小结精选 .doc
- 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像
- Java设计模式之结构型:装饰器模式
- mysql缺少函数_Sqlserver的窗口函数的精彩应用之数据差距与数据岛-答案篇
- 正常情况下ffmpeg生成moov是在mdat写完成之后写入
- 智慧城市落地难的原因分析
- 对X264/FFMPEG架构探讨---感觉不错
- 判断是否存在此对象_JVM的垃圾回收机制,判断对象是否死亡
- 【Flink】Flink KeyGroupRange {startKeyGroup=7,endKeyGroup=12} does not contain key group 45
- 揭秘:导致局域网网速变慢的五大真凶
- java pixel data_java - JavaFX PixelWriter性能低下
- 微信表情包储服务器,新发现!微信里的表情包,终于能保存到手机和电脑辣!-qq表情在哪个文件夹里...
- WPS Office 11.1.0.10314 免费完整版
- 【spring事务管理】
- 基于simulink的六足机器人模型仿真
- 生活随记-如何健康摄入果糖
- hihoCoder #1079 离散化