Linux内核设计与实现---下半部分和推后执行的工作(8)

中断处理程序上半部的局限性:

  • 中断处理程序以异步方式执行,并且它有可能会打断其他重要代码(甚至是中断处理程序)的执行。因此越短越好。
  • 如果一个中断执行,最好情况下(IRQF_DISABLED没有被设置),与该中断同级的中断被屏蔽,最坏情况下(设置IRQF_DISABLED),当前处理器所有中断被屏蔽。中断被禁用,因此越快越好。
  • 与硬件打交道,所以有时限要求。
  • 不在进程上下文执行,不能阻塞,限制了它们做其他事情。
  • 因此,操作系统必须有一个快速,异步,简单的机制负责对硬件做出迅速响应并完成那些时间要求严格的操作—–中断处理程序作为整个硬件中断处理流程一部分。
  • 分两部分:中断处理程序(上半部)和下半部(bottom halves)。

一、下半部:执行与中断处理密切相关但中断处理程序本身不执行的工作。

  • 为什么要用下半部
    • 通常下半部在中断处理程序一返回就会马上执行。
    • 下半部执行的关键是在运行时,允许响应中断。
  • 下半部的环境

    • 下半部可以通过多种机制实现,上半部只能通过中断处理程序实现。这些用来实现下半部分的机制分别由不同的接口和子系统组成。
    • 开发过程(逐步替代):(1)bottom half 机制或BH机制(该机制在2.5版以后去除。注意:与下半部这个名词区分)。(2)任务队列(task queue)机制。(3)软中断(softirqs)和tasklet (使用比较多):软中断是一组静态定义的下半部接口,有32个,可以在所有处理器上同时执行(即使类型相同)。tasklet 是一种基于软中断实现的灵活性强、动态创建的下半部分实现机制。不同类型的tasklet可以再不同的处理器上执行。

    注意:这里的软中断与软件中断(系统调用)不是同一个概念

    • 内核定时器:另外一个可以用于将工作推后执行的机制就是内核定时器。可以准确的推迟到某个时间段以后。
  • 总结:“下半部”是一个操作系统通用词汇,用于指代中断处理流程中推后执行的那一部分。并不单纯的是指软中断
  • 目前实现工作推后执行(下半部)的机制有三种:软中断(softirq和timer 类型的softirq)、tasklet、工作队列(work queue)。

二、软中断

  • 软中断实现

    • 软中断是静态分配的,在< linux/interrupt.h >中定义:
      struct softirq_action{
      void (*action) (struct softirq_action *)
      };

      只有一个可以回调的函数指针
    • kernel/softirq.c中定义了32个该结构体数组。
      static struct softirq_action softirq_vec[NR_SOFTIRQs]

    • 软中断处理程序:一个软中断不会抢占另外一个软中断。实际上,唯一可以抢占软中断的是中断处理程序。但其他软中断(甚至是相同类型的软中断)可以再其他处理器上同时执行。

    • 执行软中断:一个注册的软中断必须在被标记后才会执行。这被称作触发软中断(raising the softirq)。
      • 从一个硬件中断代码处返回时
      • 在ksoftirqd(软中断处理线程)内核线程中
      • 在那些显式检查和执行待处理的软中断的代码中。如网络子系统中。
  • 使用软中断:软中断保留给系统中对时间要求最严格以及最重要的下半部使用。目前只有两个(网络和SCSI)直接使用软中断。内核定时器和tasklet都是建立在软中断上的。

    • 分配索引:在编译期间,通过在< linux/interrupt.h >中定义的一个枚举类型来静态地声明软中断。内核用这些从0开始的索引表示一种相对优先级。目前内核实现10种类型软中断:

              {  
                  HI_SOFTIRQ=0,  
                  TIMER_SOFTIRQ,  
                  NET_TX_SOFTIRQ,  
                  NET_RX_SOFTIRQ,  
                  BLOCK_SOFTIRQ,  
                  BLOCK_IOPOLL_SOFTIRQ,  
                  TASKLET_SOFTIRQ,  
                  SCHED_SOFTIRQ,  
                  HRTIMER_SOFTIRQ,  
                  RCU_SOFTIRQ,  /* Preferable RCU should always be the last softirq */  
      
                  NR_SOFTIRQS  
              };
  • 注册你的处理程序:通过调用open_softirq()注册软中断处理程序,两个参数:软中断的索引号和处理函数。例如:open_softirq(NET_RX_SOFTIRQ,net_tx_action);

    扫描二维码关注公众号,回复: 2259038 查看本文章
    • 软中断处理程序执行的时候,允许响应中断,但是它自己不能休眠。
    • 在一个处理程序运行的时候,当前处理器上的软中断被禁止。但其他处理器仍可以执行别的软中断。
    • 如果同一个软中断在它被执行的同时再次被触发了,那么另外一个处理器可以同时运行其处理程序。这也意味着任何共享数据(甚至是仅在软中断处理程序内部使用的全局变量)都需要严格的锁保护。这也是tasklet更受青睐的原因。
    • 大部分软中断处理程序,都是通过采取单处理器数据(应该是per_cpu var)或其他一些技巧来避免显式地加锁。
    • 引入软中断的主要原因是其可扩展性。如果不需要扩展到其他处理器,那么,就使用tasklet吧(本质上也是软中断,只不过同一个处理程序的多个实例不能在多个处理器上同时运行。)
  • 触发你的软中断
    • raise_softirq();函数可以将一个软中断设置为挂起状态,调用do_softirq();函数时投入运行。
    • 在中断处理程序中触发软中断是最常见的形式。即内核在执行完中断处理程序以后,马上会调用do_softirq()函数。

