免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 13835 | 回复: 16
打印 上一主题 下一主题

底半部机制:tasklet、工作队列、软中断 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-29 16:46 |只看该作者 |倒序浏览
6可用积分
谁能形象通俗地、详细地讲解一下三种底半部机制:tasklet、工作队列、软中断?
以及“软中断和tasklet运行于中断上下文,而工作队列则运行于进程上下文。因此,软中断和tasklet处理函数中不能睡眠,而工作队列处理函数中允许睡眠”。

最佳答案

查看完整内容

2.6 的linux kernel最多可以使用32中softirq,见代码:linux中实际使用的六种:对于softirq,linux kernel中是在中断处理程序执行的,具体的路径为:在__do_softirq()中有这么一段代码:你看,这里就是对softirq进行处理了,因为pengding是一个__u32的类型,所以每一位都对应了一种softirq,正好是32种(linux kernel中实际上只使用了前6种 ).h->action(h),就是运行softirq的处理函数。对于tasklet,前面已经说了,是一种特殊的so ...

论坛徽章:
0
2 [报告]
发表于 2009-04-29 16:46 |只看该作者
原帖由 todayrw 于 2009-4-30 10:31 发表
有关工作队列还能够理解。
但关于软中断和tasklet之间的区别和联系还很模糊。
你说“能用tasklet的最好不要用软中断”,而书上又说“tasklet是基于软中断实现的”,但书上对软中断本身是怎么实现的也没有描述清楚。
可否对软中断和tasklet之间的区别和联系做一些答复,谢谢!

2.6 的linux kernel最多可以使用32中softirq,见代码:

  1. softirq.c

  2. /*表示softirq最多可以有32种类型,实际上linux只使用了六种,见文件interrupt.h*/
  3. static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp;
复制代码


linux中实际使用的六种:

  1. interrupt.h

  2. enum
  3. {
  4.         HI_SOFTIRQ=0,   /*用于高优先级的tasklet*/
  5.         TIMER_SOFTIRQ, /*用于定时器的下半部*/
  6.         NET_TX_SOFTIRQ,/*用于网络层发包*/
  7.         NET_RX_SOFTIRQ, /*用于网络层收报*/
  8.         SCSI_SOFTIRQ,   /*用于scsi设备*/
  9.         TASKLET_SOFTIRQ /*用于低优先级的tasklet*/
  10. };
复制代码


对于softirq,linux kernel中是在中断处理程序执行的,具体的路径为:

  1. do_IRQ() --> irq_exit() --> invoke_softirq() --> do_softirq() --> __do_softirq()
复制代码


在__do_softirq()中有这么一段代码:

  1.         do {
  2.                 if (pending & 1) {
  3.                         h->action(h);
  4.                         rcu_bh_qsctr_inc(cpu);
  5.                 }
  6.                 h++;
  7.                 pending >>= 1;
  8.         } while (pending);
复制代码

你看,这里就是对softirq进行处理了,因为pengding是一个__u32的类型,所以每一位都对应了一种softirq,正好是32种(linux kernel中实际上只使用了前6种 ).
h->action(h),就是运行softirq的处理函数。

对于tasklet,前面已经说了,是一种特殊的softirq,具体就是第0和第5种softirq,所以说tasklet是基于softirq来实现的。
tasklet既然对应第0和第5种softirq,那么就应该有对应的处理函数,以便h->action()会运行tasklet的处理函数。
我们看代码:

  1. softirq.c

  2. void __init softirq_init(void)  
  3. {
  4.         open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);
  5.         open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL);
  6. }
复制代码

这里注册了两种tasklet所在的softirq的处理函数,分别对应高优先级的tasklet和低优先级的tasklet。

我们看低优先级的吧(高优先级的也一样)。

  1. static void tasklet_action(struct softirq_action *a)
  2. {
  3.         struct tasklet_struct *list;

  4.         local_irq_disable();
  5.         list = __get_cpu_var(tasklet_vec).list;
  6.         __get_cpu_var(tasklet_vec).list = NULL;
  7.         local_irq_enable();

  8.         while (list) {
  9.                 struct tasklet_struct *t = list;

  10.                 list = list->next;

  11.                 if (tasklet_trylock(t)) {
  12.                         if (!atomic_read(&t->count)) {
  13.                                 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
  14.                                         BUG();
  15.                                 t->func(t->data);
  16.                                 tasklet_unlock(t);
  17.                                 continue;
  18.                         }
  19.                         tasklet_unlock(t);
  20.                 }

  21.                 local_irq_disable();
  22.                 t->next = __get_cpu_var(tasklet_vec).list;
  23.                 __get_cpu_var(tasklet_vec).list = t;
  24.                 __raise_softirq_irqoff(TASKLET_SOFTIRQ);  
  25.                 local_irq_enable();
  26.         }
  27. }
