Re: [Bug 350] New: i386 context switch very slow compared to 2.4 due to wrmsr (performance)

Linus Torvalds
2003-03-10T18:25:53Z

On Mon, 10 Mar 2003, Andi Kleen wrote:
>
> Unfortunately the patch still has the problem pointed out by Manfred
> Spraul: if you're unlucky it could destroy the _TIF_SIGPENDING set by
> another CPU with the non atomic access. Really thread_info should have
> two flag words: one that is truly local and can be accessed without LOCK
> and one that can be changed at will by external users too.

Yup, you're right.

I fixed that by splitting the "flags" field into two: "flags" is the old
flags, and "status" is thread-synchronous stuff (ie things that don't need
to worry about atomicity). Right now the FP lazy bit is the only thing
that is marked as thread-synchronous.

While going through the users I also noticed that fork() did the FPU
unlazy() thing totally wrong - it the the parent unlazy() _after_ it had
already copied the process flags to the child, so even though it copied
the x87 state to the child, the process flags could still say that the
child was using lazy state, and thus the FP state in the child was
basically totally corrupt. I wrote a test program to verify.

So I fixed that part too, by having a "prepare_to_copy()" function that
properly "calms down" the parent before we copy the task and thread
states. That fixes the bug, and also avoids an extra unnecessary x87 state
copy on x86.

(Not that the extra copy is noticeable - fork() is expensive enough
anyway. It might just _barely_ be noticeable on thread creation when we
don't have to worry about copying the VM state. But the bug was real,
and the simplification is an added bonus).

Linus