三、tasklet

  • tasklet是利用软中断实现的一种下半部机制,它和进程没有任何关系。
  • 通常应该使用tasklet。软中断一般只在那些执行频率很高和连续性要求很高的情况下才需要使用。
  • tasklet的实现:tasklet有两类中断代表:HI_SOFTIRQ和TASKLET_SOFTIRQ
    • tasklet结构体:

      struct tasklet_struct{
      struct tasklet_struct *next; /*链表中的下一个tasklet*/
      unsigned long state; /*tasklet 的状态*/
      atomic_t count; /*引用计数器*/
      void (*func) (unsigned long) /*tasklet 处理函数*/
      unsigned long data /*给tasklet处理函数的参数*/
      }

    • state成员只能是0、TASKLET_STATE_SCHED(被调度) 和TASKLET_STATE_RUN(正运行)。
    • count成员是tasklet的引用计数器。不为0,表示被禁止,不允许执行。否则被激活,只有在设置为挂起状态时,该tasklet才能够执行。
  • 调度tasklet:已经被调度的tasklet被存放在两个单处理器数据结构:tasklet_vec(普通tasklet)和tasklet_hi_vec(高级优先级的tasklet)。都是由tasklet_struct结构体构成的链表代表不同的tasklet。
  • tasklet_schedule()和tasklet_hi_schedule()两个函数调度tasklet。详细内容见教材。
  • ksoftirqd:软中断处理线程。防止可能造成的软中断饥饿或者用户空间饥饿的现象,最终在内核中实现的方案是不会立即处理重新出发的软中断。当大量软中断出现时,内核会唤醒一组内核线程来处理这些负载。处于最低优先级(nice值为19),最终保证用户程序不饥饿,软中断最终也可以被执行。
  • 每个处理器都有一个这样的线程。所有线程的名字都是ksoftirqd/n,n为处理器的编号。
    四、工作队列(work queue)
  • 工作队列可以把工作推后,交由一个内核线程去执行—–这个下半部总是会在进程上下文中执行,因此,工作队列允许重新调度甚至书面
  • 唯一能在进程上下文中运行的下半部实现机制。
  • 工作队列的实现:工作队列子线程是一个英语创建内核线程的接口,通过他创建的进程负责执行由内核其他部分排到队列里的任务。这些线程被称为工作者线程(worker thread)。
  • 缺省的工作者线程叫做events/n,每个处理器对应一个线程。

猜你喜欢

转载自blog.csdn.net/u012418573/article/details/77116462