前言
在x86 kernel 中断分析三——中断处理流程中,对于线程化中断处理函数,handle_irq_event_percpu调用了irq_wake_thread唤醒action->thread,此处唤醒的thread创建于__setup_irq,代码如下:
947 t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
948 new->name);
...
962 new->thread = t;
本篇分析irq_thread。
irq_thread
参数data是新注册的irqaction
832 /*
833 * Interrupt handler thread
834 */
835 static int irq_thread(void *data)
836 {
837 struct callback_head on_exit_work;
838 struct irqaction *action = data;
839 struct irq_desc *desc = irq_to_desc(action->irq);
840 irqreturn_t (*handler_fn)(struct irq_desc *desc,
841 struct irqaction *action);
842
843 if (force_irqthreads && test_bit(IRQTF_FORCED_THREAD,---------1
844 &action->thread_flags))
845 handler_fn = irq_forced_thread_fn;-----------------------1.1
846 else
847 handler_fn = irq_thread_fn;------------------------------1.2
848
849 init_task_work(&on_exit_work, irq_thread_dtor); ---------------2
850 task_work_add(current, &on_exit_work, false);
851
852 irq_thread_check_affinity(desc, action);-----------------------3
853
854 while (!irq_wait_for_interrupt(action)) {----------------------4
855 irqreturn_t action_ret;
856
857 irq_thread_check_affinity(desc, action);
858
859 action_ret = handler_fn(desc, action);
860 if (action_ret == IRQ_HANDLED)
861 atomic_inc(&desc->threads_handled);
862
863 wake_threads_waitq(desc);--------------------------------5
864 }
865
866 /*
867 * This is the regular exit path. __free_irq() is stopping the
868 * thread via kthread_stop() after calling
869 * synchronize_irq(). So neither IRQTF_RUNTHREAD nor the
870 * oneshot mask bit can be set. We cannot verify that as we
871 * cannot touch the oneshot mask at this point anymore as
872 * __setup_irq() might have given out currents thread_mask
873 * again.