当前课程知识点:Linux 内核分析与应用 >  第5章 中断 >  5.3 中断下半部处理机制 >  Video

返回《Linux 内核分析与应用》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《Linux 内核分析与应用》慕课在线视频列表

Video课程教案、知识点、字幕

大家好 这一讲我们来介绍一下中断的下半部分处理机制

那么首先呢我们介绍一下中断的基本机制

我们说中断服务程序一般都是在中断请求关闭的条件下执行的

以避免嵌套而使中断控制复杂化

但是呢中断是一个随机事件 它随时会到来

如果关中断的时间太长呢 CPU就不能及时响应其他的中断请求

从而造成中断的丢失 因此呢内核的目标就是尽可能快的处理完中断请求

尽其所能把更多的处理向后推迟

如图是中断的基本模型

在中断向量表中填入中断处理程序的入口地址 然后跳到该程序执行

那么下面我们就介绍一下中断的下半部分

随着系统的不断复杂 中断处理函数要做的事情也越来越多

多到都来不及接收新的中断了 于是发生了中断丢失

这显然是不行的 于是呢内核把中断分为两部分

一个叫上半部是不可中断的 一个叫下半部是可中断的

上半部也就是中断服务程序 内核立即执行而下半部也就是一些内核函数呢留着稍后处理

那么 在中断的下半部分机制中它提供了好几种机制

那么首先我们来看一下软中断机制

不管是中断的下半部 还是上半部呢

都是一种概念 实际上是什么呢实际上都是内核中的一个函数

这些函数写好以后什么时候被执行 如何执行这是内核必须统一管理的

在上一讲所讲的中断机制中呢 我们介绍了中断注册函数request_irq()

它把中断服务例程添加到中断请求队列中

其执行是由do_IRQ()函数完成的

与之对应呢 我们可以通过open_softirq添加下半部对应的处理函数

而其执行则是通过do_softirq来完成 也就是软中断机制来完成

那么软中断到底有哪些类型呢

实际上在下半部分的处理方式主要有三种

一种叫soft_irq 第二种叫tasklet也就是小任务机制

第三种叫workqueue 也就是工作队列机制

他们在使用方式和适用情况上各有不同

soft_irq用在对下半部执行时间要求比较紧急的场合

在中断上下文中执行

而tasklet和work queue在普通的驱动程序中用的相对比较多

主要区别是什么呢 小任务tasklet是在中断上下文执行的

而工作队列是在进程上下文用的

因此可以执行可能睡眠的操作

每个软中断在内核中都是以softirq_action表示的

内核目前实现了10种软中断

那么定义在interrupt.h中如图所示

下面我们来介绍一下比较常用的小任务机制 也就是tasklet机制

小任务机制是I/O驱动程序中实现可延迟函数的首选方法

小任务和工作队列都是延迟执行工作的一种机制

其实现是基于软中断的

但他们更易于使用 因而更适合于设备驱动程序

所谓小任务是什么意思呢 就是执行一些迷你型的任务

那么在内核中如何表示小任务呢 有一个数据结构叫tasklet_struct结构

那么在这个结构中有一个域func域呢

就是下半部中要推迟执行的函数

而data域是传递给这个函数的唯一参数

Count域是小任务的引用计数器

如果它不为0 则小任务就被禁止 不允许执行

只有当它为0的时候小任务才被激活 并且是在被设置为挂起的时候呢 小任务才能够执行

那么如何编写自己的小任务并交给系统进行调度

这里头我们给出三个步骤 首先声明和使用小任务

如何进行声明呢 内核提供了相应的接口DECLARE_TASKLET

那么如何编写自己的小任务处理程序呢 这跟我们

编写一般的函数是一样的 但要注意呢

小任务中不能睡眠 不能在小任务中使用信号量或其他产生阻塞的函数

但它执行时可以响应中断

那么当我们把小任务编写好以后就可以调度或者呢

不需要的时候杀死小任务 内核也是提供了相应的函数

