中断子系统6_中断嵌套处理

//	current_thread_info()->preempt_count bit划分
//	   /*
//		* - 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 can be overridden per architecture, the default is:
//		*
//		* - bits 16-27 are the hardirq count (max # of hardirqs: 4096)
//		* - ( bit 28 is the PREEMPT_ACTIVE flag. )
//		*
//		* PREEMPT_MASK: 0x000000ff
//		* SOFTIRQ_MASK: 0x0000ff00
//		* HARDIRQ_MASK: 0x0fff0000
//		*/
//		#define PREEMPT_BITS	8
//		#define SOFTIRQ_BITS	8
//
//		#ifndef HARDIRQ_BITS
//		#define HARDIRQ_BITS	12
//		#endif

//		#define PREEMPT_SHIFT	0
//		#define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)	//8
//		#define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)	//16

//		#define __IRQ_MASK(x)	((1UL << (x))-1)
//		#define PREEMPT_MASK	(__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)	//0x000000ff
//		#define HARDIRQ_MASK	(__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)	//0x0000ff00
//		#define SOFTIRQ_MASK	(__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)	//0x0fff0000
//

//		#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 preempt_count()	(current_thread_info()->preempt_count)

//		#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
//		#define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
//		#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))

//		#define in_irq()		(hardirq_count())
//		#define in_softirq()		(softirq_count())
//		#define in_interrupt()		(irq_count())

//		#define add_preempt_count(val)	do { preempt_count() += (val); } while (0)
//		#define sub_preempt_count(val)	do { preempt_count() -= (val); } while (0)

//	中断进入
//		调用路径:do_IRQ->irq_enter
//	函数主要任务:
//		1.递增hardirq嵌套计数
1.1 void irq_enter(void)
{
	do {
		//递增hardirq计数
		add_preempt_count(HARDIRQ_OFFSET);
	} while (0);
}

//	中断退出
//	调用路径:do_IRQ->irq_exit
//	函数主要任务:
//		1.递减hardirq计数
//		2.如果此中断为嵌套路径上最后一个(#(hardirq+softirq)=0),并且此刻有软中断待处理
//			2.1 执行软中断处理函数
//		3.递减抢占计数
//	注:
//		通过sub_preempt_count(IRQ_EXIT_OFFSET)、preempt_enable_no_resched()的配合,实现
//		检查是否有待处理软中断,以及执行
1.2 void irq_exit(void)
{
	//	中断退出路径上对内核抢占的考虑
	//		当支持内核抢占时,CONFIG_PREEMPT=1,此时IRQ_EXIT_OFFSET=(1<<16-1)
	//		preempt_count -= IRQ_EXIT_OFFSET => preempt_count -= (1<<16) + 1  
	//		等价于:
	//			1.递减hardirq计数
	//			2.preempt+1,禁止内核抢占
	sub_preempt_count(IRQ_EXIT_OFFSET);
	//#(softirq+hardirq)=0,有待处理的软中断
	if (!in_interrupt() && local_softirq_pending())
	{
		//执行软中断处理函数
		invoke_softirq();
	}
	//preempt-1,开启内核抢占
	preempt_enable_no_resched();
}
1.3 
#ifdef CONFIG_PREEMPT
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif

#define preempt_enable_no_resched() 
do { 
	barrier(); 
	sub_preempt_count(1); 
} while (0)


原文地址:https://www.cnblogs.com/keanuyaoo/p/3424135.html