MCPcopy Index your code
hub / github.com/OpenGamingCollective/cardwire

github.com/OpenGamingCollective/cardwire @v0.10.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.10.2 ↗ · + Follow
233 symbols 407 edges 37 files 39 documented · 17%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

cardwire

Packaging status

GitHub License

A GPU manager for Linux using eBPF LSM hooks to block GPUs

Creator and Main maintainer: @luytan

Disclaimer

  • This project is in early development. Expect bugs and incomplete functionality

Getting Started

Head to the docs to see how to install Cardwire on your system

Usage

The cardwire CLI lets you manage GPU states and system modes

Modes

  • Integrated: Blocks the discrete GPU
  • Hybrid: Unblocks the discrete GPU
  • Manual: Default mode for safety, allows individual GPU blocking/unblocking

Note: Integrated/Hybrid modes only work on host with two GPUs

Note 2: Manual mode is not implemented

# Set system mode
cardwire set integrated / hybrid / manual

# Get current mode status
cardwire get

# List all detected GPUs and their status
cardwire list

# Manually block/unblock a specific GPU by ID
cardwire gpu 1 --block
cardwire gpu 1 --unblock

Configuration

The daemon reads its configuration from /etc/cardwire/cardwire.toml.

# /etc/cardwire/cardwire.toml
auto_apply_gpu_state = true
experimental_nvidia_block = false
battery_auto_switch = false

experimental_nvidia_block is an experimental feature that blocks specifics NVIDIA's files, must be used with caution

Community projects:

for issues related to these projects, please report to their respective repo

GNOME extension (by Moxuz): https://extensions.gnome.org/extension/9919/cardwire-gpu-toggle/

Cardwire-tray (by SeawolfTony): https://github.com/JuanDelPueblo/cardwire-tray

How it works

Cardwire uses eBPF with LSM hooks to intercept file operations on GPU device nodes, such as /dev/dri/renderDX, /dev/dri/cardX, sysfs config and nvidiaX

When a GPU is "blocked," the eBPF program returns -ENOENT for any syscall targeting that device. This provides several key benefits:

  • Instant App Startup: Prevents applications (like Electron apps or GTK apps) from attempting to initialize the GPU, this eliminates the 3–4 second "hang" typically caused by waiting for a sleeping GPU to power up
  • Power Efficiency: By blocking access at the syscall level, the GPU is never woken from its lowest power state (D3cold), extending battery life on laptops
  • Non-Invasive: Unlike traditional methods that might require driver unloading, risky unbind or complex X11/Wayland setups, this approach is transparent to the rest of the system and easy to toggle
  • Also works with games

Notes

  • I'm still learning Rust, if some parts of the code are bad or unoptimized, feel free to open a PR

Credits

  • Asus-linux Discord for helping me find the ebpf method
  • Caelestia shell for the flake.nix, i used it as a reference

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

Extension points exported contracts — how you extend this code

FdoResultExt (Interface)
(no doc) [1 implementers]
crates/cardwire-daemon/src/interface/gpu.rs
Cardwire (Interface)
(no doc)
crates/cardwire-daemon/src/tasks/monitor_udev.rs
UPower (Interface)
(no doc)
crates/cardwire-daemon/src/tasks/battery_switch.rs
Cardwire (Interface)
(no doc)
crates/cardwire-daemon/src/tasks/battery_switch.rs

Core symbols most depended-on inside this repo

handle_error
called by 20
crates/cardwire-cli/src/main.rs
pci_address
called by 18
crates/cardwire-daemon/src/core/pci/models.rs
into_fdo
called by 16
crates/cardwire-daemon/src/interface/gpu.rs
block_kind
called by 10
crates/cardwire-ebpf/src/lib.rs
unblock_kind
called by 7
crates/cardwire-ebpf/src/lib.rs
nvidia_minor
called by 5
crates/cardwire-daemon/src/core/gpu/models.rs
parent_pci
called by 5
crates/cardwire-daemon/src/core/pci/models.rs
create_default_folder
called by 5
crates/cardwire-daemon/src/file/common.rs

Shape

Method 116
Class 55
Function 47
Enum 11
Interface 4

Languages

Rust86%
C14%

Modules by API surface

crates/cardwire-ebpf/src/bpf.c33 symbols
crates/cardwire-cli/src/dbus.rs23 symbols
crates/cardwire-ebpf/src/lib.rs15 symbols
crates/cardwire-daemon/src/core/pci/pci_device.rs14 symbols
crates/cardwire-daemon/src/core/pci/models.rs14 symbols
crates/cardwire-daemon/src/interface/gpu.rs13 symbols
crates/cardwire-daemon/src/file/state.rs13 symbols
crates/cardwire-daemon/src/interface/config.rs12 symbols
crates/cardwire-daemon/src/core/gpu/models.rs12 symbols
crates/cardwire-daemon/src/file/config.rs10 symbols
crates/cardwire-daemon/src/interface/mode.rs9 symbols
crates/cardwire-daemon/src/analyzer/models.rs8 symbols

For agents

$ claude mcp add cardwire \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact