您的位置:首页 > 运维架构 > Linux

linux 中断处理 tasklet workqueue

2012-04-16 10:24 429 查看
linux中注册中断历程用request_irq,isr原型为: irqreturn_t *(int irq, void* dev_id, struct pt_reg* regs)

为了使中断关闭的时间尽可能的短,linux提出了中断上半部和下半部。上半部为request_irq注册的ISR,要求时间尽可能的短,而将尽可能的工作推迟到下半部去做。下半部由上半部调度,并在安全的时间内执行,此时中断已经打开了。linux有两种机制可以实现下半部:tasket和workqueue。

tasklet为软中断的一种。linux内核有HI_SOFTIRQ, TIMER, NET_TX, NET_RX, BLOCK, TASKLET, SCHED, HRTIMER, RCU 等软中断, 在系统初始化时调用open_softirq注册。在isr中声明tasklet,然后函数tasklet_schedule()调用raise_softirq(TASKLET_IRQ),然后系统在合适的时间调度tasklet运行。

workqueue本质为内核线程。

create_workqueue -> create_workqueue_thread

|| |->kthread_create(worker_thread) // worker_thread 检查work_list,如果非空则依次执行起func

|| |->设置kthread_create_list,然后唤醒kthreadd_task(负责检查kthread_create_list,如果非空则调用kernel_thread创建内核线程)

|| -> start_workqueue_thread

||-> wake_up_process(kthread_create返回的worker_thread) //通过设置task->state=RUNNING使得下次可以调度到。

schedule_work = queue_work(eventd_wq, work) // eventd_wq 为系统初始化时创建的workqueue。用户可以用create_workqueue创建自己的workqueue。

tasklet中不允许休眠,而workqueue允许。tasklet调用时为中断上下文,workque为进程上下文(仅有内核代码)。

linux 中的timer 即采用了中断和softirq的机制实现的。在时钟中断例程 timer_interrupt中调用do_timer_interrupt,更新jiffies,检查进程时间片,设置TIMER_SOFTIRQ并调用timer的软中断(在这里处理与timer有关的tvec_base),最后统计信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: