The To-Do List
Some serious bit-rot here...
Completion of simple private pages.
- detailed design.
- enable shared address spaces.
- implement allocation of VM during bootstrap.
- complete context switching support.
- identify (speed, stepping, etc) each cpu.
- keep per-cpu clocks in sync with each other.
(non-symmetrical master/slaves time roles).
- locate more per-cpu vars (eg: curpriority, clock, run queue, stats, etc.).
- move other variables to per-cpu as needed.
Implement more specialised lock primitives.
- adapt the Lite2 lock manager and other locking
primatives to enable better dignostic and debugging
tracing and statistics. This will be spread over
the lifetime of the project as we need it.
Make interrupt/trap paths into the kernel reentrant.
- detailed design.
- 'push-down' global lock to:
- vm system.
- syscalls.
- traps.
- interrupt handlers.
IO APIC interrupt restructure.
- detailed design.
- handle >32 interrupt sources.
- even dist. of IDT vectors into APIC slots.
Fix the address space sharing.
- detailed design.
- track users of shared address space.
- make threading work.
- have the each processor's specific page double-mapped into an
array of all processor's pages.
Make the easy syscalls re-entrant without global lock.
- detailed design, identify "easy" syscalls
- code each one.
- restructure *easy* data structures to avoid locking problems, eg:
store parent process id in a child's struct to avoid getppid() from
locking parent proc struct.
Improved clock handling.
- calibrate clocks on all CPUs
- uniform handling of of hardclock tick
- speed up the hz tick if applicable. Possibly use
hz = ncpu * 100 - we need more ticks for better
responsiveness under hard scheduling load.
Additional IPIs.
- reboot/halt
- ddb
- panic
- kill process on other cpu:
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).
- forced reschedule on other cpu[s].
Fix up stats and scheduling.
- design more sensible statistics for SMP
- implement collection of statistics
- more scheduling variables that need to be per-cpu.
Processor (cache) affinity and binding in the scheduler.
- scheduler re-balance of load on cpus.
- soft processor affinity creates risk of unbalancing the load, for
long-running cpu-intensive tasks. Requires per-cpu load average etc.
Additional run queue management.
- 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.
- 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.
Fix kernel profiling to be SMP aware and design and
implement tools for profiling lock usage and congestion.
Start pushing the locking further down.
- detailed design
- global run queue and sleep queues
- timeout queue
- proc list
- memory pool
- make generic filesystem code reentrant
- make specific filesystems reentrant.
- profiling and benchmarking to identify "hot spots"
- fix or redesign code to best fix bottlenecks.
Misc ideas:
- Get other irqs on secondary cpus (sysctl!!)
- Move apic_startup before pmap_bootstrap.
- Add handshake so that all cpu's have paging enabled before pmap_bootstrap.
- Patch address of the real GDT into mpboot trampoline and use that instead.
- Make sysctl var for MP-desc structure from bios. (For easier examination)
- Make ldt stuff an array[NCPU]
- 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.
- fix pentium_microtime code so that it deals with multiple cpu's properly.