My personal feeling is that the problems are of the same order as the
Shuttle Challenger's problems.
I don't really know how to fix it, because I have not researched how the
fpu interlocking works and really don't know what the right approach is.
I am not 100% sure of the magnitude of the problem either. Simple floating
point seems to work quite safely, but the heavy demands of the X servers
pushes it over the edge.
Perhaps somebody would like to fill in the gaps in my understanding and
correct my bad assumptions..
As I understand it (in a standard kernel):
* npxproc is the pointer to the process that has been allocated the FPU.
* if npxproc == curproc, obviously it's running in the foreground.
* if the process takes an interrupt while a long running fpu operation is
in progress, it can be switched out (npxproc != cpuproc).
* if a process wants to use the fpu and curproc != npxproc (ie: another
process's FPU operation is still running), the FPU is halted, the FPU state
is stored in npxproc's pcb and the new process is either given a new fpu
context if it's never used it, or it's old fpu context is restored from
it's pcb.
* if the FPU traps with a completion signal (trap 16?, was irq 13), the
result is stored in the sleeping process's pcb (npxproc != curproc), or
the current process gets the result.
* when the kernel wants to use the FPU (for the i586 fast copying etc), it
has to jump through all sorts of hoops to "get" the fpu to itself.
Things I don't know or am not sure about:
* Is the state saving lazy? ie: does the process indicated in npxproc
have an up to date pcb when it's switched out, or is the process's state
"held" only on the FPU?
* can a process be the "owner" of the FPU even though it's sleeping or on
the run queue and not using the FPU? Does it have it's ownership taken
away when it's finished, or does it keep it indefinately until something
else uses it?
* If it's indefinate, this is a SMP killer. Imagine the process owning
the FPU on cpu#0 is scheduled onto cpu#1. cpu#1 would know nothing about
the fpu state on cpu#0, or the fact that the process owns the fpu "over
there". It could also be allocated ownership of cpu#1's fpu as well.
What if cpu#0 wants to kick the process off the fpu and saves the fpu#0
state in the proc's pcb while it's busy running on cpu#1?
I don't know the "right" answer. I assume that caching the last proc's
fpu state in the fpu is a win, if that's what we do.
I think some combination of "binding" fpu-active processes onto cpu's
might be needed, and/or flushing all fpu state out into the processes pcb
as it heads back to the run queue.
Cheers,
-Peter