zoukankan      html  css  js  c++  java
  • [linux内核][linux中断]——软中断机制

    点击打开链接

    一,linux软中断的概念
    软中断(softirq)常常表示可延迟函数的所有种类,目前linux上使用的软中断个数是有限的,linux最多注册32个,目前使用了10个,在interrupt.h中定义,中断上下文:表示内核当前正在执行一个中断处理程序或者一个可延迟函数。软中断(即使同一类型的软中断)可以并发运行在多个CPU上,因此软中断是可重入函数必须使用自旋锁保护其数据结构。一个软中断不会去抢占另外一个软中断。

    软中断和tasklet的区别
    由于软中断必须使用可重入函数,这就导致设计上的复杂度变高,作为设备驱动程序的开发者来说,增加了负担。而如果某种应用并不需要在多个CPU上并行执行,那么软中断其实是没有必要的。因此诞生了弥补以上两个要求的tasklet。它具有以下特性:
    a)一种特定类型的tasklet只能运行在一个CPU上,不能并行,只能串行执行。
    b)多个不同类型的tasklet可以并行在多个CPU上。
    c)软中断是静态分配的,在内核编译好之后,就不能改变。但tasklet就灵活许多,可以在运行时改变(比如添加模块时)。

    软中断的实现:
    软中断由softirq_action结构体表示

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. struct softirq_action{  
    2.  void (*action)(struct sotfirq_action*)  
    3. kernel/softirq.c中定义了一个包含有32个该结构体的数组  
    4. static struct softirq_action softirq_vec[NR_SOFTIRQS]  

    1,注册软中断函数 open_softirq

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void open_softirq(int nr, void (*action)(struct softirq_action *))  
    2. {  
    3.     /* softirq_vec是个struct softirq_action类型的数组 */  
    4.     softirq_vec[nr].action = action;  
    5. }  


    2,触发软中断的函数 raise_softirq 参见 kernel/softirq.c文件

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void raise_softirq(unsigned int nr)  
    2. {  
    3.     unsigned long flags;  
    4.   
    5.     local_irq_save(flags);  
    6.     raise_softirq_irqoff(nr);  
    7.     local_irq_restore(flags);  
    8. }  


    3,执行软中断 do_softirq 参见 kernel/softirq.c文件,如果有待处理的软中断,do_softirq()会循环遍历每一个,调用它们的处理程序。

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. asmlinkage void do_softirq(void)  
    2. {  
    3.     __u32 pending;  
    4.     unsigned long flags;  
    5.     /* 判断是否在中断处理中,如果正在中断处理,就直接返回 */  
    6.     if (in_interrupt())  
    7.         return;  
    8.     /* 保存当前寄存器的值 */  
    9.     local_irq_save(flags);  
    10.     /* 取得当前已注册软中断的位图 */  
    11.     pending = local_softirq_pending();  
    12.     /* 循环处理所有已注册的软中断 */  
    13.     if (pending)  
    14.         __do_softirq();  
    15.     /* 恢复寄存器的值到中断处理前 */  
    16.     local_irq_restore(flags);  
    17. }  



    4,执行相应的软中断 - 执行自己写的中断处理linux中,执行软中断有专门的内核线程,每个处理器对应一个线程,名称ksoftirqd/n

  • 相关阅读:
    关于jpa example使用
    文件下载
    文件夹下的文件根据最后修改时间排序
    前端验证图片是否加载成功
    LocalDate获取当天,本月第一天,本月最后一天,今年第一天,今年最后一天
    将word文档合成一张图片输出
    easyui前端分页与layui前端分页
    Java线程池源码流程图
    hexo发布到gitee和github上及主题优化
    【JVM之美】垃圾收集算法
  • 原文地址:https://www.cnblogs.com/zhiliao112/p/4232157.html
Copyright © 2011-2022 走看看