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).
Installation and setup
Firstly find the VID:PID of your USB device with lsusb, such as 054c:0ce6.
0. Pick your bInterval value
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)
USB 1.1 (Low Speed 1.5 Mbps, Full Speed 12 Mbps)
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 |
USB 2.0 (High Speed 480 Mbps) or higher
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.
1. Install
You can go to Releases section and download the latest .deb, .rpm or .pkg.tar.zst.
Debian/Ubuntu/Mint/Pop_OS (.deb)
# 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.deb
Arch Linux/CachyOS/EndevourOS/Manjaro (.pkg.tar.zst)
Make 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
Fedora (.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 # dnf install /tmp/usb_oc-dkms.rpm
openSUSE (.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.rpm
Nobara
Use this instead: https://github.com/GloriousEggroll/Linux-Pollrate-Patch
Yet another distro
I guess you're on your own.
2. Test it out
Load the kernel module and confirm that it's been loaded:
# modprobe usb_oc # lsmod | grep usb_oc usb_oc 16384 0
You 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.
3. Configure the module to auto-load on system startup
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:
4. Success
Share you overclock success stories at #1 and failure stories at #2!
Notes
Secure Boot
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.pub
You'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.
USB 1.1 and bandwidth limitations
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.
Little quirk: the device is reset after the bInterval descriptor change is made
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.
FAQ
Why does Fedora RPM package use DKMS instead of AKMODS?
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...).
How to benchmark the device to confirm it was overclocked?
For controllers you can use Gamepadla Polling (gamepadla-pollingAUR) and for mouse you can use evhz (evhz-gitAUR).
Why is USB overclocking not part of upstream kernel?
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!
Alternatives
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).
Useful links
- 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
Thanks to
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)
Dev notes
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)