Skip to content

Gaming performance: seg game, safe image tuning, fallback kernel (includes the lean overhaul) - #11

Merged
SegMind25 merged 23 commits into
mainfrom
seg/gaming-performance
Oct 20, 2026
Merged

SegMind25 merged 23 commits into
mainfrom
seg/gaming-performance

Conversation

@SegMind25

Copy link
Copy Markdown
Owner

Summary

Delivery: merging this puts everything on main, which is what sudo seglinux-upgrade reads, so existing installs pick it up (the upgrade now builds segctl too, see below). The merge commit carries [build iso] [build lite iso] so CI builds both editions.

Makes SegLinux fast for games without making the image heavier, on every init (OpenRC, runit, dinit, s6). Three parts:

  1. Image defaults that are safe for everyone: a few sysctls, limits, shader-cache sizes, NVIDIA modeset, wine-staging, kernel parameters, and a fallback kernel.
  2. seg game, a small addition to the existing seg Rust tool (a GameMode replacement with a readiness check and a hardware-aware driver installer). Binary: 567,536 B → 725,288 B (+157,752 B, +28 %), same release profile (opt-level = "z", LTO, codegen-units = 1, panic = "abort", strip). One new dependency, libc; all unsafe is in one file (game/proc.rs) and CI enforces that.
  3. Docs: docs/gaming.md (Steam launch options, how to read seg game check, a benchmark method), tools/seg/README.md, README, a new CHANGELOG.md.

This PR is stacked on seg/rust-lean-overhaul, which is not merged and has no PR, so its commits (lean-down, seg itself, bug fixes) are part of this diff. The gaming work starts at cd1f78c; everything before it is that branch. docs/lean-audit.md has its measurements (full ISO −4.7 %, −475 MiB installed).

Every tweak and why

Image (installed by default)

