:*sigh* Couldn't you have changed the subject line when discussing
:something of this importance?

    Sorry.  Now I am so much in a huff I'm thinking about how all this
    could be implemented from scratch with the 4.x base.  I know, I know,
    good luck Matt...

    For example, this business about interrupts as threads.  BSDI had an
    interesting solution, but what I liked most about it was that if an
    interrupt could be completed right then and there it was just like a
    normal interrupt.  It's the bit about switching stacks, detecting a
    mutex interlock, and blocking as a thread which was the complex part.
    But I think I just now came up with a better one (and to be fair, I
    just came up with this now).

    Interrupts by definition know precisely what they are going to do, so by
    definition they know precisely which mutexes (if any) they may need
    to get.  This means that, in fact, it is possible to implement a check
    to determine if any of the mutexes an interrupt might want to get are
    already being held by the SAME cpu or not, and if they are to do the
    equivalent of what our delayed-interrupt stuff does in the stable's
    spl/splx code, but instead do the check when a mutex is released.

    The result is:  No need for an idle process to support interrupt
    contexts, no need to implement interrupts as threads, and no need
    to implement fancy scheduling tricks or Giant handling.


        mainline kernel {
            s = splblah();
            masked interrupt occurs, sets bit and immediately irets
            (bit found to be set and delayed interrupt is issued here)


        mainline kernel {
            masked interrupt occurs, interrupt structure contains array
            of mutexes the interrupt will need.  Check said mutexes, one
            found to be held by current cpu.  Set interrupt-pending bit
            in mutex and iret immediately.
            (bit found to be set in mutex, triggers interrupt reissuing code)

    And there you have it.  The mutex/array test is takes very little time
    being a read-only test that requires no bus locking, and the collision
    case is cheap also because the current cpu already owns the mutex, allowing
    us to set the interrupt-pending bit in that mutex without any bus
    locking.  The check during the release of the mutex is two instructions,
    no bus locking required.  The whole thing can be implemented without any
    additional bus locking and virtually no contention.

    The case could be further optimized by requiring that interrupts only
    use a single mutex, period.  This would allow the mainline interrupt
    routine to obtain the mutex on entry to the interrupt and allow the 
    reissuing code to reissue the interrupt without freeing the mutex that
    caused the reissue, so the mutex is held throughout and then freed by
    the interrupt itself.

    Holy shit.  I think that's it!  I don't think it can get much better then
    that.  It solves all of BDE's issues, solves the interrupt-as-thread
    issue (by not using threads for interrupts at all), and removes a huge
    amount of unnecessary complexity from the system.  We could even get rid
    of the idle processes if we wanted to.


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

Reply via email to