linux内核源代码分析中断处理程序与内核同步_第1页
linux内核源代码分析中断处理程序与内核同步_第2页
linux内核源代码分析中断处理程序与内核同步_第3页
linux内核源代码分析中断处理程序与内核同步_第4页
linux内核源代码分析中断处理程序与内核同步_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、.1LINUX中断处理程序及内核同步 系统调用和中断(回顾上节课内容) 中断处理程序的上、下半部机制 LINUX下半部处理机制 同步的经典问题 LINUX内核同步实现 实验问题解答.2系统调用和中断(回顾上节课内容) 系统调用原理 INT 80H 中断描述符(80H指向system_call) 系统调用表(system_call_table) 系统调用编号(系统调用在系统调用表中的位置) 中断 中断描述符 中断号 中断处理程序.3中断处理程序的上、下半部机制 中断处理程序为什么要分上下半部 中断处理程序以异步方式执行,可能打断重要的操作的执行,越快越好 中断处理程序屏蔽其他中断,执行越快越好

2、中断处理程序往往需要对硬件操作,通常有很高的时限要求 中断处理程序不在进程的上下文中运行,所以不能阻塞以上说明:中断处理程序必须执行快,否则影响并发性;中断处理程序在某些时候必须屏蔽其他的中断。把必须屏蔽中断的一些操作放在上半部把有些操作放在下半部,可以被打断这就是操作系统中断处理的上下半部机制。(网络通信的例子).4上、下半部怎样分开 如果一个任务对时间非常敏感,将其放在中断处理程序中(上半部)执行。 如果一个任务和硬件相关,放在中断处理程序执行 如果一个任务要保证不被其他中断打断,则放在中断处理程序执行 其他的所有任务,考虑放在下半部执行。.5下半部实现机制 LINUX的上半部就是中断处理

3、程序 下半部有多种机制 软中断机制 Tasklet机制 工作队列机制.6软中断机制 此处的软中断和系统调用用大INT80H不同,是操作系统支持的一种中断机制。 软中断机制的实现 软中断在编译期间静态分配(由softirq_action结构表示,定义在中)Struct softirq_action void (*action)(struct softirq_action*);/*将要执行的函数*/void *data; /* 传递给函数的参数*/Kernel/softirq.c中定义了一个包含有32个该结构体的数组Static struct softirq_action softirq_vec3

4、2;.7软中断机制 32个是最大值,目前用到6个 软中断处理程序Void softirq_handler(struct softirq_action*)(传的是整个结构)当内核运行一个软中断处理程序的时候,会执行这个action函数如若my_softirq指向softirq_vec数组的某项,内核已下方式调用函数:My_softirq-action(mysoftirq); 执行软中断标记(raising the softirq) 处理完一个硬件中断后 在ksoftirqd内核线程中 显示检查和执行待处理软中断的代码中.8软中断机制 do_softirq(不管执行的时机,软中断都要在do_sof

5、tirq中执行)核心部分代码:u32 pending = softirq_pending(cpu);if (pending) struct softirq_action *h = softirq_vec;softirq_pending(cpu) = 0;do if (pending & 1) h-action(h); h+; pending =1; while (pending);.9软中断机制 使用软中断 分配索引 中,已用的:HI_SOFTIRQ0优先级高的TASKLetsTIMER_SOFTIRQ1NET_TX_SOFTIRQ2NET_RX_SOFTIRQ3SCSI_SOFTIRQ4TA

6、SKLET_SOFTIRQ5添加自己的项时要根据优先级定义加入,一般在SCSI的下面。.10软中断机制 注册你的处理程序 OPEN_SOFTIRQ(NET_TX_SOFTIRQ,actions,NULL); 触发你的软中断 Raise_softirq(NET_TX_SOFTIRQ)(在你的中断处理程序里触发)与中断处理程序一起的一般处理过程。.11Tasklets机制 基于软中断实现的下半部机制 接口更简单,锁保护也要求较低 Tasklets的实现(linux/interrupt.h)Struct tasklet_struct Struct tasklet_struct *next;Unsig

7、ned long sate;(0/TASKLET_STATE_SCHED/TASKLET_STATE_RUN)Atomic_t count;/*引用计数器,0允许执行,否则禁止*/Void (*func)(unsigned long);/*执行函数*/Unsigned long data;.12Tasklets机制调度tasklets Tasklets 放在tasklet_vec和task_hi_vec两个链表中; 由tasklet_schedule()和tasklet_hi_schedule()进行调度Task_schedule执行的步骤: 检查tasket的状态是否为tASKLET_STA