Change Where Why
vm.max_map_count = 2147483642 80-seglinux-gaming.conf (already there) Proton/Wine games crash with "out of memory" below ~1 M maps
kernel.split_lock_mitigate = 0 same (already there) The kernel deliberately slows games that do split locks
vm.compaction_proactiveness = 0 same, new Background memory defragmentation shows as stutter while a game allocates; on-demand compaction still works. What SteamOS sets
nofile hard 524288 → 1048576, nice -10 for @gamemode limits.d esync/fsync keep one fd per sync object; 1048576 is the kernel max. nice -10 lets seg game run raise a game's priority
Shader caches 10 GB: MESA_SHADER_CACHE_MAX_SIZE (was 4G), __GL_SHADER_DISK_CACHE_SIZE, __GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1 /etc/profile.d (so every init; environment.d is systemd's) With several games the 1 GB default evicts compiled shaders → recompiling stutter; NVIDIA deletes its cache when full unless told not to. Costs disk only; a value the user sets wins
nvidia_drm modeset=1 fbdev=1 /usr/lib/modprobe.d/seglinux-nvidia.conf Needed by Wayland compositors and VT switching. Does nothing without NVIDIA's driver
wine → wine-staging full profile Staging patches (esync/fsync/NTSYNC, game fixes); provides wine. Resolves on Artix (CI)
transparent_hugepage=madvise kernel cmdline (Setup) and seg game apply at boot Huge pages only for programs that ask; always can stall on compaction. linux-zen starts with always, so the service switches always → madvise (it leaves never alone); found by booting the Lite image
amd_pstate=active kernel cmdline (Setup), AMD CPUs only The CPU picks clocks itself, guided by the energy hint seg game run sets. Ignored by kernels/CPUs without it
Fallback kernel Setup, when online ([performance] fallback_kernel, default on) Installs linux beside linux-zen (and the reverse); GRUB lists both. The kernel that runs is never removed
seg-game service (OpenRC, runit, dinit, s6) segctl package, enabled by its install script Applies the gaming sysctls and /dev/ntsync permissions at boot on every init
gamemode group created by segctl install script Needed for the sudoers rule below; Setup already adds users to it

Already in the repo and unchanged: linux-zen as the ISO kernel, NTSYNC module + udev rule, [lib32], mesa/vulkan-* and their lib32- versions, vulkan-tools, steam, gamescope, mangohud, winetricks, lutris, NVIDIA's open driver installed by Setup only when a Turing-or-newer GPU is found.

seg game (runtime, nothing permanent)

  • seg game run -- CMD (Steam: seg game run -- %command%). While the game runs: governor + energy preference performance, AMD GPU power_dpm_force_performance_level = high, game nice -4 and best-effort I/O priority 0, screen saver held off (org.freedesktop.ScreenSaver.Inhibit over a hand-written minimal D-Bus client), optional pinning to the V-Cache chiplet of a two-chiplet X3D CPU (found from L3 sizes in /sys), shader-cache env, MangoHud/gamescope wrapping from per-game profiles. Everything is restored on exit, Ctrl+C, SIGTERM, SIGHUP and a panic of seg itself (a panic hook, since panic = "abort" skips destructors). Several games at once are handled (owners tracked by pid + start time, so a crashed game does not keep the boost on).
  • seg game check: PASS/WARN/FAIL/SKIP with the exact fix under each: Vulkan, GPU driver, lib32 drivers, ntsync, vm.max_map_count, open files, kernel, fallback kernel, governor, amd-pstate, boost permission, hugepages, split lock, compaction, mitigations. Exit 1 on FAIL.
  • seg game setup [--yes] [--games] [--lutris]: detects GPUs (/sys/class/drm + lspci) and lists/installs packages for those GPUs only. No NVIDIA card → no NVIDIA package.
  • seg game profiles, per-game ~/.config/seg/games.toml (governor, pin, MangoHud, gamescope args, nice), matched by executable name; mistakes are reported with their line number.
  • seg game apply (the service), seg game audio on|off (low-latency PipeWire, off by default), seg game unsafe-boost on|off (see safety), seg tune gaming.
  • Presets, all off until asked: a MangoHud config, PipeWire drop-ins.

Safety notes

  • mitigations=off is never a default. The only way to get it is sudo seg game unsafe-boost on --i-understand, which first prints a warning (Spectre/Meltdown-class protections; any program, including JavaScript, may read memory it must not), edits GRUB_CMDLINE_LINUX_DEFAULT, takes effect at the next boot. off undoes it; seg game check WARNs while it is on.
  • No global unsafe tweaks. The CPU governor is never performance all day by default, only while a game runs. THP stays madvise. Nothing touches voltages or clocks.
  • One narrow root helper. /etc/sudoers.d/seg-game lets the gamemode group run exactly seg game boost on <pid> [governor] and boost off <pid> as root. The helper rejects extra arguments, pid ≤ 1 and governor names with any character outside [a-z0-9_-], and only writes the cpufreq and amdgpu power files. A group member can therefore change the CPU governor and the AMD GPU power level and nothing else (the same trust the gamemode package asks for). visudo -cf runs in CI.
  • The fallback kernel is never removed, by Setup, seg clean or anything else.
  • Drivers only for hardware that is there: seg game setup and Setup read the PCI devices.
  • Restore on crash: state lives in /run/seg (0700 dir, 0600 file, flock); a reboot clears everything anyway.
  • unsafe is confined to game/proc.rs (9 libc calls, each with a SAFETY comment); CI fails if it appears anywhere else. No unwrap/expect/panic!/slice indexing outside tests (compile-time lints).

Deviations from the brief (please check)

  1. Swappiness is not in the 80-…gaming sysctl file. With zram (the default) a high value is right, and Setup writes 180; a low value would make zram worse. seg tune gaming sets 10 for machines without zram (and 180 with it). Say if you want a fixed number in the file anyway.
  2. lib32-mangohud is not in the Artix repositories (CI's pacman -Sp said so), so it is skipped: 32-bit games get no MangoHud overlay unless built from the AUR. Documented, and a test keeps it out of seg game setup.
  3. NVIDIA before Turing: no proprietary driver is installed; those cards keep nouveau/NVK (NVIDIA's current branch dropped them). nvidia-dkms (non-open) is therefore not used anywhere.
  4. docs/gaming.md, not docs/GAMING.md: that page already exists and a second file differing only in case would break checkouts on macOS/Windows. All gaming docs are there.
  5. linux-zen is already the default ISO kernel, so "zen as a selectable entry" is implemented as the other kernel (linux) being installed beside it by Setup.
  6. NVIDIA nvidia-settings power mode (PowerMizer) is not implemented in seg game run: it needs a running X/Wayland session API I could not test.

Verification

Run here and in CI:

  • cargo fmt --check, cargo clippy -- -D warnings (with and without --all-targets), cargo test --locked: 187 tests in tools/seg (was 81 on the base branch; the new ones cover CPU/GPU detection against fake /sys and /proc trees in segctl/tests/fixtures — 7950X3D, a second-CCD V-Cache part, 7800X3D, ordinary AMD/Intel CPUs, a VM; AMD, NVIDIA Ada and Pascal, Intel Arc, a hybrid laptop, no GPU — and the TOML parsing, with line numbers in errors). Root workspace fmt/clippy/tests also pass (Setup changed).
  • Release build and size: 725,288 B (CI prints it in the job summary).
  • shellcheck clean on every script (the CI step is extended); visudo -cf on the sudoers rule.
  • Package names on a real Artix container (pacman -Sp): all four package jobs (full on OpenRC/runit/dinit, Lite) pass, including wine-staging; they now also resolve every package seg game setup can choose (nvidia-open-dkms, nvidia-utils, lib32-nvidia-utils, nvidia-settings, vulkan-nouveau, …) on top of the image, via a pinned list (tests/setup-packages.txt) that a unit test keeps in step with the code.
  • Real images, built in CI (a throwaway workflow on a branch that is deleted and not part of this PR): both editions build with build-in-container.sh (OpenRC, linux-zen) and were opened. Full: 2,890,530,816 B (the base branch's was 2,887,837,696 B: +2.7 MB for wine-staging and segctl's larger binary), about 6,672 MiB installed. Lite: 1,792.2 MiB installed. In both: the sudoers file is -r--r----- root/root and its content is the two commands only, the gamemode group exists, seg-game is enabled in default (OpenRC) and its runit/dinit/s6 files are there, the sysctl/limits/profile.d/modprobe files are installed. Full: wine-staging is in and plain wine is not, steam, gamescope, mangohud, winetricks, lutris, vulkan-tools, lib32-mesa, linux-zen, gamemode are in, no NVIDIA driver is on the image.
  • Lite booted in QEMU/KVM (text console, logged in, commands typed and read back by OCR): max_map_count = 2147483642, compaction_proactiveness = 0, split_lock_mitigate = 0 and nofile hard = 1048576 are applied at boot; /dev/ntsync is crw-rw-rw-; seg-game, seg-tune, seg-zram are enabled and started; seg game check runs (9 pass, 3 to improve, 1 fail: no vulkaninfo on Lite by design); seg game run -- sleep 2 exits 0; seg game setup on the emulated VGA card says "no driver known" and lists the common Vulkan packages; seg tune gaming --dry-run shows its changes; seg doctor: no problems (that boot also found the shutdown-runlevel false positive and the hugepage gap below, both fixed afterwards).
  • Found by that boot, fixed in this PR: (1) seg doctor called OpenRC's shutdown-runlevel services failed (fixed on the base branch); (2) transparent hugepages were always on linux-zen's live image, because madvise was only a GRUB parameter written by Setup: seg game apply (the seg-game service) now changes always to madvise at boot. Both fixes have unit tests; neither was booted again after the fix.
  • sudo seglinux-upgrade only built the seglinux package, so an existing install would never have received seg, seg game, the services or the sudoers rule. It now builds segctl from the same source and installs both; CI builds this on an Artix container and checks the package, the group, the sudoers mode and syntax, the service files and seg game check/run --dry-run without a GPU.
  • The benchmark summary script in the docs was checked against an independent Python calculation on synthetic frame times (it verifies the arithmetic only; no benchmark numbers are given anywhere, on purpose).
  • Earlier on the base branch: seg against a real Artix container and a real dbus-daemon (screen-saver inhibit), restore-on-signal as an unprivileged user through a sudo shim.

Still untested

Nothing below was possible in the sandbox or in GitHub Actions (no GPU, VMs without cpufreq):

  • No GPU anywhere, so no vkcube/vkmark and no game ran. seg game check's Vulkan parsing reads the deviceName = lines of vulkaninfo --summary from the documented format, not from a live capture.
  • Real hardware paths: governor/EPP writes, AMD power_dpm_force_performance_level, /dev/ntsync on a real kernel, V-Cache pinning on a real X3D CPU (only fake sysfs trees written from the cache topology), amd_pstate driver detection. NVIDIA: nothing run on NVIDIA hardware (the DKMS step is unchanged apart from the headers; its plan text is unit-tested).
  • The fixes after the image check (hugepages at boot, the upgrade also building segctl) were verified by unit tests and the CI Artix container, not by booting an image again.
  • Setup on a real install: the fallback-kernel step, amd_pstate=active and THP parameters are covered by plan/unit tests only; grub-mkconfig listing both kernels is expected, not observed.
  • Steam/Proton end to end: seg game run -- %command% was tested with ordinary commands and signals, not under Steam's reaper/pressure-vessel; profile matching of Proton command lines is unit-tested only. The screen-saver inhibit was tested against dbus-daemon, not a desktop's screensaver service.
  • Other inits at run time: only OpenRC was booted. The runit, dinit and s6 seg-game definitions are shipped (file presence is checked in the built image) but not booted. The s6 definition (type/up) is untested in any way beyond shellcheck.
  • The boost helper's concurrency (several games at once) is unit-tested, not exercised on a running system.
  • The MangoHud options in the benchmark section (log_interval=0, autostart_log, no_display) and the low-latency PipeWire drop-ins were not run against MangoHud/PipeWire.
  • No performance claim is made: whether seg game run helps on a given machine is for the reader to measure with the method in docs/gaming.md.

Generated by Claude Code

claude added 23 commits October 20, 2026 19:31
Sizes come from CI run 48 (4ca2f45): ISO, rootfs, installed size and the
largest packages of both editions. The bloat table lists what each item
costs, why it is bloat and what is done about it; product decisions are
listed separately and not acted on.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…image

From the 19 October build report (installed size): linux-zen-headers
325 MiB, opencv 113 MiB (only spectacle needs it), plus the legacy
xorg-server and xf86 driver stack and a third system-information tool.

- Setup downloads the running kernel's headers with the NVIDIA DKMS
  driver, the only thing that builds modules. The kernel package comes
  from the pkgbase file of the running kernel.
- The artools library patch that reads the kernel version from
  /usr/lib/modules now applies to every kernel: the stock one no longer
  has headers to read it from.
- The desktop has its own screenshots, so spectacle goes; both sessions
  are Wayland, so the X stack becomes xorg-xwayland, as in Lite.
- Five packages listed twice are listed once.
- cupsd is no longer enabled by default (live session and Setup); the
  packages stay.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
A workspace of its own (release profile: opt-level z, LTO, panic=abort,
stripped; about 550 KiB) with the crate segctl and the binary seg. One
dependency, lexopt.

- seg info: distro, kernel, init, uptime, RAM, packages, disk.
- seg svc list|enable|disable|start|stop: OpenRC, runit, dinit and s6,
  detected from PID 1, /run, then the installed files.
- seg clean: orphans, pacman cache beyond the newest 2 versions (a port
  of libalpm's vercmp), rotated logs, ~/.cache size. Dry run by default.
- seg tune light|balanced|performance: vm sysctls, CPU governor, I/O
  scheduler per disk type; saved to /etc/sysctl.d/99-seg.conf.
- seg zram on|off|status: zstd swap in memory, half the RAM.
- seg doctor: failed services, missing firmware, low disk space, a stale
  db.lck, a broken keyring, each with its fix.

Root is checked up front, unwrap/expect/panic/indexing are compile errors
outside tests, output ends quietly on a closed pipe. 77 unit tests cover
every parser and the file-writing parts against a fake /sys, /proc, /etc.
Also run in an Artix container: info, doctor, clean, tune, zram status,
svc against the real dinit layout.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
- pkg/segctl: PKGBUILD, install script (enables seg-zram and seg-tune,
  choosing the init by what is installed, so it works in the build's
  chroot), Makefile. Ships seg, the services for OpenRC, runit and dinit,
  the balanced profile and the weekly fstrim job.
- build-in-container.sh builds it from tools/seg into the same local
  [seglinux] repository; both profiles list segctl; check-packages.sh and
  online-packages.sh know it is built locally.
- Setup enables seg-zram and seg-tune on every installation, and no longer
  cupsd (installed, not started).
- zram-setup (run by udev at module load) hands over to seg zram on when
  seg is installed, so systems updated before segctl keep their zram.
- Fixes a stale path in a comment of the fstab code, and the swap
  partition test now looks for the fstab line instead of the word zram.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…itions

- /etc/makepkg.conf.d/10-seglinux.conf sets MAKEFLAGS="-j$(nproc)" (the
  generic x86-64 code generation stays, no -march=native).
- udev-ioschedulers.rules: the KERNEL globs (sd[a-z]*, nvme[0-9]*n[0-9]*)
  also matched partitions, which have no queue/scheduler to write, so
  udev logged an error for every partition. Only whole disks are matched
  now, and virtual disks (vd*, xvd*) get none like seg tune sets, since
  their host does the scheduling. Checked with udevadm verify.

pacman.conf already has Color and ParallelDownloads = 5.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
Rust command-line tools from the Artix repositories (no AUR), chosen
because each is small and replaces a daily habit:

- ripgrep (rg) searches folders far faster than grep -r and skips what
  .gitignore skips; fd finds files by name without find's syntax.
- eza is ls with colors and git status (aliased as ll and la only);
  zoxide gives z, which jumps to the folder you use most.

They add a few MiB (the next build report gives the exact figure) against
the 438 MiB the earlier commits take off (linux-zen-headers 325.1 MiB and
opencv 112.8 MiB, from the 19 October build report, plus the X server).
Not added, with reasons in docs/lean-audit.md: bat, dust, bottom, procs
and sd (they replace nothing that is installed), helix (a runtime of
grammars next to nano), alacritty (the terminal is the maintainers'
call), zellij, sudo-rs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
- A seg job: cargo fmt --check, clippy with -D warnings (with and without
  the test cfg, so the unwrap/expect ban is enforced), tests, and the
  release binary's size in the job summary. It fails if seg gains a
  dependency besides lexopt.
- udevadm verify on data/system/*.rules.
- A package may be listed only once per profile and init; the five repeats
  this found in the full profile are gone.
- shellcheck also covers zram-setup (it was missing), the seg services,
  the weekly fstrim script, segctl.install and rust-tools.bashrc.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…audit

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
Builds both editions on seg/rust-lean-overhaul without publishing
anything (the ISO workflow cannot be started from here), lists what the
system image contains and does not contain, and boots Lite in QEMU, logs
in on a text console and runs seg. Removed again once the branch has been
checked.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
Two conflicts with what SegLinux Setup already writes for zram, found
while reading the code again:

- Setup writes /etc/sysctl.d/90-seglinux-zram.conf with vm.swappiness = 180.
  seg tune raised swappiness to only 100 with zram on and its 99-seg.conf
  sorts after Setup's file, so installed systems would have ended up at
  100. zram swap now means at least 180 in every profile.
- Setup also writes /etc/udev/rules.d/99-seglinux-zram.rules, which sizes
  and formats zram0 (fstab switches it on). seg zram on reset a sized
  device, which could run under that rule's mkswap. A sized device is now
  kept as it is, and the package's udev rule calls seg zram on
  --if-unconfigured, which leaves it alone entirely, as the old script did.
  An explicit --size still resizes.

Also puts back the comment in disk.rs that named Setup's udev rule: it was
right, and the earlier "fix" of it was wrong.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
Found by booting the Lite image in QEMU: killprocs, mount-ro and savecache
are enabled in OpenRC's `shutdown` runlevel and are, by design, not running
while the system is up, yet seg doctor called them "enabled but stopped".
Service gets runs_at_boot (enabled in sysinit, boot or default on OpenRC;
the same as enabled on the other inits) and doctor looks at that.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…mits

The ISO check built both editions on this branch and booted Lite in QEMU
(run 39488187492); its results are in docs/lean-audit.md: the full ISO is
4.7 % smaller and 475 MiB less is installed, Lite is unchanged. The audit
claimed the kernel headers were on both editions; Lite never had them, so
the table says full only.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…g tune gaming

A lightweight GameMode inside the existing seg tool (libc is the only new
dependency; every unsafe block is in game/proc.rs).

- seg game run -- CMD (Steam: `seg game run -- %command%`): CPU governor and
  energy preference to performance and an AMD GPU to its high power level
  for the length of the game, through a root helper that several games
  share (state in /run/seg, dead games noticed by pid and start time);
  nice -4 and best I/O priority for the game; the screen saver held off
  over a hand-written D-Bus call (org.freedesktop.ScreenSaver.Inhibit);
  optional pinning to the V-Cache complex of an X3D CPU (found from the L3
  cache sizes in /sys); MangoHud and gamescope wrapping; shader cache sizes
  set. Everything is put back when the game ends, on SIGINT/SIGTERM/SIGHUP
  (INT is not forwarded: the terminal already did) and when seg itself
  panics (a hook, since panic=abort skips destructors).
- Per-game profiles in ~/.config/seg/games.toml, matched by the names in
  the command (a Proton command line matches its .exe); a small TOML
  subset parser that names the line of a mistake.
- seg game check: 15 PASS/WARN/FAIL checks (Vulkan, lib32 drivers, GPU
  driver, ntsync, max_map_count, open files, kernel and a fallback kernel,
  amd-pstate, governor, may boost, hugepages, split lock, compaction,
  mitigations), each failure with its exact fix.
- seg game setup: the driver packages for the GPUs found (sysfs + lspci);
  --yes installs them. Only for hardware that is there.
- seg game apply (for the seg-game service), audio on|off (low-latency
  PipeWire, per user), unsafe-boost on|off (mitigations=off, behind a
  warning and --i-understand, never done by anything else).
- seg tune gaming: low swappiness without zram (180 with it), warm caches,
  short writeback; the governor stays dynamic.
- Presets (all off until asked): MangoHud, low-latency PipeWire, the sudoers
  rule for the gamemode group, seg-game services for OpenRC, runit, dinit
  and s6.

183 unit tests use fake /sys and /proc trees in tests/fixtures (7950X3D,
second-CCD V-Cache, 7800X3D, ordinary CPUs, a VM; AMD, NVIDIA Ada and
Pascal, Intel Arc, a hybrid laptop). Release binary 566,576 -> 722,808 bytes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
segctl 0.1.0-2 installs the seg-game service for OpenRC, runit, dinit and
s6, /etc/sudoers.d/seg-game (the one root helper seg game run calls, for the
gamemode group only) and the MangoHud and low-latency PipeWire presets under
/usr/share/seg, all off until asked. The install script creates the group
(a chroot-safe getent/groupadd) and enables seg-game on the init that is
installed; an upgrade from 0.1.0-1 gets the new service, nothing else is
re-enabled.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…odeset

- vm.compaction_proactiveness = 0: no background memory defragmentation
  while a game allocates (what SteamOS sets); on-demand compaction stays.
- nofile hard limit 524288 -> 1048576 (the kernel's fs.nr_open maximum) for
  Wine's esync/fsync; members of gamemode may use nice -10 for seg game run.
- MESA_SHADER_CACHE_MAX_SIZE 4G -> 10G and the NVIDIA cache set to 10 GiB
  without the cleanup that deletes it when full (profile.d, so every init;
  a value set by the user wins).
- nvidia_drm modeset=1 fbdev=1 (needed by Wayland compositors); does
  nothing unless the driver is installed.
- vm.swappiness is deliberately not in this file: 180 with zram is Setup's,
  10 without it is seg tune gaming's.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
wine-staging provides wine and adds the Staging patches (esync/fsync and
NTSYNC support, game fixes); lib32-mangohud covers 32-bit games.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…g-game

- Install the other kernel (linux beside linux-zen and the reverse) as a
  boot menu entry to fall back on, when online; the kernel that runs is
  never removed. performance.fallback_kernel = false skips it.
- Kernel command line: transparent_hugepage=madvise on every kernel and
  amd_pstate=active on AuthenticAMD; a parameter of the same name in the
  answer file replaces the default.
- seg-game joins the default services, so the gaming sysctls and
  /dev/ntsync permissions apply on whichever init the install uses.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…iles

- The dependency guard allows seg, lexopt and libc (3 lines of cargo tree).
- unsafe may only appear in src/game/proc.rs.
- visudo -cf checks the sudoers rule seg game run depends on.
- shellcheck covers the seg-game OpenRC script (the runit one is already
  matched by the glob).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
…od, changelog

- docs/gaming.md (the existing page; a second docs/GAMING.md would collide
  with it on case-insensitive checkouts): the seg game walkthrough, Steam and
  Lutris launch options, what the boost changes and how it is undone, a
  table of every seg game check line, safety notes, the updated tuning table
  and a stock-versus-seg-game benchmark method with MangoHud logs and a
  summary script (tested against an independent calculation on synthetic
  frame times; no benchmark numbers are given).
- tools/seg/README.md and docs/seg.md: the game commands, the gaming tune
  profile, the second dependency, the code layout and the privilege model.
- README.md and a new CHANGELOG.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
CI's pacman -Sp on a real Artix container reported it as the only missing
package of the full edition (wine-staging resolves). Removed from the
profile and from seg game setup --games, with a test so it is not added
back unchecked, and documented: 32-bit games get no MangoHud overlay unless
the user builds lib32-mangohud from the AUR, which the base does not use.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
CI only checked the packages in the ISO profiles, so nvidia-open-dkms,
nvidia-utils, lib32-nvidia-utils, nvidia-settings and vulkan-nouveau, which
seg game setup (and Setup) install on demand, were never looked up in the
repositories. A unit test now pins the union of everything seg game setup
can choose (tests/setup-packages.txt; SEG_WRITE_FIXTURES=1 rewrites it) and
check-packages.sh -x resolves that list on top of the image in every
package job.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
The from-source upgrade built the seglinux package only, so a system
installed before seg existed never received seg, seg game, the seg-game
service or the sudoers rule, whatever was merged. It now builds segctl from
the same source tarball (tools/seg, as pkg/segctl/Makefile does) and
installs both in one pacman -U; a segctl build failure only warns. The CI
upgrade job builds from this commit on an Artix container and checks the
package, the gamemode group, the sudoers file mode and syntax, the service
files and that seg game check and seg game run --dry-run run without a GPU.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
Booting the Lite image in QEMU showed seg game check warning
"transparent hugepages: [always]": linux-zen starts with always, and the
madvise parameter is only written to GRUB by Setup, so the live image and
a system upgraded with seglinux-upgrade never had it. The seg-game service
runs seg game apply at boot on every init, so it now changes always to
madvise (and leaves madvise and never alone).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119819Vrp5vJojQCT1CjWog
@vercel

vercel Bot commented Oct 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
seglinux Ready Ready Preview Oct 20, 2026 9:28pm UTC

@SegMind25
SegMind25 merged commit 06b24ff into main Oct 20, 2026
18 checks passed

This branch was successfully deployed

1 active deployment
Preview — 4bbb12b1 Deployed Oct 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants