11 tasklet
1 tasklet调度机制
task属于软中断,有HI_SOFTIRQ和TASKLET_SOFTIRQ两种类型。tasklet又名“小任务”,所以过于复杂的操作一般交给workqueue或其他机制实现

中断下半部softirq_init中会调用tasklet_hi_action或taskletaction。两者最终都会调用到tasklet_action_common
在while循环中遍历链表中每一个tasklet,如果tasklet没有执行,且count字段为0,则调用它的回调函数。否则将其插入清空后的链表
简单说就是被执行过的tasklet会从链表中删除,没有被执行过的tasklet会被重新放入一个被清空过后的链表
注意:tasklet无法从链表中删除函数,只能通过task_disable去阻止它执行。tasklet_kill并不删除tasklet,而是清除tasklet的状态
2 常用API和数据结构
| 函数和宏 | 描述 |
|---|---|
| DECLARE_TASKLET/DECLARE_TASKLE_OLD | 定义tasklet,count字段初始化为0 |
| DECLARE_TASKLET_DISABLED/DECLARE_TASKLET_DISABLED_OLD | 定义tasklet,count字段初始化为1 |
| tasklet_init | 初始化tasklet,count幅值为0 |
| tasklet_enable | 使能tasklet |
| tasklet_disable | 禁止tasklet,如果tasklet正在执行,需要等待其执行完毕才会返回 |
| tasklet_hi_schedule | 调度tasklet执行,对应HI_SOFTIRQ |
| tasklet_schedule | 调度tasklet执行,对应TASKLET_SOFTIRQ |
| tasklet_kill | 清除tasklet调度和运行状态,如果tasklet正在执行,需要等待其执行完毕才会返回 |
2.1 tasklet_struct
struct tasklet_struct
{
struct tasklet_struct *next;
unsigned long state; /* 当前状态. TASKLET_STATE_SCHED:加入调度等待执行。TASKLET_STATE_RUN:正在执行 */
atomic_t count; /* 此tasklet是否使能 */
void (*func)(unsigned long); /* 回调函数 */
unsigned long data; /* 回调函数的参数 */
};
state : 表示tasklet的状态
bit0为tasklet是否放入了tasklet队列。(1为已经放入了tasklet队列)
bit1为此tasklet是否已经执行完毕。(0表示内核已经调度完成此小任务)
count : 表示task是否使能。0表示使能
2.2 tasklet_init
/**
* 初始化task_let,并使能
*/
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;
}
2.3 tasklet_enable、tasklet_disable
/**
* tasklet使能和禁止
*/
static inline void tasklet_enable(struct tasklet_struct *t);
static inline void tasklet_disable(struct tasklet_struct *t);
2.4 task_schedule
/**
* 开始taskletd的调度,将tasklet放入tasklet的队列
*/
static inline void tasklet_schedule(struct tasklet_struct *t);
2.5 tasklet_kill
/**
* 如何一个进程没有被调度(未被放入队列),择将它的调度状态变更为0
* 如果一个tasklet已经被调度(已经放入队列),择将会等其被执行后再将其调度状态清0
*/
void tasklet_kill(struct tasklet_struct *t);

浙公网安备 33010602011771号