LinuxÒÁµéÔ°ÂÛ̳'s Archiver

middleware ·¢±íÓÚ 2006-6-18 23:04

¡¾ÌÖÂÛ¡¿Race Condition on task_struct

¹ØÓÚdo_exit()ÖжÔtask_struct½øÐзÃÎʲ»¼ÓËøµÄÎÊÌâ¡£ÎÒ½ñÌìÕÒµ½ÁËÒ»¸örace conditionµÄÀý×Ó£¬Ï£Íû¸ßÊÖÖ¸Õý¡£

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ÓÐûÓÐʵÖʵÄÓ°Ïì¡£

Ò³: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.