testsAndMisc/linux_configuration/fixes/fix_arch_performance.sh
Krzysztof kuhy Rudnicki 4f2b0ccdf7 Dissolve linux_configuration/scripts/ and single_use/
Two levels of pure taxonomy carrying no information, and a 2-directory
cap leaves no room for them. Categories now sit directly under
linux_configuration/: features, fixes, utils, misc, fresh-install,
installers, diagnostics, gaming, boot_recovery, periodic_background, lib,
meta, tests. A script's own lib/ and tests/ are exempt from the cap, so
those stay put.

Depth violations 248 -> 139; roughly 40 of the remainder are inside
digital_wellbeing and hosts, deferred until the guard-lib repoint.

The moves are the easy half. What breaks is every path that counted
levels, and three classes of it had to be found by resolving paths rather
than reading diffs:

  - 52 relative `source` lines for lib/common.sh and lib/android.sh. The
    correct prefix differs per file: 40 were ../../ and 12 were ../../../,
    so a blanket replace would have fixed one set and broken the other.
  - REPO_ROOT in 7 fixes/lib/tests harnesses and setup_syncyomi_guard.sh,
    each walking up four levels from a directory now two levels shallower.
    This caused a real regression -- the fixes suite went red with
    "log_warn: command not found" -- caught by running it and comparing
    against the pre-move baseline worktree.
  - conftest.py's sys.path entries, which took the pytest gate down with
    14 collection errors, and the `# shellcheck source=` directives, which
    took shellcheck down with SC1091.

16 symlinks in $HOME broke, including the entire i3blocks bar. All
repointed, and cpu_monitor/memory/disk/time/volume were run to confirm
they emit real output rather than merely resolving.

Verified: 1798 tests pass at 100% coverage, 8 of 9 lib/tests suites pass
(the ninth needs the coverage jail, identically at baseline), pre-commit
is clean, and the two untracked secret configs are still ignored after
their gitignore paths changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 18:53:30 +02:00

