Yoga Pro 9i 16IMH9 has udev spam log while charging - What is the best course of action here?

Hello everyone,

I have a rather new laptop model and am fighting with getting everything to work properly. I want to start submitting bug reports for the various hardware issues to the appropriate channels (kernel, distro, systemd, etc) so that things can gradually improve.

In this case I have traced that the issue is ALSO related to universal blue package ublue-os-udev-rules-0.8-1.fc39.noarch. I would like to present my findings here for discussion, so that I may raise a bug against ublue if appropriate.

Problem description

  • While charging (and ONLY while charging) the system log gets spammed with multiple messages per second regarding failure to access battery charge thresholds.
    • The messages stop when the laptop becomes fully charged
    • The messages also stop if the laptop is unplugged and starts discharging

The log is filled with messages like these:

Apr 27 12:45:25 myhost (udev-worker)[34230]: BAT0: Process '/bin/chmod 666 /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_control_start_threshold' failed with exit code 1.
Apr 27 12:45:25 myhost (udev-worker)[34230]: BAT0: Process '/bin/chmod 666 /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_control_end_threshold' failed with exit code 1.
Apr 27 12:45:25 myhost (udev-worker)[34230]: BAT0: Process '/bin/chmod 666 /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_start_threshold' failed with exit code 1.
Apr 27 12:45:25 myhost (udev-worker)[34230]: BAT0: Process '/bin/chmod 666 /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_stop_threshold' failed with exit code 1.

I originally mistakenly though I’d fixed it as per this thread, but it turns out that I just happened to either reboot into Fedora 40 at the moment when my battery was fully charged, or maybe I unplugged the laptop when checking. Either way this had caused the messages to stop, so I mistakenly marked that thread as solved. I am now on Bluefin-DX with Fedora 40 (since it became stable) and I can see that the problem persists.

My findings so far

After noticing udev-worker as the source of the messages, I started looking into udev and found a utility to monitor events. This revealed that it seems to be the kernel that generates these. I can see these by running the command:

❯ udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL[2223.216324] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
UDEV  [2223.238621] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
KERNEL[2223.722353] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
UDEV  [2223.744029] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
KERNEL[2224.229378] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
UDEV  [2224.250895] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
...

So it seems to me that the kernel dispatches a “uevent” repeatedly, this causes something to react and run some command, but that command fails. Looking at /lib/udev/rules.d for battery-related stuff I found:

❯ grep bat *
grep: 60-nfs.rules: Permission denied
99-thinkpad-thresholds-udev.rules:# Change the permissions of the battery threshold attributes so that they can be modified by ordinary users
99-thinkpad-thresholds-udev.rules:# See https://gitlab.com/marcosdalvarez/thinkpad-battery-threshold-extension

❯ cat 99-thinkpad-thresholds-udev.rules 
# Change the permissions of the battery threshold attributes so that they can be modified by ordinary users
# See https://gitlab.com/marcosdalvarez/thinkpad-battery-threshold-extension

ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_start_threshold"
ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_end_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_end_threshold"
ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_start_threshold"
ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_stop_threshold", RUN+="/bin/chmod 666 /sys%p/charge_stop_threshold"

❯ rpm -qf 99-thinkpad-thresholds-udev.rules 
ublue-os-udev-rules-0.8-1.fc39.noarch

For the record, the laptop is a Lenovo Yoga Pro 9i 2024 (16IMH9) which likely explains why a “thinkpad” rule triggers. It’s the same manufacturer so likely some identifier gets confused for a match?

Recap - TL/DR

  • The kernel seems to generate a uevent 3-4 times per second while charging
  • Ublue has a udev rule that tries to make some “charge threshold” files world-writeable
  • These files don’t exist so an error occurs, which causes that command to fail
  • The failure is logged, spamming the system log

