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>
