博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
软中断和tasklet
阅读量:6231 次
发布时间:2019-06-21

本文共 2270 字,大约阅读时间需要 7 分钟。

.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的处理函数可以编写成不可重入的函数,这样就减轻了编程人员的负担。

转载于:https://www.cnblogs.com/li-hao/archive/2012/03/08/2385919.html

你可能感兴趣的文章
linux(6.8版本最小化安装)安装nginx实战
查看>>
我的友情链接
查看>>
检讨~
查看>>
html引用公共的html文件
查看>>
关于Java泛型使用的问题记录
查看>>
进入Android Dalvik虚拟机之Dalvik虚拟机的特点
查看>>
while的四种使用方式
查看>>
nginx添加几十个域名
查看>>
SpringMVC同时支持多视图(JSP,Velocity,Freemarker等)的一种思路实现
查看>>
致初入模板创作:了解各种浏览器真正的核心,测试模板兼容时就不用开这么多浏览器...
查看>>
我的友情链接
查看>>
利用rsync备份邮件系统
查看>>
java.io.Serializable浅析
查看>>
分布式计算
查看>>
FBReaderJ 的编码风格
查看>>
Yeslab 马老师 V2V环境下vCenter Server Heartbeat v6.4实现vCenter5.0的双机备份
查看>>
GO chan 编程
查看>>
CSS基础教程——纯CSS开发的气泡式提示框
查看>>
python单元测试基础举例
查看>>
iframe调用父页面javascript函数的方法
查看>>