中断线程化的注册

devm_request_threaded_irq->request_threaded_irq->__setup_irq 中的下面这段code中可以看到中断线程化设置的过程
	/*
	 * Create a handler thread when a thread function is supplied
	 * and the interrupt does not nest into another interrupt
	 * thread.
	 */
//if条件成立,所以继续调用setup_irq_thread,从这里看中断线程化其实可以设置两个线程
	if (new->thread_fn && !nested) {
		ret = setup_irq_thread(new, irq, false);
		if (ret)
			goto out_mput;
		if (new->secondary) {
			ret = setup_irq_thread(new->secondary, irq, true);
			if (ret)
				goto out_thread;
		}
	}
这里继续看setup_irq_thread
static int
setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
{
	struct task_struct *t;
	struct sched_param param = {
		.sched_priority = MAX_USER_RT_PRIO/2,
	};
//这里假定secondary为null,因此调用kthread_create 创建一个thread.
	if (!secondary) {
		t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
				   new->name);
	} else {
		t = kthread_create(irq_thread, new, "irq/%d-s-%s", irq,
				   new->name);
		param.sched_priority -= 1;
	}

	if (IS_ERR(t))
		return PTR_ERR(t);
//haha 从这里可以看出这个thread的调度策略是SCHED_FIFO
	sched_setscheduler_nocheck(t, SCHED_FIFO, ¶m);

	/*
	 * We keep the reference to the task struct even if
	 * the thread dies to avoid that the interrupt code
	 * references an already freed task_struct.
	 */
	get_task_struct(t);
	new->thread = t;
	/*
	 * Tell the thread to set its affinity. This is
	 * important for shared interrupt handlers as we do
	 * not invoke setup_affinity() for the secondary
	 * handlers as everything is already set up. Even for
	 * interrupts marked with IRQF_NO_BALANCE this is
	 * correct as we want the thread to move to the cpu(s)
	 * on which the requesting code placed the interrupt.
	 */
	set_bit(IRQTF_AFFINITY, &new->thread_flags);
	return 0;
}
注意这里只是创建thread ,这时候thread并没有运行,知道irq的回调函数返回IRQ_WAKE_THREAD的时候,才会通过__irq_wake_thread 来运行这个thread
最终处理中断的函数为  
irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags)  
{  
    irqreturn_t retval = IRQ_NONE;  
    unsigned int irq = desc->irq_data.irq;  
    struct irqaction *action;  
  
    record_irq_time(desc);  
  
    for_each_action_of_desc(desc, action) {  
        irqreturn_t res;  
  
        trace_irq_handler_entry(irq, action);  
//这里会执行irq的回调函数,可以看到只有这里返回IRQ_WAKE_THREAD,才会调用__irq_wake_thread 来运行中断的线程  
        res = action->handler(irq, action->dev_id);  
        trace_irq_handler_exit(irq, action, res);  
  
        if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n",  
                  irq, action->handler))  
            local_irq_disable();  
  
        switch (res) {  
        case IRQ_WAKE_THREAD:  
            /*  
             * Catch drivers which return WAKE_THREAD but  
             * did not set up a thread function  
             */  
            if (unlikely(!action->thread_fn)) {  
                warn_no_thread(irq, action);  
                break;  
            }  
//__irq_wake_thread->wake_up_process 来wakeup在调用devm_request_threaded_irq时候为线程建立的thread  
            __irq_wake_thread(desc, action);  
  
            /* Fall through to add to randomness */  
        case IRQ_HANDLED:  
            *flags |= action->flags;  
            break;  
  
        default:  
            break;  
        }  
  
        retval |= res;  
    }  
  
    return retval;  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值