Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Feb 2002 03:09:38 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        Terry Lambert <tlambert2@mindspring.com>, Alfred Perlstein <alfred@FreeBSD.ORG>, Bosko Milekic <bmilekic@unixdaemons.com>, Seigo Tanimura <tanimura@r.dl.itc.u-tokyo.ac.jp>, <current@FreeBSD.ORG>, John Baldwin <jhb@FreeBSD.ORG>
Subject:   Success!  critical_enter()/critical_exit() revamp (was Re: malloc_bucket() idea (was Re: How to fix malloc.))
Message-ID:  <200202241109.g1OB9cn68688@apollo.backplane.com>
References:   <20020224131027.I31343-100000@gamplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
    I'm going to wait until tomorrow before posting it.  I have a bunch of
    cleanup to do.

    Bruce, your sys.dif was *invaluable*!  It would have taken me a lot 
    longer to figure out the interrupt disablement requirement around
    the icu_lock, and the statclock and hardclock forwarding issues (which I
    got working by the way!).

    It turns out that putting the pending masks in the per-cpu area was
    the right solution!  It made statclock and hardclock forwarding easy
    (I can see why you didn't even try in your patch set, doing it with
    a global mask would be nearly impossible).  In fact, it made everything
    unbelievably easy.

    Apart from all the assembly coding, there were two serious issues.
    fork_exit() assumes that interrupts are hard-disabled on entry.  I
    readjusted the code such that the trampoline assembly initialized
    the td_critnest count so it could STI prior to calling fork_exit().

    The second issue is that cpu_switch() does not save/restore the 
    PSL_I (interrupt disablement mask).  I added a PSL word to the PCB
    structure to take care of the problem.  Without this if you have
    a thread switch away while holding interrupts hard-disabled, the
    next thread will inherit the hard disablement.  I saw the sti's
    you added in various places but I figured the best solution was
    to simply save/restore the state.  The original code didn't have
    this problem because interrupts were always hard-disabled while
    holding the sched_lock and, of course, cpu_switch() is always
    called while holding sched_lock.  (Similarly, icu_lock needed 
    hard-disablements wrapped around it for the same reason, because
    a level interrupt still needs to be able to get icu_lock in order to
    defer itself).

    In anycase, I have successfully built the world in a -current 
    SMP + apic_vector system.  Tomorrow I will cleanup on the UP icu_vector
    code to match the apic_vector code and post the results.  I also
    have a sysctl that allows developers to toggle the mode for testing
    purposes (old way or new way).

    Finally, I took your suggestion in regards to not trying to combine
    the masks together.  I have a 'some sort of interrupt is pending'
    variable then I have fpending (for fast interrupts), ipending (for
    normal interrupt threads), and spending (which I use for the stat and
    hardclock forwarding).  They're all per-cpu entities, of course.
    unpend() prioritizes them.

    In anycase, I'll post it all tomorrow after I've got icu_vector cleaned
    up.  One of the best things about this patch set is that it is really
    flexible.  We should be able to really make interrupts fly.  In fact,
    it should even be possible for one cpu to steal another cpu's pending
    interrupt(s) fairly trivially, without having to resort to IPIs.

						-Matt


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202241109.g1OB9cn68688>