第二十四节、中断下文之tasklet
本节用于介绍中断下文之tasklet
一、tasklet 相关知识点
1、什么是tasklet?
tasklet是中断处理中断下文常用的一种方法,tasklet是一种特殊的软中断。处理中断下文的机制还有工作队列和软中断。
2、怎么使用tasklet来设计中断下文?
Linux把中断分成俩个部分,一个是上半部分,一个是下半部分,在上半部分我们只处理紧急的事情,同时可以调用tasklet来启动中断下文,比较耗时间的就要放到下文来处理,调用tasklet以后,tasklet绑定的函数并不会立马执行,而是出中断以后,经过一个很短的不确定时间在来执行。
3.tasklet定义
tasklet 由 tasklet_struct 结构表示,每个结构体单独代表一个tasklet
文件位置路径:include/linux/interrupt.h
struct tasklet_struct
{
struct tasklet_struct *next; //链表中的下一个tasklet,方便管理和设置tasklet
unsigned long state; //tasklet的状态
atomic_t count; //表示tasklet是否出在激活状态,如果是0,就处在激活状态,如果非0,就处在非激活状态
void (*func)(unsigned long); //结构体中的func 成员是tasklet的绑定函数,data是它唯一的参数
unsigned long data; //函数执行的时候传递的参数
};
二、tasklet 相关函数
<1>tasklet_schedule函数
作用:调度tasklet
函数原型:
文件位置路径:include/linux/interrupt.h
extern void __tasklet_schedule(struct tasklet_struct *t);
static inline void tasklet_schedule(struct tasklet_struct *t)
{
if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
__tasklet_schedule(t);
}
//参数
//t:指向tasklet_struct的指针
<2>tasklet_init函数
作用:动态初始化tasklet
函数原型:
文件位置路径:include/linux/interrupt.h
实际函数位置路径:kernel/softirq.c
extern void tasklet_init(struct tasklet_struct *t,
void (*func)(unsigned long), unsigned long data);
void tasklet_init(struct tasklet_struct *t,
void (*func)(unsigned long), unsigned long data)
{
t->next = NULL;
t->state = 0;
atomic_set(&t->count, 0);
t->func = func;
t->data = data;
}
EXPORT_SYMBOL(tasklet_init);
//参数
//t:指向tasklet_struct的指针
//func:tasklet绑定的函数
//data:函数执行的时候传递的函数
<3>tasklet_kill 函数
作用:删除一个tasklet
函数原型:
extern void tasklet_kill(struct tasklet_struct *t);
void tasklet_kill(struct tasklet_struct *t)
{
if (in_interrupt())
pr_notice("Attempt to kill tasklet from interrupt\n");
while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
do {
yield();
} while (test_bit(TASKLET_STATE_SCHED, &t->state));
}
tasklet_unlock_wait(t);
clear_bit(TASKLET_STATE_SCHED, &t->state);
}
EXPORT_SYMBOL(tasklet_kill);
//参数
//t:指向tasklet_struct的指针
注意:这个函数会等待tasklet 执行完毕,然后再将它移除。该函数可能会引起休眠,所以要禁止在中断上下文中使用。
三、使用tasklet 设计中断下文步骤
- 定义一个tasklet结构体
- 动态初始化tasklet
- 编写tasklet绑定的函数
- 在中断上文调用tasklet
- 卸载模块的时候删除 tasklet