Questions / help needed

  1. The ublue rule from that file, seems to need improvement. I thing I should file a bug report against ublue, to maybe have it properly check if the charge threshold files exist. There seems to be a TEST part that tried to check, but obviously the pattern fails in my case. So that needs improving.
  2. Should the files that ublue is trying to access exist? Who would create them? Is there maybe some other udev rule that fails to create these properly? Should I report this to the udev project? Or maybe it is the kernel that has some driver that fails to provide them?
  3. Why do these events fire so many times per second (I counted 8). It’s not TOO many so maybe they relate to reporting charge progress? Or is there a problem here that needs reporting to kernel developers? If so, which subsystem of the kernel would be best for this?

Hello,

I would like to edit file /usr/lib/udev/rules.d/99-thinkpad-thresholds-udev.rules to modify the “TEST” part so that it checks for both existence and then permissions:

ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_control_start_threshold", TEST{0002}!="/sys%p/charge_control_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_start_threshold"
ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_control_end_threshold", TEST{0002}!="/sys%p/charge_control_end_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_end_threshold"
ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_start_threshold", TEST{0002}!="/sys%p/charge_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_start_threshold"
ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_stop_threshold", TEST{0002}!="/sys%p/charge_stop_threshold", RUN+="/bin/chmod 666 /sys%p/charge_stop_threshold"

My hope is that the first test will fail because the file does not exist, so nothing will happen. Only if the file exists in the first place, AND has incorrect permissions would the rule fire.

Obviously due to the whole “atomic” thing, I can’t change this. What is the best way to go about this?

Thanks!

EDIT: As instructed, I have filed Improve udev rule for thinkpad charge threshold · Issue #270 · ublue-os/config · GitHub

Please file this as an issue:

I’ll leave this open so we can crosslink: tossing it in /etc/udev/rules.d should override it and let you at least see if the change works.

I have a yoga but not this specific model but going on a trip so I won’t be able to check on this for a bit but hopefully we can sort it out.

Hey, I can confirm this worked! I copied the file and edited as per my suggestion above:

root@aurelius ~ [2]# diff /usr/lib/udev/rules.d/99-thinkpad-thresholds-udev.rules /etc/udev/rules.d/99-thinkpad-thresholds-udev.rules 
4,7c4,8
< ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_start_threshold"
< ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_control_end_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_end_threshold"
< ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_start_threshold"
< ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST{0002}!="/sys%p/charge_stop_threshold", RUN+="/bin/chmod 666 /sys%p/charge_stop_threshold"
---
> ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_control_start_threshold", TEST{0002}!="/sys%p/charge_control_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_start_threshold"
> ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_control_end_threshold", TEST{0002}!="/sys%p/charge_control_end_threshold", RUN+="/bin/chmod 666 /sys%p/charge_control_end_threshold"
> ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_start_threshold", TEST{0002}!="/sys%p/charge_start_threshold", RUN+="/bin/chmod 666 /sys%p/charge_start_threshold"
> ACTION=="add|change", KERNEL=="BAT[0-1]", GROUP="wheel" , SUBSYSTEM=="power_supply", TEST=="/sys%p/charge_stop_threshold", TEST{0002}!="/sys%p/charge_stop_threshold", RUN+="/bin/chmod 666 /sys%p/charge_stop_threshold"

I can now see the events firing:

root@myhost ~# udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL[356.536545] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
UDEV  [356.548673] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
KERNEL[357.116292] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
UDEV  [357.129487] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
KERNEL[357.549330] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
UDEV  [357.558398] change   /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:16/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 (power_supply)
...

But they are ignored. Nothing shows up in the system log:

root@myhost ~# journalctl -b | grep BAT
May 04 18:47:19 fedora kernel: ACPI: battery: Slot [BAT0] (battery present)
May 04 18:47:19 fedora kernel: ACPI: battery: Slot [BAT0] (battery present)

It would be nice if someone with a supported Thinkpad could confirm that the file as shown above still works for them (i.e. triggers the command to fix the permissions when the files actually exist).

The new rule with the extra test has fixed the log spamming, as the command is no longer attempted. The kernel however is still firing events in the background (they are just being ignored).

I would like to file a bug report against the kernel, and one of the questions asks if this bug is present in “rawhide”. Is it possible to install a rawhide kernel in Bluefin?