Rather than an "iointr" routine that decomposes a vector into an
IRQ, we maintain a vector table directly, hooking up each "iointr"
routine at the correct vector. This also allows us to hook device
interrupts up to specific vectors (c.f. Jensen).
We can shave even more cycles off, here, and I will, but it requires
some changes to the alpha_shared_intr stuff.
be locked before it can be marked as `active' on a processor.
- Require that pmaps other than the kernel pmap be locked when they
are passed to pmap_tlb_shootdown(). This, combined with the locking
protocol tweak, allow us to get a consistent view of `activeness' of
a pmap, which means we can optmize away a lot of TLB shootdown traffic
for user pmaps.
- Borrow an idea from the i386mp branch; use the normal SHOOTDOWN IPI
to deal with hitting the entire TLB, and garbage-collect the TBIA
and TBIAP IPIs.
using the cycle counter. MP-safeness is achieved by giving each
CPU its own PCC frequency variables, and kicking the non-primary
processors via an IPI once per second.
Based on the sample code from David Mills' "A Kernel Model for
Precision Timekeeping".
to arrive here referencing the kernel_lev1map without having the
RESERVED ASN -- another CPU may have caused pmap_lev1map_destroy()
to be called, and that routine only invalidates the ASN for the
CPU that called it. So, in the MULTIPROCESSOR case, simply assign
the RESERVED ASN if we reference the kernel_lev1map rather than
asserting that we already have the RESERVED ASN. Thanks to Bill
Sommerfeld for helping me track down the problem.
Also add a new IPI that causes a CPU to re-activate its address
space if the pmap it's using changes level 1 maps (this probably
won't happen very often, but it's correct to have it).
This makes Alpha MP kernels boot multiuser. In fact, this commit
is being made from my dual-CPU AlphaServer 1200 running an MP kernel.
and place the definition in <machine/types.h>. This can now be used
as a flag to indicate whether or not <machine/intr.h> can be included
to get the generic soft interrupt API.
multiprocessor support:
- Implement MP-safe halt.
- Make the FPU saving code more like Bill's on the i386 MP branch.
XXX This code will no doubt be revisited again.
- Pass the cpu_info and trapframe to IPI handlers, saving some work
in the handlers themselves, and also making it possible for the
"pause" handler to reference register state for DDB.
- Add "machine cpu" to DDB, making it possible to reference other
CPUs registers (and thus get e.g. a traceback) from whichever
CPU is actually running the debugger.
- Garbage-collect "machine halt" and "machine reboot" DDB commands.
They don't have a prayer of working properly in multiprocessor
kernels, and didn't really work all that well in uniprocessor kernels.
macro in the MULTIPROCESSOR case (hardclock() wants it).
- Implement __GENERIC_SOFT_INTERRUPTS, and redefine the legacy
software interrupts in terms of it. Garbage-collect setsoftserial().
add an IPI which causes the target CPU to perform AST processing when
it returns to userspace.
- Add a way to get/set a private pointer in the shared interrupt header.
that is priority is rasied. Add a new spllowersoftclock() to provide the
atomic drop-to-softclock semantics that the old splsoftclock() provided,
and update calls accordingly.
This fixes a problem with using the "rnd" pseudo-device from within
interrupt context to extract random data (e.g. from within the softnet
interrupt) where doing so would incorrectly unblock interrupts (causing
all sorts of lossage).
XXX 4 platforms do not have priority-raising capability: newsmips, sparc,
XXX sparc64, and VAX. This platforms still have this bug until their
XXX spl*() functions are fixed.
tty structures, and on some machines (namely the DraCo internal lpt, and some
multi-i/o boards for Amigas and DraCos), tying spltty to the pretty high printer
interupt level would hurt serial performance.
On all affected ports but Amiga, spllpt() has been defined in machine/intr.h
to be spltty(), thus preserving old behaviour. Portmasters are encouraged to
change is, if they feel something else is better (e.g., one of its own were
possible).
(1) it was using 'max', and some functions use a variable
of that name (*sigh*), and
(2) that makes it easier to be a bit trickier, and only call
swpipl if changing the IPL.