• Linux设备驱动程序 之 软中断


    软中断保留给系统中对时间要求严格以及最重要的下半部使用;目前,只有两个子系统(网络和SCSI)直接使用软中断;此外,内核定时器和tasklet都是建立在软中断上的;在使用软中断之前,要先确定为什么不能使用tasklet,tasklet可以动态生成,并且对加锁的要求不高,使用起来也很方便,性能也不错;当然,对于时间要求严格并能自己高效完成加锁的工作,软中断是正确的选择;

    分配索引

    在编译期间,通过在<linux/interrupt.h>中定义一个枚举类型来静态的声明软中断,内核用这些索引来表示优先级,索引号小的软中断在索引号大的软中断之前执行;

    建立新的软中断必须在此枚举的类型中加入新的项;加入时,不能像其他地方一样,简单的把项增加到列表的末尾;相反,必须根据希望赋予她的优先级来决定加入的位置;习惯上,HI_SOFTIRQ通常作为第一项,而RCU_SOFTIRQ作为最后一项;新项可能插在BLOCK_SOFTIRQ和TASKLET_IRQ之间;

     1 enum
     2 {
     3     HI_SOFTIRQ=0,
     4     TIMER_SOFTIRQ,
     5     NET_TX_SOFTIRQ,
     6     NET_RX_SOFTIRQ,
     7     BLOCK_SOFTIRQ,
     8     IRQ_POLL_SOFTIRQ,
     9     TASKLET_SOFTIRQ,
    10     SCHED_SOFTIRQ,
    11     HRTIMER_SOFTIRQ, /* Unused, but kept as tools rely on the
    12                 numbering. Sigh! */
    13     RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq */
    14 
    15     NR_SOFTIRQS
    16 };
    注册处理程序

    在运行时,通过调用open_softirq()注册软中断处理程序,该函数有两个参数:软中断的索引号和处理函数;

    1 void open_softirq(int nr, void (*action)(struct softirq_action *));

    如网络子系统注册中断的方式如下:

    1 open_softirq(NET_TX_SOFTIRQ, net_tx_action);
    2 open_softirq(NET_RX_SOFTIRQ, net_rx_action);
    1 open_softirq(NET_TX_SOFTIRQ, net_tx_action);
    2 open_softirq(NET_RX_SOFTIRQ, net_rx_action);

    软中断处理程序执行的时候,允许响应中断,但是它自己不能休眠;在一个处理程序运行的时候,当前处理上的软中断被禁止;但其他处理器上仍可以执行别的软中断;如果同一个软中断在它被执行的同时再次触发了,那么另外一个处理器可以同时运行其处理程序;这意味着任何共享数据都需要严格的锁保护;这也是tasklet更受青睐的原因;大部分软中断处理程序,都通过使用单处理器数据或者其他一些技巧来避免显式的加锁,从而获得更出色的性能;

    引入软中断的主要原因是其可扩展性;如果不需要扩展到多个处理器,那么,使用tasklet是好的选择;tasklet本质上也是软中断,只不过同一个处理程序的多个实例不能再多个处理器上同时运行;

    软中断的触发

    通过在枚举类型的列表中添加了新项之后,并调用open_softirq()进行了注册,新的软中断处理程序就能够运行了;raise_softirq()函数可以将一个软中断设置为挂起状态,让它在下次调用do_softirq()函数时投入运行;

    raise_softirq()函数再触发一个软中断之前要先禁止中断,触发之后再恢复原来的状态;如果中断本来就已经被禁止了,那么可以调用raise_softirq_irqoff()函数,将会带来一些优化效果;

    1 void raise_softirq_irqoff(unsigned int nr);
    2 void raise_softirq(unsigned int nr);

    在中断处理程序中触发软中断是最常见的形式,在这种情况下,中断处理程序执行硬件设备的相关操作,然后触发相应的软中断,最后退出;内核在执行完中断处理程序以后,马上就会调用do_softirq()函数;于是软中断开始执行中断处理程序留给它去完成的剩余任务;

  • 相关阅读:
    C# 非UI线程向UI线程发送数据的两种方法
    c# 富客户端使用 MethodInvoker简化代码
    Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'xxxx'.
    弃元
    Serilog 配置基础知识
    测试软件开发准则--基于TTStand
    SuperSocketHostBuilder<TReceivePackage>
    Ext CheckBoxGroup使用
    2020年12月28日 新工作新旅程
    2021年全国计算机等级考试报名照片制作教程(压缩、裁剪、换白底)
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11761772.html
Copyright © 2020-2023  润新知