Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corsair Commander Pro occasional unexpected OS error #698

Open
RayJW opened this issue Apr 22, 2024 · 28 comments
Open

Corsair Commander Pro occasional unexpected OS error #698

RayJW opened this issue Apr 22, 2024 · 28 comments
Labels
bug Apparent bug in liquidctl

Comments

@RayJW
Copy link

RayJW commented Apr 22, 2024

Describe the bug

When constantly monitoring the status of the Corsair Commander Pro, liquidctl produces an error saying “ERROR: Corsair Commander Pro: unexpected OS error: OSError(95, 'Operation not supported')”, I stumbled upon the issue because I use CoolerControl which constantly monitors the devices thus regularly logging errors due to this liquidctl error (issue). It is possible that this might be an issue with hwmon driver, but I thought reporting this issue level by level before reaching the kernel makes sense, in case anything else is causing this issue.

Commands executed

watch -e -n1 liquidctl status -n 0

Output of all relevant commands with --debug flag

❯ liquidctl status -n 0 --debug
[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (__init__): has kernel driver: corsair-cpro (/sys/class/hidraw/hidraw1/device/hwmon/hwmon3)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc1
[INFO] (commander_pro) (get_status): bound to corsair-cpro kernel driver, reading status from hwmon
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (hwmon) (get_string): read in0_input: 11955
[DEBUG] (hwmon) (get_string): read in1_input: 4950
[DEBUG] (hwmon) (get_string): read in2_input: 3337
Corsair Commander Pro
├── +12V rail     11.96  V
├── +5V rail       4.95  V
└── +3.3V rail     3.34  V

Affected device

Corsair Commander Pro

Does your version of liquidctl support the device in question?

Yes, my version supports it

Operating system and version

Pop!_OS 22.04

Installation method

I upgraded the Ubuntu repo version with sudo pip install liquidctl --upgrade to ensure it's not an issue with the outdated version.

Version of liquidctl

liquidctl v1.13.0 (Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35)

@RayJW RayJW added the bug Apparent bug in liquidctl label Apr 22, 2024
@jonasmalacofilho
Copy link
Member

jonasmalacofilho commented Apr 23, 2024

Can you add the output immediately preceding (i.e. current and previous two liquidctl executions) an error from watch -e -n1 liquidctl status -n 0 --debug?

@aleksamagicka
Copy link
Member

aleksamagicka commented Apr 23, 2024

From the linked gitlab issue, looks like the kernel driver returns an -EOPNOTSUPP when reading fanX_input. It does that when the device thinks the command is invalid. At a glance, looks like liquidctl and the hwmon driver are sending the same things...

What is listed under the hwmon dir (/sys/class/hwmon/hwmonX, where hwmonX is the driver) and how many fans have you got connected?

(This seems to be the upstream repo.)

@RayJW
Copy link
Author

RayJW commented Apr 23, 2024

Can you add the output immediately preceding (i.e. current and previous two liquidctl executions) an error from watch -e -n1 liquidctl status -n 0 --debug?

[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (__init__): has kernel driver: corsair-cpro (/sys/class/hidraw/hidraw1/device/hwmon/hwmon4)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc1
[INFO] (commander_pro) (get_status): bound to corsair-cpro kernel driver, reading status from hwmon
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (hwmon) (get_string): read in0_input: 11949
[DEBUG] (hwmon) (get_string): read in1_input: 4932
[DEBUG] (hwmon) (get_string): read in2_input: 3332
Corsair Commander Pro
├── +12V rail     11.95  V
├── +5V rail       4.93  V
└── +3.3V rail     3.33  V

[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (__init__): has kernel driver: corsair-cpro (/sys/class/hidraw/hidraw1/device/hwmon/hwmon4)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc1
[INFO] (commander_pro) (get_status): bound to corsair-cpro kernel driver, reading status from hwmon
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (hwmon) (get_string): read in0_input: 11946
[DEBUG] (hwmon) (get_string): read in1_input: 4932
[DEBUG] (hwmon) (get_string): read in2_input: 3331
Corsair Commander Pro
├── +12V rail     11.95  V
├── +5V rail       4.93  V
└── +3.3V rail     3.33  V

[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (__init__): has kernel driver: corsair-cpro (/sys/class/hidraw/hidraw1/device/hwmon/hwmon4)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc1
[INFO] (commander_pro) (get_status): bound to corsair-cpro kernel driver, reading status from hwmon
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[INFO] (cli) (log): detailed error: Corsair Commander Pro: unexpected OS error: OSError(95, 'Operation not supported')
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/liquidctl/cli.py", line 469, in main
    status = dev.get_status(**opts)
  File "/usr/local/lib/python3.10/dist-packages/liquidctl/driver/commander_pro.py", line 343, in get_status
    return self._get_status_from_hwmon()
  File "/usr/local/lib/python3.10/dist-packages/liquidctl/driver/commander_pro.py", line 326, in _get_status_from_hwmon
    voltage = self._hwmon.read_int(f'in{i}_input') * 1e-3
  File "/usr/local/lib/python3.10/dist-packages/liquidctl/driver/hwmon.py", line 42, in read_int
    return int(self.get_string(name))
  File "/usr/local/lib/python3.10/dist-packages/liquidctl/driver/hwmon.py", line 37, in get_string
    value = (self.path / name).read_text().rstrip()
  File "/usr/lib/python3.10/pathlib.py", line 1135, in read_text
    return f.read()
OSError: [Errno 95] Operation not supported
[ERROR] (cli) (log): Corsair Commander Pro: unexpected OS error: OSError(95, 'Operation not supported')

From the linked gitlab issue, looks like the kernel driver returns an -EOPNOTSUPP when reading fanX_input. It does that when the device thinks the command is invalid. At a glance, looks like liquidctl and the hwmon driver are sending the same things...

What is listed under the hwmon dir (/sys/class/hwmon/hwmonX, where hwmonX is the driver) and how many fans have you got connected?

(This seems to be the upstream repo.)

❯ ll /sys/class/hwmon/hwmon4/
Permissions Size User Date Modified Name
lrwxrwxrwx     - root 23 Apr 10:13   device -> ../../../0003:1B1C:0C10.0002
.r--r--r--  4.1k root 23 Apr 10:13   fan1_input
.r--r--r--  4.1k root 23 Apr 10:13   fan1_label
.rw-r--r--  4.1k root 23 Apr 10:13   fan1_target
.r--r--r--  4.1k root 23 Apr 10:13   fan2_input
.r--r--r--  4.1k root 23 Apr 10:13   fan2_label
.rw-r--r--  4.1k root 23 Apr 10:13   fan2_target
.r--r--r--  4.1k root 23 Apr 10:13   fan3_input
.r--r--r--  4.1k root 23 Apr 10:13   fan3_label
.rw-r--r--  4.1k root 23 Apr 10:13   fan3_target
.r--r--r--  4.1k root 23 Apr 10:13   fan4_input
.r--r--r--  4.1k root 23 Apr 10:13   fan4_label
.rw-r--r--  4.1k root 23 Apr 10:13   fan4_target
.r--r--r--  4.1k root 23 Apr 10:13   fan5_input
.r--r--r--  4.1k root 23 Apr 10:13   fan5_label
.rw-r--r--  4.1k root 23 Apr 10:13   fan5_target
.r--r--r--  4.1k root 23 Apr 10:13   in0_input
.r--r--r--  4.1k root 23 Apr 10:13   in1_input
.r--r--r--  4.1k root 23 Apr 10:13   in2_input
.r--r--r--  4.1k root 23 Apr 10:13   name
drwxr-xr-x     - root 23 Apr 10:13   power
.rw-r--r--  4.1k root 23 Apr 10:13   pwm1
.rw-r--r--  4.1k root 23 Apr 10:13   pwm2
.rw-r--r--  4.1k root 23 Apr 10:13   pwm3
.rw-r--r--  4.1k root 23 Apr 10:13   pwm4
.rw-r--r--  4.1k root 23 Apr 10:13   pwm5
lrwxrwxrwx     - root 23 Apr 10:13   subsystem -> ../../../../../../../../../../../../class/hwmon
.rw-r--r--  4.1k root 23 Apr 10:13   uevent

As is also reflected in the directory, currently there are 5 out of 6 possible fans connected and 1 out of 2 possble LED controllers.

@aleksamagicka
Copy link
Member

aleksamagicka commented Apr 23, 2024

voltage = self._hwmon.read_int(f'in{i}_input') * 1e-3

Fails with voltage this time. Looks like the device is getting confused for some reason, or the kernel driver is not sending something correctly? Perhaps the requests need to be spaced out a bit?

Does it fail if you try with --direct-access multiple times in a row?

@jonasmalacofilho
Copy link
Member

Does it fail if you try with --direct-access multiple times in a row?

It might be wise to manually unload the kernel driver instead of trying --direct-access in succession. Otherwise each liquidctl invocation will cause the kernel driver to be unloaded and reloaded in quick succession, and that may confuse the device.

@RayJW
Copy link
Author

RayJW commented Apr 23, 2024

So, as advised, I unloaded the driver with sudo modprobe -r corsair_cpro and then repeated the same procedure. So far there hasn't been an error in ~40 minutes, which seems promising when considering that it used to error every few minutes.
I'll let it running for some more time and check occasionally if the issue occurs again. But I think in the meantime it seems like it might be worth filing with the kernel driver module then, right?
Is there any disadvantage to using the liquidctl driver for now, since that one has been discontinued AFAIK?

@jonasmalacofilho
Copy link
Member

jonasmalacofilho commented Apr 23, 2024

Have you noticed any unreasonable values being reported now? We don't check the specific (supposed) error flag that the kernel driver checks, so we might just be reporting garbage. On the other hand, it's also possible that the kernel driver check was resulting in false positives, and that the actual data was fine.


Is there any disadvantage to using the liquidctl driver for now, since that one has been discontinued AFAIK?

The direct access code paths in liquidctl have not been deprecated. Their use is discouraged when a hwmon driver is available, but not every system runs Linux and has the corresponding hwmon driver loaded.

When a hwmon driver is available, there are generally a few advantages to using it:

  • it allows other tools to work, since it's a standard Linux userspace interface;
  • it should completely prevent unsafe/unpredictable races in accessing the device (liquidctl should do a lot better than it currently does in this regard, but even then it will always limited to prevent races from cooperating processes);1
  • it may be more efficient since, unlike invocations of the liquidctl CLI, the kernel driver maintains state.

The liquidctl direct access code path, on the other hand, generally supports more features.

Footnotes

  1. The kernel driver can prevent all unwanted races as long as no process unloads it or bypasses it through hidraw. And regarding the latter, the kernel driver could very well not expose the hidraw interface... it only currently does it to let userspace implement stuff like RGB.

@RayJW
Copy link
Author

RayJW commented Apr 23, 2024

Have you noticed any unreasonable values being reported now? We don't check the specific (supposed) error flag that the kernel driver checks, so we might just be reporting garbage. On the other hand, it's also possible that the kernel driver check was resulting in false positives, and that the actual data was fine.

Now that you mention it, there actually are unreasonable values. I didn't check what was actually being reported, just if it errors out. And looking at the RPM graph, there is definitely something off.

image

The purplish lines are all the fans connected to the Commander Pro and as you can see the RPM seems way off because the fans are obviously not spinning at 10'000 RPM for one singular second before returning (unless they actually intend to, but don't have enough time to ramp). The same goes for dipping down to 0 before going back up.

Edit: It seems like the RPM spikes have actually stopped as soon as I terminated the watch command. Maybe they were caused by multiple applications trying to access the data? However, I restarted the command again and now it doesn't seem to be happening anymore? It's quite confusing for me at the moment.

Also when looking at the voltage more closely I see a few outliers that might hint at issues, here are a few select ones:

[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc11
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:2e:aa:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:2e:aa:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 1 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:13:53:00:00:00:00:00:00:00:00:00:00:00:00:00
Corsair Commander Pro
├── +12V rail     11.95  V
├── +5V rail      11.95  V
└── +3.3V rail     4.95  V

[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc11
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:03:0f:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:2e:aa:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 1 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:13:4d:00:00:00:00:00:00:00:00:00:00:00:00:00
Corsair Commander Pro
├── +12V rail      0.78  V
├── +5V rail      11.95  V
└── +3.3V rail     4.94  V
[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc11
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:2e:b3:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:13:44:00:00:00:00:00:00:00:00:00:00:00:00:00
Corsair Commander Pro
├── +12V rail      0.00  V
├── +5V rail      11.96  V
└── +3.3V rail     4.93  V

[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc11
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:2e:9b:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:13:41:00:00:00:00:00:00:00:00:00:00:00:00:00
Corsair Commander Pro
├── +12V rail      0.00  V
├── +5V rail      11.93  V
└── +3.3V rail     4.93  V
[DEBUG] (cli) (_log_env_infos): script: /usr/local/bin/liquidctl
[DEBUG] (cli) (_log_env_infos): version: 1.13.0
[DEBUG] (cli) (_log_env_infos): platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
[DEBUG] (cli) (_log_env_infos): python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
[DEBUG] (cli) (_log_env_infos): encoding: UTF-8 current, UTF-8 preferred, utf8_mode 0
[DEBUG] (cli) (_log_env_infos): with colorlog: 6.6.0
[DEBUG] (cli) (_log_env_infos): with crcmod: 1.7
[DEBUG] (cli) (_log_env_infos): with docopt: 0.6.2
[DEBUG] (cli) (_log_env_infos): with hidapi: 0.9.0.post3
[DEBUG] (cli) (_log_env_infos): with pyusb: 1.2.1.post1
[DEBUG] (cli) (_log_env_infos): with pillow: 9.0.1
[DEBUG] (cli) (_log_env_infos): with smbus: 1.1.post2
[DEBUG] (cli) (_log_env_infos): with winusbcdc: version n/a (No package metadata was found for winusbcdc)
[DEBUG] (cli) (_log_env_infos): with libusb-package: version n/a (No package metadata was found for libusb-package)
[DEBUG] (smbus) (find_devices): searching LinuxI2c
[DEBUG] (smbus) (find_devices): LinuxI2c drivers: Ddr4Temperature, EvgaPascal, RogTuring, VengeanceRgb
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-3
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-1
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-8
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-6
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-4
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-2
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-0
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-9
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-7
[DEBUG] (smbus) (find_devices): I²C adapter: i2c-5
[DEBUG] (usb) (find_devices): searching HidapiBus
[DEBUG] (usb) (find_devices): HidapiBus drivers: Aquacomputer, AuraLed, CommanderCore, CommanderPro, CorsairHidPsu, H1V2, HydroPlatinum, Kraken2, KrakenX3, KrakenZ3, NzxtEPsu, RgbFusion2, SmartDevice, SmartDevice2, _BaseSmartDevice
[DEBUG] (usb) (find_devices): HID device: 1b1c:0c10 (usage_page=0x0084 usage=0x0052)
[DEBUG] (usb) (probe): CommanderPro identified: Corsair Commander Pro
[DEBUG] (cli) (main): device: Corsair Commander Pro
[DEBUG] (keyval) (__init__): data in /run/user/1000/liquidctl/vid1b1c_pid0c10/loc11
[DEBUG] (keyval) (load): no data (file) found for temp_sensors_connected
[DEBUG] (keyval) (load): no data (file) found for fan_modes
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:2e:aa:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (clear_enqueued_reports): discarded 0 previously enqueued reports
[DEBUG] (usb) (write): writing report 0x00 with 64 bytes: 12:02:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
[DEBUG] (usb) (read): read 16 bytes: 00:13:5c:00:00:00:00:00:00:00:00:00:00:00:00:00
Corsair Commander Pro
├── +12V rail      0.00  V
├── +5V rail      11.95  V
└── +3.3V rail     4.96  V

Now I'm not familiar with the actual electronics, but it seems a bit unlikely to me that these voltages are actually correct. That would either cause the device to crash or take damage over time. But it kinda looks like the values for the rails might be getting mixed up from time to time as it seems like the values are shifted by one? Not sure, just throwing around ideas here.

@jonasmalacofilho
Copy link
Member

Edit: It seems like the RPM spikes have actually stopped as soon as I terminated the watch command. Maybe they were caused by multiple applications trying to access the data? However, I restarted the command again and now it doesn't seem to be happening anymore? It's quite confusing for me at the moment.

Yes, that makes a lot of sense, especially if any one of those applications/processes is using hidraw (i.e. direct access). These applications don't synchronize (like I said, liquidctl could to a lot better and at least synchronize across liquidctl instances, but other applications certainly wouldn't synchronize with liquidctl), and trample over each other when talking with the device, especially given how this specific protocol works.

That said, similar race issues (either errors or unreasonable values as a result of those races) when only using hwmon would mean a bug in that driver. But given the protocol and a cursory glance at the driver's source code, I think that's unlikely.

Any chance there was a non-hwmon process talking to the device all this time, even when your watch command was using hwmon?

@RayJW
Copy link
Author

RayJW commented Apr 23, 2024

Any chance there was a non-hwmon process talking to the device all this time, even when your watch command was using hwmon?

So after restarting and fully disabling CoolerControl to rule out any conflicts, I wasn't able to reproduce the error in three hours. From my understanding regarding the different discussions, this probably means, that it actually might be a CoolerControl issue since it seems to cause race issues trying to access the data.

At least for me, that seems to be the only logical conclusion, since turning the CoolerControl service back on after three hours of watch -e -n1 "(liquidctl status -n 0 --debug)" the coolercontrol-liqctld.service immediately starts reporting the same errors again in a somewhat regular interval. The chance that CoolerControl is running into race issues with some other application in a matter of minutes while just running liquidctl status every second for three hours didn't have that problem, seems incredibly low to me.

@jonasmalacofilho
Copy link
Member

I'm not sure it's that simple: when you first reported the issue, both Cooler Control and the watch command were both using the hwmon driver, and races are not supposed to be a problem when using it.

I think the more likely scenarios are:

  • the device has issues with receiving too many commands in too close succession (and perhaps some specific attributes are harder to read than others);
  • a subtle bug in the kernel driver that results in commands being sent to the device in some invalid or corrupted way (I'll take a look at this).

If either is confirmed to be the case here, then the fix should be done in the kernel driver.

@jonasmalacofilho
Copy link
Member

On your part, it would help to confirm the issue just using the kernel driver, that is, without the involvement of liquidctl, coolercontrol, or any other program of the sort.

I would start by spamming reads of all hwmon attributes from the device in quick succession and/or from racing threads.

@jonasmalacofilho
Copy link
Member

jonasmalacofilho commented Apr 24, 2024

I think I may have found an issue with the kernel driver:

  • (a) the driver uses a single buffer for both input and output;
  • (b) ccp_raw_event overwrites the buffer if there's a completion pending;
  • (c) send_usb_cmd actually reinits the completion (and therefore unlocks ccp_raw_event) before submitting the report.

With just (b) alone this means that any unexpected/spurious report from the device will, during a brief window, take the place of the actual report the driver is waiting for.

But because of (a) and (c), it's also possible for a spurious input report to change what command will be sent to the device next, possibly explaining why the device seems to report some invalid commands. And this would happen as part of a data race with hidcore/usbhid (so it might not just replace the command, but instead change it in rather hard to predict ways).

@aleksamagicka, do you think this makes sense?

@aleksamagicka
Copy link
Member

With just (b) alone this means that any unexpected/spurious report from the device will, during a brief window, take the place of the actual report the driver is waiting for.

Yes...

But because of (a) and (c), it's also possible for a spurious input report to change what command will be sent to the device next, possibly explaining why the device seems to report some invalid commands.

... also yes, in case something arrives between reinit_completion() and hid_hw_output_report().

Also, if I see correctly, just doing a complete() each time will lead to the completion being marked as done multiple times from all incoming reports, which maybe came before the driver issued any commands on its own - meaning that that many waits will just go through. (Similar issue as gigabyte_wateforce had, for example.)

The driver seems to be written without hidraw in mind. Unfortunately, the command outputs don't seem to return what the command was AFAICS, so parsing them in ccp_raw_event() doesn't seem possible.

And it even says so in the header:

When using hidraw and this driver simultaniously, reports could be switched.

@RayJW
Copy link
Author

RayJW commented Apr 24, 2024

On your part, it would help to confirm the issue just using the kernel driver, that is, without the involvement of liquidctl, coolercontrol, or any other program of the sort.

I'm glad to help diagnose. Could you perhaps lead me how to do that effectively? I have never touched the hwmon drivers directly, so I have no idea what would count as an effective spam in terms of their capabilities.

@jonasmalacofilho
Copy link
Member

jonasmalacofilho commented Apr 24, 2024

@aleksamagicka,

I'll report what we found to the upstream repo you found.


When using hidraw and this driver simultaniously, reports could be switched.

Yes, but it seems that reports can be switched and commands corrupted even just through hwmon (as in the setup the user originally reported, where both coolercontrol and liquidctl were using hwmon).

@aleksamagicka
Copy link
Member

Yes, but it seems that reports can be switched and commands corrupted even just through hwmon (as in the setup the user originally reported, where both coolercontrol and liquidctl were using hwmon).

Yes, that's just what I'm pondering right now after reading through the thread again... get_data() locks the mutex always, I'm probably overseeing something.

@jonasmalacofilho
Copy link
Member

Yes, that's just what I'm pondering right now after reading through the thread again... get_data() locks the mutex always, I'm probably overseeing something.

It does lock it, but that doesn't prevent the device from sending a report anyway (for some reason) and hid-core from processing it and calling the ccp_raw_event callback.

That said, whether the device can ever send a spurious report without some interference from hidraw is an open question. But, given the little information we (and, probably, Marcus too) have about the device, it might not be wise to assume it can't ever do that... even if it may appear to be rare.

@aleksamagicka
Copy link
Member

It does lock it, but that doesn't prevent the device from sending a report anyway (for some reason) and hid-core from processing it and calling the ccp_raw_event callback.

True, but if it wants to act possessed without giving info as to why, probably not much we can do 😆

I'd still rather make ccp_raw_event() similar to this:

static int ccp_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
{
	struct ccp_device *ccp = hid_get_drvdata(hdev);

	/* only copy buffer when requested */
	if (!completion_done(&ccp->wait_input_report)) {
		memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
		complete_all(&ccp->wait_input_report);
	}

	return 0;
}

... possibly with a spinlock around, so that it only parses once after a reinit (as to what it's parsing - well...). Would be much easier if only the protocol repeated back the command ID.

@jonasmalacofilho
Copy link
Member

@RayJW,

It might be enough to run a few simultaneous loops of:

grep "" /sys/class/hwmon/hwmonX/*_input

Where hwmonX points to the correct hwmon node for the device.
(One way to figure that is by listing all hwmon names with grep "" /sys/class/hwmon/*/name).

If we're on the right track, these simultaneous loops should stress the driver as much (or more) than liquidctl + cooler control were doing before.

Regarding which loop to use, I'm not sure what will be best approach to reproduce the issue we're looking for. You can start with many instances of watch -n1 or similar. If you can't get it to error out (or produce unreasonable results), then maybe try a simple while loop with no sleeps.

And make sure to have no liquidctl and cooler control instances running while running these tests.


If you can't reproduce the issue with just grep loops, then maybe also try to see if two or more watch -n1 liquidctl [filter] status instances are a better way to reveal the problem.

@jonasmalacofilho
Copy link
Member

jonasmalacofilho commented Apr 24, 2024

True, but if it wants to act possessed without giving info as to why, probably not much we can do 😆

Indeed, the protocol doesn't give us much choice. But perhaps synchronizing with get_data or using different buffers, making sure a spurious read can't corrupt the next write, would be an improvement.

Also, if I see correctly, just doing a complete() each time will lead to the completion being marked as done multiple times from all incoming reports, which maybe came before the driver issued any commands on its own - meaning that that many waits will just go through. (Similar issue as gigabyte_wateforce had, for example.)

I'd still rather make ccp_raw_event() similar to this: [...]

I think this is also an improvement.

possibly with a spinlock around, [...]

Hm, related to this, I forget what was the conclusion (only that the docs had some issue)... is reinit_completion safe from races with complete, or is a lock required if such races are possible?

@aleksamagicka
Copy link
Member

But perhaps using different buffers to make sure a spurious read doesn't corrupt the next write would be an improvement.

Agreed.

Hm, related to this, I forget what was the conclusion (only that the docs had some issue)... is reinit_completion safe from races with complete, or is a lock required if such races are possible?

From the docs:

The re-initialization function, reinit_completion(), simply resets the
->done field to 0 ("not done"), without touching the waitqueue.
Callers of this function must make sure that there are no racy
wait_for_completion() calls going on in parallel.
...
There can only be one thread calling complete() or complete_all() on a
particular 'struct completion' at any time - serialized through the wait
queue spinlock. Any such concurrent calls to complete() or complete_all()
probably are a design bug.

IMO the first part applies to completing as well, since those functions also touch ->done. With hidraw, a spinlock + complete_all() from above should be added to both places, as it's the same situation as here (and if the device likes to send its own reports with no IDs, that's as unpredictable as hidraw).

@RayJW
Copy link
Author

RayJW commented Apr 24, 2024

@RayJW,

It might be enough to run a few simultaneous loops of:

grep "" /sys/class/hwmon/hwmonX/*_input

Where hwmonX points to the correct hwmon node for the device. (One way to figure that is by listing all hwmon names with grep "" /sys/class/hwmon/*/name).

If we're on the right track, these simultaneous loops should stress the driver as much (or more) than liquidctl + cooler control were doing before.

Regarding which loop to use, I'm not sure what will be best approach to reproduce the issue we're looking for. You can start with many instances of watch -n1 or similar. If you can't get it to error out (or produce unreasonable results), then maybe try a simple while loop with no sleeps.

And make sure to have no liquidctl and cooler control instances running while running these tests.

If you can't reproduce the issue with just grep loops, then maybe also try to see if two or more watch -n1 liquidctl [filter] status instances are a better way to reveal the problem.

I followed your instruction and let ten instances of this bash script run for 20 minutes, however no errors so far.

#!/bin/bash

set -e;

while true;
  do grep "" /sys/class/hwmon/hwmon3/*_input;
  done;

I then added ten instances of watch -e -n1 "(liquidctl -n 0 status)" on top but still no errors in another ~45 minutes of this plus the grep loops.

However, as soon as I started the coolercontrold.service again, in a matter of seconds 19 out of 20 shell instances threw the “Operation not supported” error while the last instance of the watch command staid alive for another few minutes.
Did I do something wrong or is this something we expected?

Also, there is another thing I remembered, CoolerControl does also have the ability to control the RGB. Since the hwmon driver does not support the RGB control, is it possible that there is a weird interaction where sending an RGB signal needs to use the liquidctl implementation while the fan speed related things use the hwmon driver?

I tried confirming this theory by running instances of watch -e -n1 "(liquidctl -n 0 status)" and watch -e -n1 "(liquidctl -n 0 status --direct-access)" in parallel and sure enough, I see some hwmon instances throwing errors and some direct access instances reporting messed up voltages.

@aleksamagicka
Copy link
Member

aleksamagicka commented Apr 24, 2024

I then added ten instances of watch -e -n1 "(liquidctl -n 0 status)" on top but still no errors in another ~45 minutes of this plus the grep loops.

That sounds good...? If the device were sending something on its own it probably would have errored at some point if I'm not missing something.

However, as soon as I started the coolercontrold.service again, in a matter of seconds 19 out of 20 shell instances threw the “Operation not supported” error while the last instance of the watch command staid alive for another few minutes.
Did I do something wrong or is this something we expected?

I don't know what it does exactly, but perhaps it ran initialize and reset something?

Since the hwmon driver does not support the RGB control, is it possible that there is a weird interaction where sending an RGB signal needs to use the liquidctl implementation while the fan speed-related things use the hwmon driver?

Yes, that's how it works generally. Use hwmon if/where possible, fall back to direct access otherwise. The point being that devices are usually specific about what they are communicating, unlike this one.

So, what can at least be improved in the driver:

  • separate buffer for receving raw event
  • proper locking and complete_all()

@MisterZ42
Copy link

Hello, developer of corsair-cpro driver here,
answering here instead of MisterZ42/corsair-cpro#7

In the driver, every access to buffer and the completion is enveloped in a mutex. There should be no races, when accessing only the hwmon attributes. (please correct me, if I am wrong)

But there can be races when using hidraw. All RGB software is using this (since there is no kernel support for RGB yet)
The firmware also does not use report-ids. So there is no possibility to know, whether the report was requested by the driver or by hidraw.
I am not sure, what the best solution would be. Disabling hidraw in the driver would be a possibility, but many users would have problems. (e. g. liquidctl does not recognize the device, when I test it with hidraw disabled, openrgb would have problems)

@aleksamagicka
Copy link
Member

In the driver, every access to buffer and the completion is enveloped in a mutex. There should be no races, when accessing only the hwmon attributes. (please correct me, if I am wrong)

Except in ccp_raw_event(), which hidraw can trigger at anytime.

The firmware also does not use report-ids. So there is no possibility to know, whether the report was requested by the driver or by hidraw.

That's true, but I think we can reduce the possibility as much as possible. I've made a branch at my fork for the improvements I've noted earlier, and I'll announce when I have something to show.

Disabling hidraw in the driver would be a possibility, but many users would have problems. (e. g. liquidctl does not recognize the device, when I test it with hidraw disabled, openrgb would have problems)

Indeed, disabling hidraw would net no good, and we'd just get issue reports.

@aleksamagicka
Copy link
Member

Opened a PR upstream, please take a look.

@aleksamagicka
Copy link
Member

The commits from the PR I linked above have just been merged by Guenter upstream. I marked them with Fixes: so they should be propagated to earlier kernel versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Apparent bug in liquidctl
Projects
None yet
Development

No branches or pull requests

4 participants