critical section 中断唤醒系统流程(7)

电脑杂谈  发布时间:2018-02-14 08:19:38  来源:网络整理

clear_bit(irq, irqs_resend);

desc = irq_to_desc(irq);

local_irq_disable();

desc->handle_irq(desc);

local_irq_enable();

}

}

/* Tasklet to handle resend: */

static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);

1) irqs_resend是一个unsigned int类型的数组,每一个bit都代表一个irq是否resend。

2) resend_irqs是注册的resend_tasklet的callback函数,当tasklet_schedule(&resend_tasklet)之后就会被调度执行。

3) 在resend_irqs函数中,通过判断irqs_resend变量中的每一个bit位是否为1(即是否需要resend,也就是调用irq注册的中断handle)。

好了,现在可以解答清楚的解答第一个问题了:设备唤醒cpu之后是立即跳转中断向量表指定的位置吗?如果不是,那么是什么时候才会跳转呢?设备唤醒cpu之后并不是立即跳转中断向量执行中断,而是等到syscore_resume以及打开cpu中断之后才开始。第二个问题也有答案了,已经跳转到中断服务函数开始执行代码,后续就会调用你注册的中断handle 吗?如果不是,那中断服务函数做什么准备呢?而你注册的中断handle又会在什么时候才开始执行呢?第一次跳转执行中断仅仅是设置相关的flag并且disable_irq,在执行完成设备的resume noirq回调函数之后通过check_irq_resend中调度tasklet,最终执行注册的中断handle,至于为什么要这么做,前面分析也给了答案。

2.7. IRQ handler会睡眠吗?

你想过request_thread_irq函数注册的hardirq handler或者是threaded handler会执行一半时,系统会再一次的休眠下去吗?再看看2.2节的图,实际上对于所有已经打开的irq在suspend_device_irqs()会调用synchronize_irq()等待正在处理的hardirq handler或者threaded handler。synchronize_irq()代码如下:

void synchronize_irq(unsigned int irq)

{

struct irq_desc *desc = irq_to_desc(irq);

if (desc) {

__synchronize_hardirq(desc);

/*

* We made sure that no hardirq handler is

* running. Now verify that no threaded handlers are

* active.

*/

wait_event(desc->wait_for_threads,

!atomic_read(&desc->threads_active));

}

}

1)__synchronize_hardirq()是等待hardirq handler执行完毕。

2)只要threads_active计数不为0就,等待threaded handler执行完毕。

__synchronize_hardirq()代码如下:

static void __synchronize_hardirq(struct irq_desc *desc)


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-77052-7.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...