第一次读这本linux的圣经的时候,真是一头雾水,无从下手,参考知乎上知友推荐的阅读顺序,勉勉强强读完了第一遍,脑袋里有了印象,之后在工作中用到了一些东西,参考代码,然后才准备第二次阅读,结合陈老师的读书笔记,梳理框架,整理思路,做学习记录。
中断下半部的处理机制
1.软中断请求(softirq)机制 软中断的分配是静态的(即在编译时定义),同一种类型的软中断可并发的运行在多个cpu上,所以软中断是可重入函数且必须明确使用自旋锁保护其数据结构,软中断代码在:kernel/softirq.c,软中断流程如下 2.小任务(tasklet)机制 tasklet分配和初始化可在运行事进行(eg:安装一个内核模块时),相同类型的tasklet总是被串行的执行,即不能再两个cpu同事运行相同类型的tasklet,但类型不同的tasklet可在几个cpu上并发执行,tasklet也是利用软中断实现,但提供了比软中断更好的接口,一般建议使用tasklet实现自己的中断。 tasklet对应的结构体在 <linux/interrupt.h> 中
struct tasklet_struct
{
struct tasklet_struct *next;
unsigned long state;
atomic_t count;
void (*func)(unsigned long);
unsigned long data;
};
3.工作队列机制 以上的可延迟函数运行在中断上下文中,工作队列的函数运行在进程上下文中,执行可阻塞函数(eg:需访问磁盘数据块的函数)的唯一饭否是是在进程上下文运行,因为中断上下文不可能发生进程切换,可延迟函数(软中断)和工作队列函数君不能访问进程用户态地址空间,工作队列中的函数是由内核线程来执行的。 (1)工作队列用到的3个结构体如下:
struct work_struct {
atomic_long_t data;
#define WORK_STRUCT_PENDING 0
#define WORK_STRUCT_FLAG_MASK (3UL)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
struct list_head entry;
work_func_t func;
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
struct cpu_workqueue_struct {
spinlock_t lock;
struct list_head worklist;
wait_queue_head_t more_work;
struct work_struct *current_work;
struct workqueue_struct *wq;
struct task_struct *thread;
} ____cacheline_aligned;
struct workqueue_struct {
struct cpu_workqueue_struct *cpu_wq;
struct list_head list;
const char *name;
int singlethread;
int freezeable;
int rt;
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
(2)工作队列的执行流程 在学习中进步,如有错误,请多多批评指正
|