Hi all,
        I have some questions when reading source code of callb and scheduler 
subsystems, which seem to me like possble race  conditions.
        The first case is race between callb_execute_class() and 
callb_delete(). 
Relative code from uts/common/os/callb.c as below:
void *
callb_execute_class(int class, int code)
{
        mutex_enter(&ct->ct_lock);
        for (cp = ct->ct_first_cb[class];
            cp != NULL && ret == 0; cp = cp->c_next) {
                while (cp->c_flag & CALLB_EXECUTING)
                        cv_wait(&cp->c_done_cv, &ct->ct_lock);
                /*
                 * cont if the callb is deleted while we're sleeping
                 */
                if (cp->c_flag == CALLB_FREE)
                        continue;
                cp->c_flag |= CALLB_EXECUTING;
                mutex_exit(&ct->ct_lock);
                if (!(*cp->c_func)(cp->c_arg, code))
                        ret = cp->c_name;
                mutex_enter(&ct->ct_lock);
                cp->c_flag &= ~CALLB_EXECUTING;
                cv_broadcast(&cp->c_done_cv);
        }
        mutex_exit(&ct->ct_lock);
        return (ret);
}

        Suspicious code is
                /*
                 * cont if the callb is deleted while we're sleeping
                 */
                if (cp->c_flag == CALLB_FREE)
                        continue; 
        Actually, when (cp->c_flag == CALLB_FREE) is true, cp->c_next should
already point to next node on freelist instead of on class list.

        The second case is relative to function disp_setup() in 
uts/common/disp/disp.c.
dsip_setup() tries to grow dispatch queue entries in dispatch table when 
increasing max
global priority. In current implementation, all other CPUs will be paused when 
replacing
per-CPU dispatch table to protect it, but there's no such protection when 
replacing
CPU partition level preempt dispatch table.
        The above possible race condition could be triggered by configure 
"kpqpri" to
a value less than 100 in /etc/system.
        BTW, following code in function disp_setup() may be isn not what we 
want because
kpqpri has been already set to kpreemptpri in disp_init(), so test "(kpqpri == 
KPQPRI)" will
always be false.
                        if (kpqpri == KPQPRI)
                                kpqpri = kpreemptpri;

        Thanks!

Liu Jiang (Gerry)
Senior Software Engineer
OpenSolaris, OTC, SSG, Intel
Tel: (8610)82171643
iNet: 8-758-1643
Location: Raycom 9W013


_______________________________________________
opensolaris-code mailing list
opensolaris-code@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to