强制中断线程化threadirqs

kernel 提供了一个命令行参数threadirqs,这个参数会让irq 中断强制运行在thread context,这个时候不管用户是否
设置中断线程化,都强制让中线运行在线程上下文中.
static int __init setup_forced_irqthreads(char *arg)
{
	force_irqthreads = true;
	return 0;
}
early_param("threadirqs", setup_forced_irqthreads);
当命令行加threadirqs时,则setup_forced_irqthreads等于true
当调用request_threaded_irq->__setup_irq 申请中断时
static int
__setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
{
	struct irqaction *old, **old_ptr;
	unsigned long flags, thread_mask = 0;
	int ret, nested, shared = 0;

#检查是否中断中嵌套中中断,从这里看kernel是支持中断嵌套的
	nested = irq_settings_is_nested_thread(desc);
	if (nested) {
		if (!new->thread_fn) {
			ret = -EINVAL;
			goto out_mput;
		}
		/*
		 * Replace the primary handler which was provided from
		 * the driver for non nested interrupt handling by the
		 * dummy function which warns when called.
		 */
		new->handler = irq_nested_primary_handler;
	} else {
#这里检查是否强制中断线程化
		if (irq_settings_can_thread(desc)) {
			ret = irq_setup_forced_threading(new);
			if (ret)
				goto out_mput;
		}
	}
}
一般我们都不设置_IRQ_NOTHREAD,所以if (irq_settings_can_thread(desc)) 返回true 进入到irq_setup_forced_threading
static inline bool irq_settings_can_thread(struct irq_desc *desc)
{
	return !(desc->status_use_accessors & _IRQ_NOTHREAD);
}


static int irq_setup_forced_threading(struct irqaction *new)
{
#可以看到如果没有通过命令行设置force_irqthreads 为ture的话,这里就返回了
	if (!force_irqthreads)
		return 0;
	if (new->flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT))
		return 0;
	
	/* Deal with the primary handler */
	set_bit(IRQTF_FORCED_THREAD, &new->thread_flags);
	new->thread_fn = new->handler;
#设置中断线程化的话,需要让中断线程返回IRQ_WAKE_THREAD,这样就会调用原本中断的callback函数new->handler
	new->handler = irq_default_primary_handler;
	return 0;
}
这个函数将在中断环境中执行,而用户设置的真正的中断回调函数却在线程上线文中执行
static irqreturn_t irq_default_primary_handler(int irq, void *dev_id)
{
	return IRQ_WAKE_THREAD;
}

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/109983169
今日推荐