复制代码

你看,在运行softirq的处理时(__do_softirq),对于

  1.         do {
  2.                 if (pending & 1) {
  3.                         h->action(h);
  4.                         rcu_bh_qsctr_inc(cpu);
  5.                 }
  6.                 h++;
  7.                 pending >>= 1;
  8.         } while (pending);
复制代码

如果tasklet有任务需要处理,会运行到h->action(),这个函数指针就会指向tasklet_action(),然后在tasklet_action()里再去执行tasklet对应的各个任务,这些任务都是挂在一个全局链表里面的,具体的代码这里就不分析了。

另外, softirq在smp中是可能被同时运行的,所以softirq的处理函数必须被编写成可重入的函数。
但tasklet是不会在多个cpu之中同时运行的,所以tasklet的处理函数可以编写成不可重入的函数,这样就减轻了编程人员的负担。

不知道这样写,LZ看明白了没有?

论坛徽章:
0
3 [报告]
发表于 2009-04-29 17:07 |只看该作者
自己顶一下,大家讨论讨论吧

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
4 [报告]
发表于 2009-04-29 19:10 |只看该作者

回复 #1 todayrw 的帖子

你是想讨论这几种机制的区别么?

论坛徽章:
0
5 [报告]
发表于 2009-04-30 09:30 |只看该作者

回复 #3 dreamice 的帖子

是的,还有这句话“软中断和tasklet运行于中断上下文,而工作队列则运行于进程上下文。因此,软中断和tasklet处理函数中不能睡眠,而工作队列处理函数中允许睡眠”。

论坛徽章:
0
6 [报告]
发表于 2009-04-30 09:40 |只看该作者
可能Lz需要找本书,搞清楚进程是什么,中断是什么,他们之间是否有关系。
搞清楚了这些,tasklet、工作队列、软中断之间的区别和联系,看《linux kernel development》就很简单了。

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
7 [报告]
发表于 2009-04-30 09:49 |只看该作者
原帖由 todayrw 于 2009-4-30 09:30 发表
是的,还有这句话“软中断和tasklet运行于中断上下文,而工作队列则运行于进程上下文。因此,软中断和tasklet处理函数中不能睡眠,而工作队列处理函数中允许睡眠”。


有句话是这样的:能用tasklet的最好不要用软中断。
工作队列(work queue)是Linux kernel中将工作推后执行的一种机制。这种机制和BH或Tasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠,它和软中断与tasklet的区别表现在以下几方面:
1、tasklet 在软件中断上下文中运行的结果是所有的 tasklet 代码必须是原子的. 相反, 工作队列函数在一个特殊内核进程上下文运行; 结果, 它们有更多的灵活性. 特别地, 工作队列函数能够睡眠.

2、tasklet 常常在它们最初被提交的处理器上运行. 工作队列以相同地方式工作, 缺省地

3、内核代码可以请求工作队列函数被延后一个明确的时间间隔
两者之间关键的不同是 tasklet 执行的很快, 短时期, 并且在原子态, 而工作队列函数可能有高周期但是不需要是原子的. 每个机制有它适合的情形

论坛徽章:
0
8 [报告]
发表于 2009-04-30 10:31 |只看该作者

回复 #6 dreamice 的帖子

有关工作队列还能够理解。
但关于软中断和tasklet之间的区别和联系还很模糊。
你说“能用tasklet的最好不要用软中断”,而书上又说“tasklet是基于软中断实现的”,但书上对软中断本身是怎么实现的也没有描述清楚。
可否对软中断和tasklet之间的区别和联系做一些答复,谢谢!

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
9 [报告]
发表于 2009-04-30 10:50 |只看该作者

回复 #7 todayrw 的帖子

关于软中断和tasklet,我记得是这样的:
1、相同的软中断和tasklet在不同CPU(SMP的情况)上都不能并发的执行;
2、不同的软中断不能在不同的CPU上并发执行;
3、不通的tasklet可以在不同的CPU上并发执行。

论坛徽章:
0
10 [报告]
发表于 2009-04-30 15:00 |只看该作者

回复 #2 new_learner 的帖子

明白了!谢谢!讲得很详细!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP