.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

软中断和tasklet相关推荐

  1. Linux软中断、tasklet和工作队列

    Linux内核中的软中断.tasklet和工作队列详解 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的"下半部"(bottom ...

  2. linux中断机制--理解中断上半部/下半部、软中断、tasklet、工作队列(可调度、可睡眠)

    1. 中断vs轮询 Linux 内核需要对连接到计算机上的所有硬件设备进行管理,毫无疑问这是它的份内事.如果要管理这些设备,首先得和它们互相通信才行,一般有两种方案可实现这种功能: 中断(interr ...

  3. 【中断】软中断、tasklet和任务队列

    Linux中断知识汇总: [深入理解Linux内核][中断]内容汇总帖 目录 中断下半部实现机制 什么是软中断? 什么是tasklet? 什么是工作队列? 软中断.tasklet和工作队列的区别与联系 ...

  4. Linux内核中的软中断、tasklet和工作队列详解

    本文基于Linux2.6.32内核版本. 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的"下半部"(bottom half)演 ...

  5. Linux内核中的软中断、tasklet和工作队列具体解释

    [TOC] 本文基于Linux2.6.32内核版本号. 引言 软中断.tasklet和工作队列并非Linux内核中一直存在的机制,而是由更早版本号的内核中的"下半部"(bottom ...

  6. 六、系统软中断、tasklet、工作队列work queue的区别及使用

    前言:这篇文章不会对系统软中断.tasklet.工作队列work queue的内核实现机制进行深入分析,仅仅是谈一下这几种机制的不同以及简单的使用.有描述不对的地方,欢迎大家指出. 说明:在分析具体代 ...

  7. [笔记]Linux内核学习之旅--软中断与tasklet

    关于软中断上一篇文章有提到,这一篇文章就记一点关于tasklet的东西吧 tasklet是一种特殊的软中断,一般挂在中断号为0和5的中断向量上.tasklet也作为一种可延迟的中断存在,为什么这样说, ...

  8. linux中的tasklet机制【转】

    转自:http://blog.csdn.net/yasin_lee/article/details/12999099 转自: http://www.kerneltravel.net/?p=143 中断 ...

  9. linux软中断的实现

    中断服务程序往往都是在CPU关中断的条件下执行的,以避免中断嵌套而使控制复杂化.但是CPU关中断的时间不能太长,否则容易丢失中断信号.为此, Linux将中断服务程序一分为二,各称作"Top ...

  10. linux软中断优先级,Linux中软中断机制分析

    Linux中软中断实现分析 在Linux中最多可以注册32个软中断,目前系统用了6个软中断,他们为:定时器处理.SCSI处理.网络收发处理以及Tasklet机制,这里的tasklet机制就是用来实现下 ...

最新文章

  1. 数据治理(Data Governance)
  2. docker存储卷篇
  3. 自然语言处理中的符号表征
  4. python希尔排序的优缺点_Pythonの希尔排序
  5. 固定资产打开提示:上年度数据未结转!
  6. fisher-yates_使用Fisher-Yates随机播放算法以O(n)时间随机播放给定数组
  7. C++ 11右值引用
  8. 实现python扩展的C API方法过程全纪录(windows)
  9. select into
  10. python stdout_python 之sys.stdout小记
  11. 物联网大数据的爆发只是一个开始
  12. TortoiseGit:参考文章
  13. 图像处理六:预处理方法
  14. 3.6 SQL Server 内存
  15. python---python基本算法的时间复杂度和空间复杂度
  16. linux下的qt没有qpixma类吗,Qt基础教程之QTreeWidget和QDockWidget用法详解
  17. 数据库(MYSQL)之元数据
  18. NYOJ1237_最大岛屿
  19. BBEdit 10.X for mac的lincese
  20. Excel 表格有重复内容怎么办?

热门文章

  1. 记录:添加trace_event埋点并调用
  2. SRv6技术课堂(一):SRv6概述
  3. u-boot 2016.05 添加自己的board 以及config.h uboot移植
  4. Ceph 撸源码系列(二):Ceph源代码里的那些锁 std::mutex(2 of 3)
  5. 三个基于WebRTC开源MCU框架的横向对比
  6. Linux内核部件分析 设备驱动模型的基石kobject
  7. 阿牛的EOF牛肉串(递推dp)
  8. 操作系统原理-----进程同步与通信
  9. STL--vector、pair
  10. hdu1864--dp