The To-Do List
- Get timer irqs on secondary cpus.
- Get other irqs on secondary cpus (sysctl!!)
- Send APIC->APIC irq when process is killed.
- Send APIC->APIC irq when debugger or panic.
- Make statistics look sensible for SMP.
- Move apic_startup before pmap_bootstrap.
- Add handshake so that all cpu's have paging enabled before pmap_bootstrap
- Patch the address of the real GDT into the mpboot trampoline and use
that instead.
- Make sysctl var for MP-desc structure from bios. (For easier examination)
- Make cpu-id stuff an array[NCPU].
- Make ldt stuff an array[NCPU]
- Revive the original scheme of having a "processor unique" page
at the same fixed address, and do away with 99% of the APIC_ID reads.
Then, simply have the each processor's specific page double-mapped into an
array of all processor's pages.
- Defer the smp startup until much later in the boot. locore and init386
will do the minimal amount of init work to detect SMP and reserve space,
but leave it open ended.
later on, when the timers are running, VM is active (so we can allocate
memory :-), cpu clock speed is known, etc, we parse the MP config block
(or use the "default" configuration if it's not supplied), allocate UPAGES
for each cpu (PDIR+KSTACK+pcb), create a state for it to idle in, and fire
up the cpu, directing it towards a smp-aware _idle() loop.
- get rid of the cpuidle0/1 procs, they are not needed.
- finish generic apic IPI message passing code
- program the apic timers to give a local 100Hz scheduling interrupt, and
release the 8259 timer that currently does this.
- fix the pentium_microtime code so that it deals with multiple cpu's
properly.
A more current list from Peter, needs merging with the above...
- we need to identify (speed, stepping, speed, etc) each cpu in the system,
not just the first one.
- we need to calibrate the clocks on all cpus rather than disabling the
code.
- npx needs to be investigated once and for all so that we can turn back on
the i586 fast copyin/out/bcopy code.
- run queue needs restructuring so that there is a per-cpu queue of
runnable tasks. This means that a cpu could access it's own run queue
outside the kernel lock.
- processor affinity and binding in the scheduler when determining
which cpu's run queue to put a process into. (to conserve the i686 cpu cache)
- interrupt system redesign for at least the apic case so that we can
have 'N' interrupts. I've talked with a few people about this extensively
some time ago, I should make notes and let you see what you think.
- make "outer" kernel interface code reentrant so that we can lock at the
syscall/trap/interrupt handler entry rather than a global lock. (first step
of pushdown)
- make shared address spaces work.. The VM system needs to know when
the page tables of a "!= curproc" process might be in use on another
cpu (ie: check all other SMPcurproc[]'s). When modifying the current process
it needs to check the vmspace reference count and do the appropriate IPI's
to the other cpu. Locking is a problem here. This is more John Dyson's
area (He has a dual P6 motherboard, but just one cpu at present. He'll be
joining in soon)
- fix killing of processes. One cpu can 'kill -9' a process that's running
in usermode on another cpu. It needs an IPI so that it stops executing and
begins signal-receipt handling. Forced kills of processes needs work (eg:
when out of swap space, a process is nuked by the current thread of execution
rather than having the process deallocate itself at next schedule)
- fix up stats and scheduling. There are more scheduling variables that
need to be per-cpu.
- ipi's for reboot/halt, ddb and panic.
- There's a hell of a lot more variables and data that need to be
per-cpu (eg: clock, run queue, stats, etc). This is getting to
the point that we must do per-cpu fixed address pages or we'll go
#ifdef crazy and the slowdown from calling cpunumber() so often
will become very noticable.