Skip to contentSkip to conversation

BUG: Global FPU corruption in 2.2

DISCUSSION Victor Zandy 3 participants 4 messages Apr 24, 2001 1 message not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]'s

#1 lore raw

Someone else here traced the process flags of a FP-intensive program on a machine before and after it is put in the faulty FPU state. He periodically sampled /proc/pid/stat while the program was running.

He found that PF_USEDFPU was always set before the machine was broken. After he found that it was set about 70% of the time.

Vic

#2 lore raw

[ Alan, I'm lazy and only have 2.2.14 sources on-line. Maybe this has
been fixed already and there's something else going on. Worth a look ]

In article <[email protected]>,

Quoted 7 lines · Victor Zandy

Someone else here traced the process flags of a FP-intensive program on a machine before and after it is put in the faulty FPU state. He periodically sampled /proc/pid/stat while the program was running.

He found that PF_USEDFPU was always set before the machine was broken. After he found that it was set about 70% of the time.

[ Looks closer at the ptrace synchronization ]

Ahh.. This actually _does_ look like a race on "current->flags":
PTRACE_ATTACH will do a

	child->flags |= PF_PTRACED;

without waiting for the child to have stopped.

(Aside: thinking more about the stopping logic - I'm not actually sure the ptrace synchronization is complete wrt scheduling, as there will be a window when the process has set the task state to TASK_STOPPED but hasn't actually yet scheduled away. Oh, well).

All other ptrace operations (not counting killing the child) will check that the child is quiescent. But PTRACE_ATTACH will not, as we're just setting up the stopping.

In 2.4.x, this bug doesn't happen because "flags" was split up into "current->ptrace" and "current->flags". Exactly because of locking concerns.

Linus

#3 lore raw
In reply to Victor Zandy
Quoted 3 lines · Victor Zandy

He found that PF_USEDFPU was always set before the machine was broken. After he found that it was set about 70% of the time.

If I'm not mistaken this actully can cause GLOBAL FPU corruption. Here's why:

Assyme for a moment that we lose either the PF_USEDFPU flag of one process. This not only means that the current process won't have its state saved, it also means that the next process won't have the TS bit set. This in turn means that this new process won't get PF_USEDFPU set and suddenly we have a second process with a corrupted FPU state.

Victor: Could you try to reproduce the system wide corruption if you add an explicit call to stts(); at the very end of __switch_to? This should prevent the FPU corruption from spreading.

NOTE: This is just to prove my theory, it is not and isn't meant to be a fix for the actual problem.

regards Christian Ehrhardt

Signature · 1 line
THAT'S ALL FOLKS!
#4 lore raw
In reply to Victor Zandy
Quoted 3 lines · Christian Ehrhardt

Victor: Could you try to reproduce the system wide corruption if you add an explicit call to stts(); at the very end of __switch_to? This should prevent the FPU corruption from spreading.

After adding this call, I cannot reproduce the global corruption. There is still occasional local corruption of individual pi processes while pt is running.

Vic