那么在第五讲中我们将演示如何编写小任务并对相关的代码进行分析

下面我们介绍第三种机制 也就是工作队列机制

那么前面的机制不论如何去折腾呢 实际上有一点是不会变的

他们都是在中断上下文中 为什么呢

说明它们是不可挂起的 而且由于是串行执行

因此只要有一个处理时间较长的话 则会导致其他中断响应的延迟

为了完成这些不可能完成的任务呢 于是出现了工作队列机制

工作队列说白了就是一组内核线程 作为中断守护线程来使用

多个中断可以放在一个线程中 也可以每个中断分配一个线程

工作队列对线程作了封装 使用起来更方便

因为工作队列是线程 所以我们可以使用所有可以在线程中使用的方法

那么我们首先看一下工作队列中的几个数据结构

那么第一个数据结构就叫work_struct

我们把推后执行的任务就叫做工作 描述它的数据结构就叫做work_struct结构

其中func钩子函数就是我们推后要执行的函数

而data就是传递给这个函数的参数

那么第二个数据结构叫做每CPU工作队列结构

如果是多线程 内核就要根据当前系统CPU的个数呢

为每CPU创建一个cpu_workqueue_struct结构

简称CWS结构

在该结构中主要维护了一个任务队列以及内核线程需要睡眠的等待队列

另外还维护了一个任务上下文 也就是task_struct结构

那么工作队列的运行机制是什么样子的呢

当用户调用工作队列初始化函数

对工作队列进行初始化以后呢

内核就开始为用户分配一个工作队列对象

并且将它挂到一个全局的workqueue队列中

然后内核根据当前CPU的情况

为workqueue对象分配与CPU个数相同的

cpu_workqueue_struct对象

每一个cpu_workqueue_struct对象都会有一条任务队列

紧接着呢 内核为

cpu_workqueue_struct对象分配一个内核线程

也就是内核daemon去处理每个队列中的任务

至此呢 用户调用初始化接口将工作队列初始化完毕 返回workqueue的指针

workqueue初始化完毕以后 将任务运行的上下文环境就构建起来了

但是具体还没有可执行的任务

所以 需要定义具体的work_struct对象

然后呢将work_struct加入到任务队列中

内核会唤醒内核线程daemon去处理该任务

前面介绍了那么多 我们下面给出一个总结

什么时候使用哪种中断处理机制

前面我们说了Request_irq挂的是中断函数

那么这个函数要尽量的简单

只做必须在屏蔽中断情况下要做的事情

中断的其他部分都要放在下半部分中完成

软中断的使用原则很简单 最好不用

它甚至都不算是一种真正的中断处理机制

只是tasklet的实现基础

工作队列也要少用 如果不是必须要用到线程才用的某些机制

就不要使用工作队列

为什么对工作队列机制进行了比较详细的介绍

是希望大家从这种设计机制中能够得到启发

其实对于中断来说呢 只是对中断进行简单的处理

大部分工作是在驱动程序中完成的

除了上述情况以外呢 一般都使用小任务tasklet机制

即使是下半部分呢 也只是做必须在中断中要做的事情

如保存数据等 其他的都是交给驱动程序去做

关于中断 我们一定要动手实践 在linux内核之旅网站的新手上路栏目呢

有内核入门系列文章 其中呢有感受小任务机制

中断下半部分之tasklet

有感受工作队列机制 中断下部分之工作队列

调试其中的代码并分析源代码进行切实的感受

最后我们给出参考资料

那么依然是《深入理解Linux内核》第三版的第四章

《Linux内核设计与实现》第三版的第七章

蜗窝科技网站关于中断的系列文章

那么 最后呢我们带着思考离开

为什么要有中断下半部分处理机制

而且还有好几种机制

那么第二个问题在中断下半部处理机制中

你认为是否还有改进的余地 谢谢大家

Linux 内核分析与应用课程列表:

第1章 概述

-1.1 Linux操作系统概述

--1.1 Linux 操作系统概述

