## The To-Do List

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.
- multiple IO apics (long term).

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.