Linux kernel module for overclocking USB devices (controllers, mice, keyboards, etc.). Equivalent of the hidusbf driver on Windows.
This allows you to change their poll rates by loading this out-of-tree module, instead of having to patch and re-compile the whole kernel.
Why even overclock USB devices at all? For input devices, to achieve lower effective input latency and higher input smoothness (so pretty much the same reason one would want a higher-Hz screen too).
Firstly find the VID:PID of your USB device with lsusb, such as 054c:0ce6.
Check the speed of your USB device with (replace with your device's VID:PID):
$ lsusb -d 054c:0ce6 -v | grep '^Negotiated speed:'
Negotiated speed: Full Speed (12Mbps)This is most of the devices. bInterval range is from 1 to 255. Note that it seems a technically-2.0 device can be operating at either of these reduced speeds and thus make use of this table.
| Value of bInterval | Polling Period | Frequency |
|---|---|---|
| 1 | 1 ms | 1000 Hz |
| 2 (to 3) | 2 ms | 500 Hz |
| 4 (to 7) | 4 ms | 250 Hz |
| 8 (to 15) | 8 ms | 125 Hz |
| 16 (to 31) | 16 ms | 62.5 Hz |
| 32 (to 63) | 32 ms | 31.25 Hz |
| 64 (to 127) | 64 ms | 15.625 Hz |
| 128 and above | 128 ms | 7.8125 Hz |
The formula seems to be Period = 2^(bInterval - 1) * 0.125. bInterval range is from 1 to 16.
| Value of bInterval | Polling Period | Frequency |
|---|---|---|
| 1 | 0.125 ms | 8000 Hz |
| 2 | 0.250 ms | 4000 Hz |
| 3 | 0.500 ms | 2000 Hz |
| 4 | 1 ms | 1000 Hz |
| 5 | 2 ms | 500 Hz |
| 6 | 4 ms | 250 Hz |
Important
This needs further research and testing. Please submit overclock results after step 4 and what bInterval values corresponded to which polling.
If in doubt, underclock the device to a bInterval value like 6 and then test the polling.
You can go to Releases section and download the latest .deb, .rpm or .pkg.tar.zst.
# curl -Lo /tmp/usb-oc-dkms.deb https://github.com/p0358/usb_oc-dkms/releases/download/v1.1/usb-oc-dkms_1.1_amd64.deb
# apt install /tmp/usb-oc-dkms.debMake sure to first install appropriate headers package for the kernel you're using! (e.g. linux-headers or linux-zen-headers or linux-lts-headers or linux-cachyos-headers or linux-cachyos-lts-headers etc.).
AUR: usb_oc-dkms or:
# curl -Lo /tmp/usb_oc-dkms.pkg.tar.zst https://github.com/p0358/usb_oc-dkms/releases/download/v1.1/usb_oc-dkms-1.1-1-any.pkg.tar.zst
# pacman -U /tmp/usb_oc-dkms.pkg.tar.zst# curl -Lo /tmp/usb_oc-dkms.rpm https://github.com/p0358/usb_oc-dkms/releases/download/v1.1/usb_oc-dkms-1.1-1.fc45.noarch.rpm
# dnf install /tmp/usb_oc-dkms.rpm# curl -Lo /tmp/usb_oc-dkms.rpm https://github.com/p0358/usb_oc-dkms/releases/download/v1.1/usb_oc-dkms-1.1-1.fc45.noarch.rpm
# zypper install --allow-unsigned-rpm /tmp/usb_oc-dkms.rpmUse this instead: https://github.com/GloriousEggroll/Linux-Pollrate-Patch
I guess you're on your own.
Load the kernel module and confirm that it's been loaded:
# modprobe usb_oc
# lsmod | grep usb_oc
usb_oc 16384 0You can change the module configuration on-the-fly without unloading the module. The changes will be applied immediately. Assuming you want, for the device with VID:PID of 054c:0ce6, to set bInterval to 1, run:
# echo -n '054c:0ce6:1' > /sys/module/usb_oc/parameters/interrupt_interval_overrideIf you want to overclock multiple devices, you'd do:
# echo -n '054c:0ce6:1,1234:5678:1' > /sys/module/usb_oc/parameters/interrupt_interval_overrideDo monitor the output of dmesg command to diagnose the module and see any warnings.
See the FAQ section for how to benchmark your device to confirm the actual overclocked rate is working. Some devices might just be impossible to overclock and will not send more data than they were designed for, when polled more frequently. Some will, for which this module is made. And some will already be set to their maximum polling rate of given USB version.
Once you're done with testing, you may unload the module with rmmod usb_oc. Reconnect any USB devices if you want to restore their bIntervals to default.
If you found a working configuration, you will probably want to persist it, so that it always overclocks your device when you boot up your computer.
Firstly, set the module to load on system startup:
# echo 'usb_oc' > /etc/modules-load.d/usb_oc.confSecondly, set the module configuration (again, assuming you want, for the device with VID:PID of 054c:0ce6, to set bInterval to 1):
# echo 'options usb_oc interrupt_interval_override=054c:0ce6:1' > /etc/modprobe.d/usb_oc.confAfter rebooting the machine, verify the module was loaded and working with:
# dmesg | grep usb_ocShare you overclock success stories at #1 and failure stories at #2!
If you have Secure Boot enabled (check with mokutil --sb-state) and you get modprobe: ERROR: could not insert 'usb_oc': Key was rejected by service when trying to modprobe, you need to enroll DKMS's MOK key to your machine in order for the module to be possible to load.
Just run:
mokutil --timeout -1
mokutil --import /var/lib/dkms/mok.pubYou'll be prompted to create a password. Enter it twice.
Reboot the computer. At boot you'll see the MOK Manager EFI interface. Press any key to enter it.
- "Enroll MOK"
- "Continue"
- "Yes"
- Enter the password you set up just now.
- Select "OK" and the computer will reboot again.
Now the module should be possible to load.
If your device is USB 1.1 ("Full Speed" 12 Mbps, or, heavens forbid, "Low Speed" 1.5 Mbps) and you overclock it too high (1000 Hz), you may run into bandwidth issues and sometimes experience some lagged input in games. At least I think that's why it happens and goes away with higher bInterval.
I did the maths and with 12 Mbps and 1000 Hz, it should be roughly ~1572 bytes per poll though, which doesn't seem that little. I don't know how chatty XInput protocol is. Perhaps it's just the particular device that can't keep up. In any case, at some point you might have diminishing results with overclocking the device too much.
This is so that the change is picked up. But be careful with this, and not only for this reason, but in general:
Warning
Unload this module if you're trying to do something "sensitive"/"risky" with the overclocked device, such as trying to flash its firmware. I am not responsible for any problems if you do dumb things, please use common sense here.
Because I couldn't figure out the kmod counterpart and didn't care enough to spend more time on it, if the DKMS one works (and then it works on more distros like openSUSE too). But if you care, then contributions are welcome to add it, including the CI workflow to build the appropriate RPM files (as far as I understand, we'd want to publish SRPM in Releases, but still would want to at least check the binary modules are indeed building from those for current kernel...).
For controllers you can use Gamepadla Polling (gamepadla-pollingAUR) and for mouse you can use evhz (evhz-gitAUR).
What do I know? A you can see in "Alternatives" section below, some means of overclocking some devices exist, and yet the patchset to overclock any device didn't seem to get accepted. And some distros outside of Nobara seem to be allergic to it for some reason too. But who cares, this module allows you to overclock your devices anyway, without care about what your distro thinks about it or recompiling the whole kernel!
The usbhid driver has options for mousepoll, but it reportedly doesn't work with USB 3 devices. The option kbpoll also exists for keyboards, but likely suffers from the same problem. It also has an option jspoll for joysticks, but it doesn't work with gamepads using other drivers like xpad.
Linux-Kernel_MiSTer has a downstream patch for xpad driver adding cpoll option. Unfortunately it is not upstreamed.
Nobara comes with this patch applied to its kernel.
Some devices have settings apps that allow changing on-device configuration used by the device's firmware and its processor. Sometimes this configuration include the poll rate that will be advertised by the device, without needing a kernel module for it (for example Solaar for select Logitech mice).
- https://gamepadla.com/
- https://www.overclock.net/threads/usb-mouse-hard-overclocking-2000-hz.1589644/
- https://docs.google.com/document/d/1cQ3pbKZm_yUtcLK9ZIXyPzVbTJkvnfxKIyvuFMwzWe0/edit
- https://support.microchip.com/s/article/What-is-bInterval (something is wrong with High Speed table though...)
- https://www.keil.com/pack/doc/mw/usb/html/_u_s_b__endpoint__descriptor.html
- http://janaxelson.com/usbfaq.htm
Some inspiration (parts of code/scripts) taken from:
- https://github.com/hannesmann/gcadapter-oc-kmod (skeleton for a simple DKMS USB overclock module)
- https://github.com/GloriousEggroll/Linux-Pollrate-Patch (kernel patchset with a configurable USB overclocking parameter)
- https://github.com/strongtz/i915-sriov-dkms (CI and Makefiles)
- https://github.com/KyleGospo/openrgb-dkms (Fedora dkms rpm spec file)
For updating, remember to update the version in:
dkms.confsrc/usb_oc.cpackaging/arch/PKGBUILDpackaging/rpm/usb_oc-dkms.spec- (in this README in the Install section in package URLs)