Originally Posted by AndDiSa
@zeitferne @Lanchon i've merged those two commits into my kernel. I am running it since yesterday but I did not realize those performance issues yet.
The performance cost seems to be really marginal. If you want to measure it, an ideal benchmark would look something like that:
1. In one thread, do FPU operations. The speed of this thread is the benchmark's result.
2. Setup other threads that do not use the FPU (make sure to compile with -msoft-float) but which do use the CPU, so that as many context switches as possible occur for the first thread.
Without this patch, Linux would notice that the other threads did not use the FPU and therefore will skip writing the data it saved when it switched away from that thread to the FPU registers again, since it is (or should be; that's the bug) already there. With the patch, it writes the data to the registers anyway (but on the other hand, the patch saves the checking if it has to write the data).
Originally Posted by zeitferne
[...] I disabled the CONFIG_EXYNOS4_LOWPWR_IDLE configuration option. Result: The FPU corruption seems to be gone (and my phone is still able to wake up this time )
Now I have reverted to stock CM kernel and applied only this single configuration change for which there is one single #ifdef in mach-exynos/cpuidle-exynos4.c (and no references in any makefile) and the bug is still gone. If my thinking is right, this means, our bug can be summarized succinctly as:
FPU registers on CPU0 get corrupted in Low Power Idle State. EDIT3: More specifically in AFTR (sic!) mode. Googling for "Exynos 4210 AFTR" reveals interesting results. [/EDIT3]
There are quite a few branches on soc_is_exynos4210() in the related functions, which would be a good explanation why this happens only on these devices.
EDIT2: Since this Low Power Idle Mode can only be entered if only one CPU is online (see this line
) also explains why disabling hotplug gets rid of the bug.
EDIT: A file that is properly unifdefed for i9100 is here
(ca. 200 lines ~ 10% less; all remaining #if-branches are active).