欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

linux中斷處理子系統(tǒng)小結 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當前位置>首頁 » 新聞資訊 » 技術分享 >

linux中斷處理子系統(tǒng)小結

發(fā)表時間:2020-10-19

發(fā)布人:葵宇科技

瀏覽次數(shù):60


前面的博文中, 大年夜致分散介紹了一些中斷相干的器械, 然則對軟中斷的部分沒有細心介紹, 在這里同一總結一下.
中斷上半部的處理,匯編到request_irq的handle之間的過程.
http://blog.csdn.net/jackjones_008/article/details/42387241
MIPS平臺的一點記錄
http://blog.csdn.net/jackjones_008/article/details/41945909
tasklet/workqueue的介紹鄙人面這篇博文中有比較具體的介紹.
http://blog.csdn.net/jackjones_008/article/details/42295411
中斷的處理, 起首當然是硬件中斷產(chǎn)生后匯編部分的處理, 然后在hardirq處理完之后, 在函數(shù)irq_exit中, 如不雅發(fā)明當前沒有hardirq并且softirq沒有被禁止,
也沒有pending的本地softirq, 則會顯示的調(diào)用do_softirq 去處理softirq. 在處理softirq的過程中, 是會樊籬硬件中斷的.
asmlinkage void do_softirq(void)
{
	__u32 pending;
	unsigned long flags;

	if (in_interrupt())
		return;

	local_irq_save(flags);

	pending = local_softirq_pending();

	if (pending)
		__do_softirq();

	local_irq_restore(flags);
}

在__do_softirq 瑯綾擎, 在獲得pending的softirq后, 又會打開硬件中斷. 然后會去依次處理pending 的softirq.
這個依次, 其實就是根據(jù)enum中的定義大年夜 HI_SOFTIRQ 履行到 RCU_SOFTIRQ.
再多煩瑣一下, 為什么會有pending的softirq呢, 因為代碼有些處所去調(diào)用了 __raise_softirq_irqoff .
我們還可以留意到, __do_softirq 瑯綾擎定義了一個max_restart, 這個值是10, 是體系的一個折中, 處理軟中斷, 然則不克不及過度的影響其他過程的履行.
完成不了的, 可以交給 ksoftirqd 這個內(nèi)核thread去做.
asmlinkage void __do_softirq(void)
{
	struct softirq_action *h;
	__u32 pending;
	int max_restart = MAX_SOFTIRQ_RESTART;
	int cpu;

	pending = local_softirq_pending();
	account_system_vtime(current);

	__local_bh_disable((unsigned long)__builtin_return_address(0));
	trace_softirq_enter();

	cpu = smp_processor_id();
restart:
	/* Reset the pending bitmask before enabling irqs */
	set_softirq_pending(0);

	local_irq_enable();

	h = softirq_vec;

	do {
		if (pending & 1) {
			int prev_count = preempt_count();

			h->action(h);

			if (unlikely(prev_count != preempt_count())) {
				printk(KERN_ERR "huh, entered softirq %td %p"
				       "with preempt_count %08x,"
				       " exited with %08x?\n", h - softirq_vec,
				       h->action, prev_count, preempt_count());
				preempt_count() = prev_count;
			}

			rcu_bh_qsctr_inc(cpu);
		}
		h++;
		pending >>= 1;
	} while (pending);

	local_irq_disable();

	pending = local_softirq_pending();
	if (pending && --max_restart)
		goto restart;

	if (pending)
		wakeup_softirqd();

	trace_softirq_exit();

	account_system_vtime(current);
	_local_bh_enable();
}

enum
{
	HI_SOFTIRQ=0,
	TIMER_SOFTIRQ,
	NET_TX_SOFTIRQ,
	NET_RX_SOFTIRQ,
	BLOCK_SOFTIRQ,
	TASKLET_SOFTIRQ,
	SCHED_SOFTIRQ,
	HRTIMER_SOFTIRQ,
	RCU_SOFTIRQ,	/* Preferable RCU should always be the last softirq */

	NR_SOFTIRQS
};

接上, restart 中處理完后, 還有pending的softirq的話, 就交給內(nèi)核過程 ksoftirqd 去做. 這個內(nèi)核過程也揮菰式的調(diào)用 do_softirq 去處理.
static int ksoftirqd(void * __bind_cpu)
{
	set_current_state(TASK_INTERRUPTIBLE);

	while (!kthread_should_stop()) {
		preempt_disable();
		if (!local_softirq_pending()) {
			preempt_enable_no_resched();
			schedule();
			preempt_disable();
		}

		__set_current_state(TASK_RUNNING);

		while (local_softirq_pending()) {
			/* Preempt disable stops cpu going offline.
			   If already offline, we'll be on wrong CPU:
			   don't process */
			if (cpu_is_offline((long)__bind_cpu))
				goto wait_to_die;
			do_softirq();
			preempt_enable_no_resched();
			cond_resched();
			preempt_disable();
			rcu_qsctr_inc((long)__bind_cpu);
		}
		preempt_enable();
		set_current_state(TASK_INTERRUPTIBLE);
	}
	__set_current_state(TASK_RUNNING);
	return 0;

wait_to_die:
	preempt_enable();
	/* Wait for kthread_stop */
	set_current_state(TASK_INTERRUPTIBLE);
	while (!kthread_should_stop()) {
		schedule();
		set_current_state(TASK_INTERRUPTIBLE);
	}
	__set_current_state(TASK_RUNNING);
	return 0;
}

這時, 又弗成避免的回到了中斷上半部和下半部的話題, 上半部我們可以懂得為一向履行到 request_irq 中注冊的那個 handle 為止. 而softirq 開端的處理都是屬于下半部的處理.
鄙人半部的處理中, 根據(jù)睡眠與否可以應用tasklet和workqueue的機制.
其實tasklet也是屬于softirq的一種, 并且弗成睡眠. workqueue的機制則是交給了內(nèi)核thread去履行, 可以許可睡眠.

相關案例查看更多