-1.2 Linux内核结构以及内核模块编程

--Video

-1.3 Linux内核源码中的双链表结构

--Video

-1.4 源码分析-内核中的哈希表

--Video

-1.5 动手实践-Linux内核模块的插入和删除

--Video

-第1章 概述--章节测验

-第1章导学--引领你进入Linux内核的大门

第2章 内存寻址

-2.1 内存管理之内存寻址

--Video

-2.2 段机制

--Video

-2.3分页机制

--Video

-2.4 动手实践-把虚拟地址转换成物理地址

--Video

-第2章 内存寻址--章节测验

-第二章导学-从零打造自己的操作系统

第3章 进程管理

-3.1 进程概述

--Video

-3.2 Linux进程创建

--Video

-3.3 Linux进程调度

--Video

-3.4 动手实践-打印进程描述符task_struct中的字段

--Video

-3.5工程实践-基于内核模块的负载监控

--Video

-第3章 进程管理--章节测验

-第三章导学-进程背后琳琅满目的宝贝到哪里挖?

第4章 内存管理

-4.1 Linux内存管理机制

--Video

-4.2 进程用户空间管理机制

--Video

-4.3 物理内存分配与回收机制(上)

--Video

-4.4 物理内存分配与回收机制(下)

--Video

-4.5 动手实践-Linux内存映射基础(上)

--Video

-4.6 动手实践-Linux内存映射实现(中)

--Video

-4.7 动手实践-Linux内存映射测试(下)

--Video

-4.8 初学者对内存管理的常见疑惑

--初学者对内存管理的常见疑惑(一)

--初学者对内存管理的常见疑惑(二)

--初学者对内存管理的常见疑惑(三)

-第4章 内存管理--章节测验

第5章 中断

-5.1 中断机制概述

--Video

-5.2 中断处理机制

--Video

-5.3 中断下半部处理机制

--Video

-5.4 时钟中断机制

--Video

-5.5 动手实践-中断上半部的代码分析及应用

--Video

-5.6 动手实践-中断下半部的代码分析及应用

--Video

-第5章 中断--章节测验

第6章 系统调用

-6.1 Linux中的各种API

--Video

-6.2 系统调用机制

--Video

-6.3 动手实践-添加系统调用(系统调用日志收集系统)

--Video

-第6章 系统调用--章节测验

第7章 内核同步

-7.1 内核同步概述

--Video

-7.2 内核同步机制

--Video

-7.3 动手实践-内核多任务并发实例(上)

--Video

-7.4 动手实践-内核多任务并发实例(下)

--Video

-第7章 内核同步--章节测验

第8章 文件系统

-8.1 虚拟文件系统的引入

--Video

-8.2 虚拟文件系统的主要数据结构

--Video

-8.3 文件系统中的各种缓存

--Video

-8.4 页高速缓存机制以及读写

--Video

-8.5 动手实践-编写一个文件系统(上)

--Video

-8.6 动手实践-编写一个文件系统(中)

--Video

-8.7 动手实践-编写一个文件系统(下)

--Video

-第8章 文件系统--章节测验

第9章 设备驱动

-9.1 设备驱动概述

--Video

-9.2 I/O空间管理

--Video

-9.3 设备驱动模型

--Video

-9.4 字符设备驱动程序简介

--Video

-9.5 块设备驱动程序简介

--Video

-9.6 动手实践-编写字符设备驱动程序

--Video

-9.7工程实践-编写块设备驱动的基础(上)

--Video

-9.8 工程实践-块设备驱动程序分析(中)

--Video

-9.9 工程实践-块设备驱动程序实现(下)

--Video

-第9章 设备驱动--章节测验

致谢与说明

-致谢与说明

--Video

直播视频:从Linux内核学习到自主操作系统研发

-从Linux内核学习到自主操作系统研发

附录:实验代码、课件以及相关素材

-各章实验代码

-《Linux内核分析与应用》课件

-《Linux操作系统原理与应用》教材课堂视频

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。