216 lines
6.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Fix common Arch Linux performance issues on laptops with NVIDIA hybrid graphics
#
# Issues addressed:
# 1. NVIDIA xorg RenderAccel disabled → forces software rendering, Xorg eats 30%+ CPU
# 2. CPU governor stuck on powersave → AMD Ryzen throttled despite AC power
# 3. No power management daemon → inconsistent CPU/GPU power state management
# 4. Systemd journal bloated (>1GiB) → wastes disk I/O
# 5. NetworkManager-wait-online.service → adds ~6s to every boot for no benefit
# 6. media-organizer.service broken → wrong script path & user, fails every boot
#
# Usage:
# ./fix_arch_performance.sh # Apply all fixes
# ./fix_arch_performance.sh --dry-run # Show what would be done
# ./fix_arch_performance.sh --interactive # Prompt before each fix
# ./fix_arch_performance.sh -h # Show help
#
# Safe to re-run: all fixes are idempotent.
# Requires reboot/re-login for xorg changes to take effect.
set -euo pipefail
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
# shellcheck source=../lib/common.sh
source "$SCRIPT_DIR/../lib/common.sh"
parse_interactive_args "$@"
shift "$COMMON_ARGS_SHIFT"
DRY_RUN=false
for arg in "$@"; do
case "$arg" in
--dry-run)
DRY_RUN=true
;;
-h | --help)
cat <<'EOF'
fix_arch_performance.sh - Fix common Arch Linux laptop performance issues
Usage: fix_arch_performance.sh [OPTIONS]
Options:
--dry-run Show what would be done without making changes
-i, --interactive Prompt before each fix
-h, --help Show this help message
Fixes applied:
1. Enable NVIDIA hardware acceleration (RenderAccel true)
2. Install/enable power-profiles-daemon, set performance profile
3. Vacuum systemd journal to 300M, cap future size
4. Disable NetworkManager-wait-online.service (saves ~6s boot)
5. Fix media-organizer.service (correct path and user)
All fixes are idempotent and safe to re-run.
Xorg fixes require reboot/re-login to take effect.
EOF
exit 0
;;
esac
done
require_root "$@"
print_setup_header "Arch Linux Performance Fix"
FIXES_APPLIED=0
FIXES_SKIPPED=0
# ---------------------------------------------------------------------------
# Helper: run or print a fix depending on --dry-run / --interactive
# ---------------------------------------------------------------------------
apply_fix() {
local description="$1"
shift
echo ""
log_info "$description"
if [[ $DRY_RUN == "true" ]]; then
echo " [dry-run] Would run: $*"
return 0
fi
if [[ $INTERACTIVE_MODE == "true" ]]; then
if ! ask_yes_no " Apply this fix?"; then
log_warn "Skipped."
((FIXES_SKIPPED++)) || true
return 0
fi
fi
if "$@"; then
log_ok "Done."
((FIXES_APPLIED++)) || true
else
log_error "Failed (non-fatal, continuing)."
fi
}
# ===================================================================
# Fix 1: NVIDIA RenderAccel
# ===================================================================
fix_nvidia_render_accel() {
local conf="/etc/X11/xorg.conf.d/20-nvidia.conf"
# Check if RenderAccel is already correct
if [[ -f $conf ]] && grep -qi 'RenderAccel.*true' "$conf"; then
log_ok "NVIDIA RenderAccel is already enabled — skipping."
return 0
fi
mkdir -p /etc/X11/xorg.conf.d
# Back up the current config if it exists and has the bad setting
if [[ -f $conf ]]; then
cp "$conf" "${conf}.bak.$(date +%Y%m%d_%H%M%S)"
fi
cat >"$conf" <<'XORGEOF'
# NVIDIA configuration - hardware acceleration enabled
# Disabling RenderAccel forces Xorg into software rendering,
# causing 30%+ CPU usage on desktop. Keep this set to "true".
Section "Device"
Identifier "NVIDIA Card"
Driver "nvidia"
Option "RenderAccel" "true"
EndSection
XORGEOF
# Clean up old backups left by nvidia_troubleshoot.sh
rm -f /etc/X11/xorg.conf.d/20-nvidia.conf.backup.* 2>/dev/null || true
return 0
}
# ===================================================================
# Fix 2: Power management daemon + performance profile
# ===================================================================
fix_power_management() {
# Install power-profiles-daemon if missing
if ! pacman -Qi power-profiles-daemon >/dev/null 2>&1; then
log_info "Installing power-profiles-daemon..."
pacman -S --needed --noconfirm power-profiles-daemon
fi
# Enable and start the service
if ! systemctl is-enabled power-profiles-daemon.service >/dev/null 2>&1; then
systemctl enable --now power-profiles-daemon.service
elif ! systemctl is-active power-profiles-daemon.service >/dev/null 2>&1; then
systemctl start power-profiles-daemon.service
fi
# Resolve TLP conflict if both are enabled
if systemctl is-enabled tlp.service >/dev/null 2>&1; then
log_warn "TLP conflicts with power-profiles-daemon — disabling TLP."
systemctl disable --now tlp.service
fi
# Set performance profile (appropriate when plugged in with strong hardware)
sleep 1
if has_cmd powerprofilesctl; then
powerprofilesctl set performance
log_info "Power profile set to: $(powerprofilesctl get)"
fi
return 0
}
# shellcheck source=lib/arch_perf_fixes.sh
source "$SCRIPT_DIR/lib/arch_perf_fixes.sh"
main() {
apply_fix \
"Fix 1/5: Enable NVIDIA hardware acceleration (RenderAccel → true)" \
fix_nvidia_render_accel
apply_fix \
"Fix 2/5: Install/enable power-profiles-daemon + set performance profile" \
fix_power_management
apply_fix \
"Fix 3/5: Vacuum journal logs + set permanent 300M size cap" \
fix_journal
apply_fix \
"Fix 4/5: Disable NetworkManager-wait-online.service (~6s boot saving)" \
fix_nm_wait_online
apply_fix \
"Fix 5/5: Fix media-organizer.service (correct path and user)" \
fix_media_organizer
# ---------------------------------------------------------------
# Summary
# ---------------------------------------------------------------
echo ""
echo "=============================="
echo " Performance Fix Summary"
echo "=============================="
if [[ $DRY_RUN == "true" ]]; then
log_info "Dry-run mode — no changes were made."
else
log_ok "Fixes applied: $FIXES_APPLIED"
if [[ $FIXES_SKIPPED -gt 0 ]]; then
log_warn "Fixes skipped: $FIXES_SKIPPED"
fi
fi
echo ""
log_info "Reboot or re-login for xorg changes (Fix 1) to take effect."
log_info "After reboot, verify with: diagnose_arch_performance.sh"
}
main