irq: nobody cared (try booting with the “irqpoll” option)


こんにちは!凧のブログですが、


私と一緒に交流することを歓迎します。


IRq 286:nobody cared(try booting with the“irqpoll”option)の前にこのwarningを見て、私はネット上の他の人が書いたのが少しおかしいと思って、手がかゆくて特に記録します:
grepでコードを検索すると、この行の文は:_report_bad_IRq関数:
static inline int bad_action_ret(irqreturn_t action_ret)
{
     
	if (likely(action_ret <= (IRQ_HANDLED | IRQ_WAKE_THREAD)))
		return 0;
	return 1;
}

static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
{
     
	unsigned int irq = irq_desc_get_irq(desc);
	struct irqaction *action;
	unsigned long flags;

	if (bad_action_ret(action_ret)) {
     
		printk(KERN_ERR "irq event %d: bogus return value %x
"
, irq, action_ret); } else { printk(KERN_ERR "irq %d: nobody cared (try booting with " "the \"irqpoll\" option)
"
, irq); } ...... }

bad_action_ret関数が0を返すとき、すなわちaction_ret<=(IRQ_HANDLED|IRQ_WAKE_THREAD)の場合、この印刷があります.
じゃあretパラメータはどこから伝わってきたのですか?上を見続けます.
void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret)
{
     
	unsigned int irq;

	if (desc->istate & IRQS_POLL_INPROGRESS ||
	    irq_settings_is_polled(desc))
		return;

	if (bad_action_ret(action_ret)) {
     // 1, 1 nobody cared log 
		report_bad_irq(desc, action_ret);
		return;
	}
	......
	if (unlikely(action_ret == IRQ_NONE)) {
     
		/*
		 * If we are seeing only the odd spurious IRQ caused by
		 * bus asynchronicity then don't eventually trigger an error,
		 * otherwise the counter becomes a doomsday timer for otherwise
		 * working systems
		 */
		if (time_after(jiffies, desc->last_unhandled + HZ/10))
			desc->irqs_unhandled = 1;
		else
			desc->irqs_unhandled++;
		desc->last_unhandled = jiffies;
	}
	......
		if (unlikely(desc->irqs_unhandled > 99900)) {
     
		/*
		 * The interrupt is stuck
		 */
		__report_bad_irq(desc, action_ret);// 
		/*
		 * Now kill the IRQ
		 */
		printk(KERN_EMERG "Disabling IRQ #%d
"
, irq); desc->istate |= IRQS_SPURIOUS_DISABLED; desc->depth++; irq_disable(desc); mod_timer(&poll_spurious_irq_timer, jiffies + POLL_SPURIOUS_IRQ_INTERVAL); } desc->irqs_unhandled = 0; }

note_interrupt関数はいくつかの重要でないコードを省略した.関数にはaction_retパラメータはIRQ_NONEの場合、irqs_unhandledはカウントを累計しますirqs_unhandledが99900より大きい場合、__が呼び出されます.report_bad_IRq関数は、log:irq xx:nobody cared(try booting with the「irqpoll」option)を印刷する可能性があります.
ここではまだactionを理解していませんretはどこから来たのか、上を見続けます.2つの関数がnoteを呼び出した可能性があります.interrupt関数、1つは:handle_nested_IRq(desc,action_ret)、もう一つはhandle_irq_event_percpu(desc, retval). よく見ると、どの関数でも分かるはずだ、action_retは,書き込みドライバ時に割り込みを登録するコールバック関数である.そしてIRQ_NONEは<=(IRQ_HANDLED|IRQ_WAKE_THREAD)なので、必ずそのlog:irq xx:nobody cared(try booting with the"irqpoll"option)が表示されます
ドライバコードに登録されている割り込みコールバックでIRQが返されたと結論できますNONE、そして割り込みが99900回トリガーされると、このロゴが印刷されます
事実、oopsのスタック情報に基づいて、対応する駆動の割り込み関数を見つけたのは、確かにIRQ_を返したからだ.NONE