Introduction
Cardwire is GPU manager for linux that uses eBPF LSM hooks to block GPUs
It was made to be a successor to the deprecated supergfxctl
Caution
Cardwire is in an early development stage, expect breaking changes and unstability.
Getting Started
Before proceeding, take a look at the requirements to make sure your system is supported.
Requirements
Requirements to be able to run Cardwire:
Kernel
Version 5.7 or later
uname -r
Built with CONFIG_BPF_LSM enabled
zcat /proc/config.gz | grep CONFIG_BPF_LSM
returns
CONFIG_BPF_LSM=yif it’s enabled
Enabled in the boot cmdline
cat /proc/cmdline
Must contains
lsm=bpf
Installation
Arch
using AUR:
yay -S cardwire
then enable the service and reboot
sudo systemctl enable cardwired.service
reboot
Note
cardwire-git is also available, this one is built from the dev branch, rather than a fixed release tag
Important
i’m also looking for an official maintainer for both AUR, since i do not use Arch.
Nix
Using the repo’s flake:
flake.nix:
cardwire = {
url = "github:opengamingcollective/cardwire";
inputs.nixpkgs.follows = "nixpkgs";
};
configuration.nix:
imports = [ inputs.cardwire.nixosModules.default ];
services.cardwire.enable = true;
Fedora
Using the offical copr:
sudo dnf copr enable luytan/cardwire
sudo dnf install cardwire
Other distros
For now, other distros must clone the repo and use make to build and install Cardwire.
Build dependencies:
- cargo
- clang
- libbpf
git clone https://github.com/OpenGamingCollective/cardwire.git
make build
sudo make install
Caution
Makefile wasn’t tested, use with caution.
Important
For mainstream distros, i will be making an official install methods, like a copr for Fedora and a .deb for Debian based.
Non-systemd distros
Warning
Cardwire only supports systemd-based distros. If you want to use it on a non-systemd distro, either open a PR with patches for non-systemd or get it working on your setup.
Troubleshooting
Name is not activable
Is the daemon running?
systemctl status cardwired.service
If it’s not running, enable the daemon with
systemctl enable cardwired.serviceand reboot your device.
dGPU is detected as the default gpu
On ROG laptop
is the asus MUX enabled?
asusctl armoury list
then find
gpu_mux_mode:
current: [(0),1]
0 means that the MUX is enabled, the dGPU IS the default GPU in this case
Non ROG Laptop
This shouldn’t happen, please create an issue with the output of
ls /sys/class/drm
and
cat /sys/class/drm/*/status
DBUS
Service
- Bus Name:
com.github.opengamingcollective.cardwire - Object Path:
/com/github/opengamingcollective/cardwire - Interface:
com.github.opengamingcollective.cardwire
Methods
SetGpuBlock
Set the block state for a specific GPU. Only available when Mode is set to Manual
The default GPU cannot be blocked
Inputs:
- gpu_id (in):
u– The GPU identifier (idfield) - block (in):
b–trueto block,falseto unblock
Outputs: None
ListDevices
List all detected GPU devices
Inputs: None
Outputs:
- (out):
a{t(ussuubbbs)}
GPU Struct (ussuubbbs) fields:
id:u– GPU identifiername:s– GPU namepci:s– PCI address (e.g.0000:01:00.0)render:u– DRM render node minor numbercard:u– DRM card node minor numberdefault:b– Whether this is the default display GPUblocked:b– Whether the GPU is currently blocked by the daemonnvidia:b– Whether the GPU is an NVIDIA devicenvidia_minor:s– NVIDIA driver minor number (empty string if not applicable)
ListDevicesPci
List all detected PCI devices
Inputs: None
Outputs:
- (out):
a{s(ssssssss)}
PCI Struct (ssssssss) fields:
pci_address:s– PCI address (e.g.0000:01:00.0)iommu_group:s– IOMMU group number (empty string if none)vendor_id:s– PCI vendor ID (empty string if unknown)device_id:s– PCI device ID (empty string if unknown)vendor_name:s– Vendor name (empty string if unknown)device_name:s– Device name (empty string if unknown)driver:s– Kernel driver in use (empty string if unknown)class:s– PCI class (empty string if unknown)
Properties
Mode
Controls the global GPU blocking mode
- Type:
u(uint32) - Access: Read/Write
- Emits:
PropertiesChangedon change
Values:
0– Integrated: Block the dGPU. Requires exactly 2 GPUs1– Hybrid: Unblock the dGPU. Requires exactly 2 GPUs2– Manual: Allow per-GPU blocking viaSetGpuBlock, applies saved GPU state ifauto_applyis enabled