TLP
, a power management utility for Thinkpads and other laptops, uses tpacpi-bat
script for battery calibration and setting charge thresholds (for Thinkpads xx20 and later), which in turn uses acpi_call
Linux kernel module that enables calls to ACPI
methods through /proc/acpi/call
. acpi_call
can also be used for hybrid graphics switching and other power management tasks.
As explained here and here, a kernel upstream commit made seek support for procfs
mandatory. Not providing it will cause a null pointer exception for kernels >=5.13.0, including Ubuntu 21.10.
Consequently, pre-1.2.2 versions of acpi_call
became incompatible, and calling into them leads to a null pointer dereference.
- kernel oops
- errors and system freezes when using
TLP
- in case of Thinkpads, EFI variable storage in NVRAM is flooded with kernel dumps every boot
- as a result, boot
Error: The Non-Volatile Variable Storage is About Full
- if ignored, it can lead to an unbootable system due to NVRAM getting filled up
If you run Ubuntu 21.10 and have acpi-call-dkms
installed, you can check if this bug affects you with this command:
sudo dmesg | grep "BUG: kernel NULL pointer dereference" -A 10
If it does, you'll see something like this among the lines:
[45420.141212] BUG: kernel NULL pointer dereference, address: 0000000000000000
[45420.141217] #PF: supervisor instruction fetch in kernel mode
[45420.141220] #PF: error_code(0x0010) - not-present page
[45420.141221] PGD 0 P4D 0
[45420.141224] Oops: 0010 [#4] SMP NOPTI
[45420.141226] CPU: 3 PID: 85578 Comm: tpacpi-bat Tainted: G D O 5.13.0-19-generic #1
...
Thankfully, acpi_call
has already been fixed in v1.2.2. Unfortunately, many repositories still ship an outdated version, not mentioning the need for backports. So, if you happen to have this combo of a Thinkpad xx20 or later, a Linux kernel >=5.13, an acpi_call
<1.2.2, and TLP
or some other software utilizing it, you'll have to manually download, compile and install a fresh version of acpi_call
.
But first, if there was a Non-Volatile Variable Storage is About Full
boot error, you'll need to clean up NVRAM, as described here. In our case, this error is caused by kernel dumps filling up the storage. Make sure you have the same error, by comparing your dmesg
output with the one above, check TLP
battery FAQ, and UEFI troubleshooting on ArchWiki.
Commands below are for Debian/dpkg
-based distributions, including Ubuntu and its derivatives. If needed, replace with appropriate commands for your distro.
# Check if there are any dumps
sudo ls /sys/firmware/efi/efivars/dump-*
# If found, delete them
sudo rm /sys/firmware/efi/efivars/dump-*
Now on to installing the kernel module.
# Remove previously installed acpi-call-dkms package (if any)
sudo apt purge acpi-call-dkms
# Install git (if you don’t have it installed yet)
sudo apt install git
# Clone the repository at nix-community/acpi_call
git clone --branch v1.2.2 https://github.com/nix-community/acpi_call.git
# Navigate to the cloned repository
cd acpi_call
# Prepare dkms.conf file
make dkms.conf
# Copy the module source to the shared sources directory
sudo cp -R . /usr/src/acpi-call-1.2.2
# Add the module to the dkms tree for build
sudo dkms add -m acpi-call -v 1.2.2
# Build the module
sudo dkms build -m acpi-call -v 1.2.2
# Install the module
sudo dkms install -m acpi-call -v 1.2.2
# Reboot
sudo reboot
Finally, take a moment and notify the maintainers of the package for your distro about the bug and the updated version. For example, here is the bug report for Debian acpi-call-dkms
package, and here is for Ubuntu.
EDIT: the proper way of installing the module is taken from here, kudos to @monosoul.
This appears to solve the "tpacpi-bat (acpi_call)" kernel error in TLP...
Your efforts are much appreciated !