8、TE_SCHED,若是返回, 保存中断状态,然后禁止本地中断 把需要调度的tasklet放在每个处理器的tasklet_vec表头上去。 唤起TASKLET_SOFTIRQ或TASKLET_HI_SOFTIRQ. 恢复中断。.13Tasklets机制 Tasklet_action() 和tasklet_hi_action()做的工作: 禁止中断 将当前处理器上的该链表清空 允许中断 循环遍历链表上每一个待处理的tasklet 若是多处理器系统,看是否RUN,若是下一个 若没有执行,设为RUN 检查count是否为0,若不是,下一个 调用执行TASKLET,后清空相应的标志。 下一个.14Tas

9、klets机制 使用 tasklets 声明Tasklet DECLARE_TASKLET(name,func,data) DECLARE_TASKLET_DISABLED()以上是静态的方式Tasklet_init(t,tasklet_handler,dev) ;/*动态创建*/ 编写处理程序 Tasklet_handler(unsigned long data).15Tasklets机制 调度自己的tasklet 实际上是标记,或称挂起 Tasklet_schedule(&mytasklet); 另外的控制:tasklet_disable(&my_tasklet);tasklet_enab

10、le(&my_tasklet);总结tasklet机制.16Ksoftirqd 软中断和tasklet机制中,当中断或 tasklet频繁发生时其处理方式要慎重选择。 尽快执行(系统忙时,用户进程得不到响应) 滞后执行(系统闲的时候,中断处理的也不快) 折中的办法:低优先级核心进程专门处理软中断.17Ksoftirqd/n For(;)If (!softirq_pending(cpu) shedule();set_current_state(TASK_RUNNING);While (softirq_pending(cpu)Do_softirq();If (need_resched() sche

11、dule() .18工作队列机制 工作队列机制和上面两中机制不同,它将下半部功能交由内核线程执行,有线程的上下文环境,可以睡眠。 工作队列机制的实现 提供创建worker threads的接口 提供默认的工作者线程处理排到队列里的下半部工作 提供把需要推后执行的任务排到队列里的接口.19工作队列机制 表示线程的数据结构 Struct workqueue_struct Struct cpu_workqueue_struct cpu_wqNR_CPUS; Struct cpu_workqueue_struct Spinlock_t lock; Struct list_head worklist;

12、wait_queue_head_t more_work; Wait_queue_head_t work_done; Struct workqueue_struct *wq; Tast_t *thread; Struct completion exit;.20工作队列机制 表示工作的数据结构 Struct work_struct Unsigned long pending; Struct list_head entry; Void (*func)(void*); Void *data; Void *wq_data; Struct timer_list timer;.21工作队列机制 核心线程 见

13、书81页,处理机制如下: 线程将自己设置为休眠状态 若工作连表为空,休眠 若不空,调用run_workqueue() 函数执行工作。 Run_workqueue的执行:(p82) 当工作链表不空时,选取下一个节点对象,获取要执行的函数和参数。 待处理标志清0 调用函数 重复执行.22工作队列机制 工作队列机制的使用 创建工作DECLARE_WORK(name,void(*func)(void*),void*data);Init_work(.) 工作队列处理函数void work_handler(void *data); 对工作进行调度shedule_work();shedule_delayed

14、_work(&work,delay); 刷新操作 flush_scheduled_work(); cancel_ 创建新的队列.23选择推后任务的处理机制 上下文顺序执行保障 软中断中断没有 Tasklet中断同类型的不能同时执行 工作队列进程没有.24加锁的问题 下半部之间 下半部与用户进程之间有共享资源的地方要加锁.25内核同步问题 临界区临界区就是访问和操作共享资源的代码段,必须保证原子地执行才能保证安全。 共享变量的例子(p90).26内核同步问题 加锁一个简单共享变量的操作问题还容易解决一些,比如让硬件本身提供原子操作的复合指令。但若是共享的是一个复杂的数据结构,比如一个结构的链表,就不能这样解决啦。加锁的思路是,保证在临界区中执行的线程只有一个。(P91).27内核同步问题 同步问题一般必须事先设计好,否则很难调试。(即使不加处理,有时也很难出现错误) 内核中有并发执行,所以也有同步问题,引起并发的原因: 中断 内核抢占 睡眠及用户空间的同步 对称多处理.28内核同步问题 死锁 死锁产生的四个必要条件.29内核同步方法 原子操作 原子整数操作 Atomic_dec_and_test(atomic_t,*v) 原子位操作 Set_bit(0,&word).30内核同步方法

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论