Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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=y if 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.service and 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 (id field)
  • block (in): btrue to block, false to unblock

Outputs: None

ListDevices

List all detected GPU devices

Inputs: None

Outputs:

  • (out): a{t(ussuubbbs)}

GPU Struct (ussuubbbs) fields:

  • id: u – GPU identifier
  • name: s – GPU name
  • pci: s – PCI address (e.g. 0000:01:00.0)
  • render: u – DRM render node minor number
  • card: u – DRM card node minor number
  • default: b – Whether this is the default display GPU
  • blocked: b – Whether the GPU is currently blocked by the daemon
  • nvidia: b – Whether the GPU is an NVIDIA device
  • nvidia_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: PropertiesChanged on change

Values:

  • 0 – Integrated: Block the dGPU. Requires exactly 2 GPUs
  • 1 – Hybrid: Unblock the dGPU. Requires exactly 2 GPUs
  • 2 – Manual: Allow per-GPU blocking via SetGpuBlock, applies saved GPU state if auto_apply is enabled