关于task_struct flags的race condition
关于do_exit()中对task_struct进行访问不加锁的问题。我今天找到了一个具体的例子,希望高手指正。
fastcall NORET_TYPE void do_exit(long code)
{
... ...
tsk->flags |= PF_EXITING;
/*
* Make sure we don't try to process any timer firings
* while we are already exiting.
*/
tsk->it_virt_expires = cputime_zero;
tsk->it_prof_expires = cputime_zero;
tsk->it_sched_expires = 0;
... ...
}
static void process_timer_rebalance(struct task_struct *p,
unsigned int clock_idx,
union cpu_time_count expires,
union cpu_time_count val)
{
... ...
do {
if (likely(!(t->flags & PF_EXITING))) {
ticks = cputime_add(virt_ticks(t), left);
if (cputime_eq(t->it_virt_expires,
cputime_zero) ||
cputime_gt(t->it_virt_expires, ticks)) {
t->it_virt_expires = ticks;
}
}
t = next_thread(t);
} while (t != p);
break;
... ...
}
上面两个函数对it_virt_expires的访问存在race condition,其执行顺序可能为:
1. process_timer_rebalanc()检查
if (cputime_eq(t->it_virt_expires, cputime_zero) ||
cputime_gt(t->it_virt_expires, ticks))
2. do_exit()设置flags = PF_EXITING,it_virt_expirtes = 0。
3. process_timer_rebalanc()将it_virt_expires设置为ticks。
至此,it_virt_expires在进程处于PF_EXITING状态时仍然不为0。
请高手指正我对这个race conditon分析得对不对。这个问题对kernel有没有实质的影响。