中断分层处理-工作队列
4.中断分层处理
a.中断嵌套
中断嵌套指的是当一种中断产生的时候,又发现了另一种类型的中断。
b.中断分层方式
假如一个中断处理程序需要10秒钟,中断处理程序运行到第七秒的时候,出现了另外一种类型的中断,但是另外一种类型的中断丢失掉了,那么如何解决呢?一种方法是将中断处理的时间尽量缩短,减少丢失中断的可能。那么如何缩短处理的时间呢?中断处理的工作分为两种,一种与硬件相关,另一种是程序做的工作,包括中断检测,中断处理(可以将这部分工作放到其他部分来工作),这个就叫中断分层技术。
另一种是
a.1软中断
a.2tasklet
a.3工作队列(用的最为广泛)
工作队列是一种将任务推后执行的形式,他把推后的任务交由一个内核线程去执行。这样下半部会在进程上下文执行,它允许重新
调度甚至睡眠。 每个被推后的任务叫做“工作”,由这些工作组成的队列称为工作队列。
c.使用工作队列实现分层
struct workqueue_struct {
unsigned int flags; /* W: WQ_* flags */
union {
struct cpu_workqueue_struct __percpu *pcpu;
struct cpu_workqueue_struct *single;
unsigned long v;
}cpu_wq; /* I: cwq's */
struct list_head list;/* W: list of all workqueues */
struct mutex flush_mutex;/* protects wq flushing */
int work_color; /* F: current work color */
int flush_color; /* F: current flush color */
atomic_t nr_cwqs_to_flush; /* flush in progress */
struct wq_flusher *first_flusher; /* F: first flusher */
struct list_head flusher_queue; /* F: flush waiters */
struct list_head flusher_overflow; /* F: flush overflow list */
mayday_mask_t mayday_mask; /* cpus requesting rescue */
struct worker *rescuer; /* I: rescue worker */
int nr_drainers; /* W: drain in progress */
int saved_max_active; /* W: saved cwq max_active */
const char *name; /* I: workqueue name */
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
工作队列的使用:创建工作队列(create_workqueue)-》创建工作(init_work)-》提交工作(queue_work)。
#include<linux/init.h>
#include<linux/module.h>
#include<linux/io.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
struct workqueue_struct *my_wq;//定义工作队列
struct work_struct *work;//定义工作
void work_func(struct work_struct *work)//打印语句
{
printk("<0>this is work->\n");
}
static int work_init(void)
{
my_wq = create_workqueue("my_que");//创建工作队列,create_workqueue(name) ;//name为工作队列的名字,返回的是工作队列的一个指针。
work = kmalloc(sizeof(struct work_struct),GFP_KERNEL);//为工作分配内存空间
INIT_WORK(work,work_func);//创建工作,work为初始化工作指针,work_func为要执行的函数。
queue_work(my_wq,work);//挂载工作
return 0;
}
static void work_exit(void)
{
}
module_init(work_init);
module_exit(work_exit);
MODULE_LICENSE("GPL");