git: kernel - Fix serious issue w/ smp_invltlb(), plus other issues (2)
Matthew Dillon
dillon at crater.dragonflybsd.org
Thu Oct 28 14:22:48 PDT 2010
commit 2d910aaf6e46b623aae5ea8623eacfcd23f6e9dc
Author: Matthew Dillon <dillon at apollo.backplane.com>
Date: Thu Oct 28 12:36:32 2010 -0700
kernel - Fix serious issue w/ smp_invltlb(), plus other issues (2)
It looks like there are a number of additional cases where kernel threads
can wind up running with interrupts physically disabled, which can create
serious problems for smp_invltlb().
It is not entirely clear how these deadlocks occur since the IPI code does
a forced "STI" if it would otherwise loop, but there are several other
hard loops that do not: lwkt_switch looping on a vm_token, spin locks,
and probably a few other places.
We want interrupts to be enabled in all cases where these sorts of loops
occur in order to be able to service Xinvltlb via smp_invltlb() as well
as to prevent the LAPIC interrupt queue from filling up and livelocking
something that it shouldn't.
* lwkt_preempt() must save, zero, and restore gd->gd_intr_nesting_level
when issuing a preemption. Otherwise it will improperly panic on
an assertion if the preempting interrupt thread code tries to switch out.
It is perfectly acceptable for the preempting thread to block (it just
switches back to the thread that got preempted).
Why the assertion was not occuring before I do not know but it is
probably related to threads getting stuck in 'cli' mode. The additional
changes below appear to significantly increase the number of interrupt
thread preemptions which succeed (lwkt.preempt_{hit,miss} counters).
* STI prior to running ithread_fast_handler() from all IDTVECs related
to device interrupts.
* STI in Xcpustop, Xipiq, and Xtimer. These functions can call more
complex C code and doing so with interrupts disabled may prevent
Xinvltlb (via smp_invltlb()) from being executed, deadlocking the
system.
* Reorder a mfence(). Probably not needed but do it anyway.
Summary of changes:
sys/kern/lwkt_thread.c | 8 +++++++
sys/platform/pc32/apic/apic_vector.s | 9 +++++++
sys/platform/pc32/i386/mp_machdep.c | 38 +++++++++++++++++++++++++++++++++
sys/platform/pc32/icu/icu_vector.s | 1 +
sys/platform/pc64/apic/apic_vector.s | 9 +++++++
sys/platform/pc64/icu/icu_vector.s | 1 +
sys/platform/pc64/x86_64/mp_machdep.c | 38 ++++++++++++++++++++++++++++----
7 files changed, 99 insertions(+), 5 deletions(-)
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/2d910aaf6e46b623aae5ea8623eacfcd23f6e9dc
--
DragonFly BSD source repository
More information about the Commits
mailing list