Linux kernel task work机制
文章目录
task work机制可以在内核中向指定的进程添加一些任务函数,这些任务函数会在进程返回用户态时执行,使用的是该进程的上下文。
本文部分转载自:Linux:task work 机制,内核代码的版本是v4.18。
1. definition
进程对象task_struct中有个字段用来存储这些待进行的任务列表头即task_works,这个结构体包含一个next指针和需要执行的函数指针。1
2
3
4
5
6
7
8
9/**
* struct callback_head - callback structure for use with RCU and task_work
* @next: next update requests in a list
* @func: actual update function to call after the grace period.
*/
struct callback_head {
struct callback_head *next;
void (*func)(struct callback_head *head);
};
2. task_work_add
1 | static struct callback_head work_exited; /* all we need is ->next == NULL */ |
主要工作:
- 通过CAS以无锁的形式添加了一个链表元素。(新元素排在原有链表头部)
set_notify_resume
函数向指定的进程设置了一个_TIF_NOTIFY_RESUME
标记。
3. task_work_run执行时机
3.1 with _TIF_NOTIFY_RESUME
flag
3.1.1 exit_to_usermode_loop
1 | static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) |
3.1.2 tracehook_notify_resume
1 | /** |
在进程对象的task_works不为null的情况下才有任务需要执行。
3.2 without _TIF_NOTIFY_RESUME
flag
get_signal
执行task_work_run
1 | // 执行task work机制中的work |
4. task_work_run
1 | /** |
- 通过CAS,以无锁的方式取得
task_works
链表 - 因为原链表是按元素添加到链表的时间逆序排列的(见
task_work_add
),先把链表反转一遍 - 反转链表后,遍历链表,执行各个元素的任务函数即
work->func(work)
参考资料: