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分析相关推荐

  1. Linux内核跟踪之trace框架分析【转】

    转自:http://blog.chinaunix.net/uid-20543183-id-1930846.html ------------------------------------------ ...

  2. Linux内核抢占实现机制分析【转】

    Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...

  3. linux lock函数,Linux lock_kernel()函数的分析。

    这只是暂时的记录,以后会把它归类到start_kernel()函数的分析.在分析之前,我先要说说几个概念. 内核抢占:在2.6内核加入了抢占的能力,就是说调度程序有办法在一个内核级的任务正在执行的时候 ...

  4. Linux2.6 内核进程调度分析

    Linux2.6 内核进程调度分析    进程的调度时机与引起进程调度的原因和进程调度的方式有关.在 2.6 中,除核心应用     主动调用调度器之外, 核心还在应用不完全感知的情况下在以下三种时机 ...

  5. kernel 3.10内核源码分析--中断--中断和异常返回流程

    一.问题 1.内核调度与中断/异常/系统调用的关系如何? 2.信号处理与中断/异常/系统调用的关系如何? 3.内核抢占与中断/异常/系统调用的关系如何? 4.内核线程的调度有何特别之处?中断/异常/系 ...

  6. 2018-2019-1 20189201 《LInux内核原理与分析》第九周作业

    那一天我二十一岁,在我一生的黄金时代.我有好多奢望.我想爱,想吃,还想在一瞬间变成天上半明半暗的云.那一年我二十一岁,在我一生的黄金时代.我有好多想法.我思索,想象,我不知该如何行动,我想知道一个城市 ...

  7. 内核进程切换实现分析

    当我们在linux编写用户态程序时并不需要考虑进程间是如何切换的, 即使当我们编写驱动程序时也只需调用一些阻塞接口来让渡cpu. 但是cpu究竟是如何切换进程的, 在进程切换过程中需要做什么, 今天我 ...

  8. Linux内核态抢占机制分析

    http://blog.sina.com.cn/s/blog_502c8cc401012pxj.html [摘要]本文首先介绍非抢占式内核(Non-Preemptive Kernel)和可抢占式内核( ...

  9. Linux Kernel Oops异常分析

    0.linux内核异常常用分析方法 异常地址是否在0附近,确认是否是空指针解引用问题 异常地址是否在iomem映射区,确认是否是设备访问总线异常问题,如PCI异常导致的地址访问异常 异常地址是否在st ...

最新文章

  1. 什么?你还在使用fastjson,性能太差了
  2. Java程序设计第二次作业
  3. 3、 PPT合并形状
  4. 选购个人计算机小结,计算机实训小结精选 .doc
  5. 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像
  6. Java设计模式之结构型:装饰器模式
  7. mysql缺少函数_Sqlserver的窗口函数的精彩应用之数据差距与数据岛-答案篇
  8. 正常情况下ffmpeg生成moov是在mdat写完成之后写入
  9. 智慧城市落地难的原因分析
  10. 对X264/FFMPEG架构探讨---感觉不错
  11. 判断是否存在此对象_JVM的垃圾回收机制,判断对象是否死亡
  12. 【Flink】Flink KeyGroupRange {startKeyGroup=7,endKeyGroup=12} does not contain key group 45
  13. 揭秘:导致局域网网速变慢的五大真凶
  14. java pixel data_java - JavaFX PixelWriter性能低下
  15. 微信表情包储服务器,新发现!微信里的表情包,终于能保存到手机和电脑辣!-qq表情在哪个文件夹里...
  16. WPS Office 11.1.0.10314 免费完整版
  17. 【spring事务管理】
  18. 基于simulink的六足机器人模型仿真
  19. 生活随记-如何健康摄入果糖
  20. hihoCoder #1079 离散化

热门文章

  1. 从红包大战看银行与微信支付宝差距
  2. 嵌入式接口技术(一)GPIO
  3. android 微信登录返回 -6
  4. Equalized Focal Loss for Dense Long Tailed Object Detection 论文解读
  5. 采购订单的审批制作完整版
  6. CLion-控制台输出中文乱码
  7. Linux物理网络和虚拟网络对比
  8. 苹果经典提示音_macOS Big Sur带回了经典的启动提示音
  9. Pix2Pix原理解析以及代码流程
  10. 如何“阻止”程序员上班摸鱼?