It kinda sounds like the interrupt/trap code that calls into
    kern/subr_trap.c should be responsible for placing us in a 
    critical section.  kern/subr_trap.c has no business making
    assumptions in regards to cpu_critical_enter()/cpu_critical_exit()
    (for the same reason that fork_exit() has no business making
    those kinds of assumptions).

    For the moment I'm not going to worry about it.  I'll just keep the
    cpu_critical_*() API intact for i386 for now.

                                        Matthew Dillon 
                                        <[EMAIL PROTECTED]>

:The use of cpu_critical*() in subr_trap.c is a bit trickier/kludgier.
:We need to return from the interrupt handler atomically with clearing
:the lazy-masking flag.  The hardware interrupt enable flag must be
:used for this on i386's.  The code for this is logically:
:In ast:
:       /* Prevent changes to flags while we are deciding if they are set. */
:       critical_enter();
:       while ((ke->ke_flags & (KEF_ASTPENDING | KEF_NEEDRESCHED)) != 0) {
:               critical_exit();
:               ...
:               /* As above. */
:               critical_enter();
:       }
:In doreti:
:       /*
:        * Must use MD code to prevent race window after critical_exit().
:        * We switch from lazy sofware masking using td_critnest (or
:        * whatever critical_enter() uses) to hardware masking using cli.
:        */
:       cli();
:       critical_exit();
:       ...
:       iretd();
:but this is optimized in -current by using cpu_critical*() instead of
:critical_enter*() in ast() and not doing the cli() and critical_exit()
:in doreti.  This depends on cpu_critical_enter() being precisely cli().

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to