Kernel thread (kworker) eats 100% of my CPU or my Mac is running super hot while doing nothing

This problem usually happens in MacBook (or MacBook Pro), although it can happen on other machines too.

"kworker" is a placeholder process for kernel worker threads, which perform most of the actual processing for the kernel, especially in cases where there are interrupts, timers, I/O, etc. These typically correspond to the vast majority of any allocated "system" time to running processes. It is not something that can be safely removed from the system in any way. They usually get busy when there are requests from programs to access disks, send network packets, etc.

Sometimes, something can go wrong that the CPU gets interrupted very often (a few hundred or thousands per second). When this happens, kworker gets very busy, the kernel gets very busy, CPU is occupied, and the machine gets hot. All for doing nothing.

When this happens, the solution is to upgrade the kernel in the hope that this particular problem is fixed, or do some workaround to disable the offending interrupt. As far as "upgrade the kernel goes", this as happened since kernel 3.10 onwards and at the time of writing, kernel 4.14 (which is 3.34 if Linus didn't rename 3.20 as 4.0) - the problem still  happens.

Fatdog has a built-in script do to this. The script examines the interrupts issued by ACPI, and if the number of interrupts exceeded a given threshold in a given detection time, it will disable it. The name of the script is disable-spurious-gpe.

This script can also be started at boot. Fatdog has the system service configured for this, but it is disabled by default. All you need to do is enable the service from Fatdog Control Panel. If need be, it can be customised too. The init script is called /etc/init.d/99-disable-spurious-gpe.

Please note that ACPI interrupts are there for a reason. If you disable the ACPI interrupts, some functions may stop working. In the case of MacBook, gpe06 and gpe07 are the two known problem case and they don't seem to affect much. On other machines, those interrupts may provide hooks to generate special ACPI event keys (e.g. Fn-F1, Fn-F2, etc); and by disabling that you disable the ability to detect those key combinations as well.

PS: If you run the script and some interrupts gets disabled, you can re-enable them again by giving this command:

echo enable > /sys/firmware/acpi/interrupts/gpeXX

where XX is the interrupt number you want to enable. If you want to disable it instead, use echo disable instead of echo enable.


References:
  1. https://unix.stackexchange.com/questions/242013/disable-gpe-acpi-interrupts-on-boot#254880
  2. https://bugzilla.redhat.com/show_bug.cgi?id=1192856