One‑shot checklist and files to reproduce my Lenovo ThinkBook 14 G6 IRL setup on Ubuntu 24.04 + XanMod kernel. Keeps the laptop aggressively fast on AC and sane on battery, with Wayland/Chrome tuning and GNOME theming.
- CPU: Intel Core i7‑13700H (14 cores, up to 5.0 GHz, 24 MB cache)
- RAM: 32 GB DDR5‑5200 (2×16 GB, dual channel)
- Storage: 1 TB NVMe M.2 Gen4 (≈5 GB/s read)
- GPU: Intel Iris Xe (integrated)
- Display: 14″ 1920×1200 (16:10), 300 nits, matte
- Wi‑Fi / BT: Intel AX211 Wi‑Fi 6E + BT 5.1+
- I/O: RJ‑45 GbE, 1×USB‑C (PD + video), 1×HDMI, 2×USB‑A, full‑size SD
- Input: ABNT2 backlit keyboard, FHD webcam + dual mics
- Security: Fingerprint + TPM 2.0
- Battery: 60 Wh (fast charge), Weight: ~1.4 kg
arthur@av-laptop
-----------------
OS: Ubuntu 24.04.3 LTS x86_64
Host: 21NQ ThinkBook 14 G6 IRL
Kernel: 6.16.4-x64v3-xanmod2
Uptime: 3 hours, 52 mins
Packages: 2010 (dpkg), 18 (brew), 14 (flatpak), 26 (snap)
Shell: zsh 5.9
Resolution: 3440x1440
DE: GNOME 46.0
WM: Mutter
WM Theme: Nordic-darker-v40
Theme: Nordic-darker-v40 [GTK2/3]
Icons: Papirus [GTK2/3]
Terminal: qterm
CPU: 13th Gen Intel i7-13700H (20) @ 4.800GHz
GPU: Intel Raptor Lake-P [Iris Xe Graphics]
Memory: 17780MiB / 31611MiB
- CPU/Power toggles (
ac-perf-toggle) that flip dozens of low‑level knobs on AC vs battery:powerprofilesctl+ platform profile, Intel HWP Dynamic Boost, EPB=0 on AC /8on battery, governors, THP, swappiness/dirty ratios, NVMe read‑ahead, Wi‑Fi power‑save.
- Auto‑apply at boot + hot‑plug (systemd units and udev rule).
- ZRAM via systemd zram‑generator (zstd, 75% RAM, high priority).
- NVMe scheduler tuning and read‑ahead.
- Filesystem:
noatime,lazytime+ weeklyfstrim.timer. - Intel GPU:
i915.enable_guc=3for GuC/HuC/RC/SLPC. - Chrome on Wayland defaults and safe flags.
- Monitoring:
perf-audit.sh, MangoHud,btop,s-tui, GPU/IO tools. - A couple user services (e.g.
fix-pcm-volume.service).
Fresh Ubuntu 24.04 install, GNOME (Wayland), XanMod kernel.
# 1) Base packages
sudo apt update
sudo apt install -y msr-tools zram-tools systemd-zram-generator irqbalance powertop powerstat lm-sensors nvme-cli iotop sysstat fio tmux btop s-tui intel-gpu-tools glmark2-x11 mangohud iw gnome-shell-extensions chrome-gnome-shell
# 2) Copy files from this repo
# (adjust $REPO if needed)
REPO="$HOME/av-laptop-infra"
# scripts / binaries
sudo install -Dm755 "$REPO/bin/ac-perf-toggle" /usr/local/sbin/ac-perf-toggle
sudo install -Dm755 "$REPO/bin/ac-perf-boot-wrapper" /usr/local/sbin/ac-perf-boot-wrapper
# udev: AC plug/unplug -> toggle
sudo install -Dm644 "$REPO/udev/99-ac-perf-toggle.rules" /etc/udev/rules.d/99-ac-perf-toggle.rules
sudo udevadm control --reload && sudo udevadm trigger -s power_supply
# systemd (boot-time AC/Battery branch)
sudo install -Dm644 "$REPO/systemd/ac-perf-on-ac.service" /etc/systemd/system/ac-perf-on-ac.service
sudo install -Dm644 "$REPO/systemd/ac-perf-on-battery.service" /etc/systemd/system/ac-perf-on-battery.service
sudo systemctl daemon-reload
sudo systemctl enable --now ac-perf-on-ac.service ac-perf-on-battery.service
# user service example
install -Dm644 "$REPO/services/fix-pcm-volume.service" "$HOME/.config/systemd/user/fix-pcm-volume.service"
systemctl --user daemon-reload
systemctl --user enable --now fix-pcm-volume.service
# 3) ZRAM (zstd, 75% RAM, priority 100)
sudo install -Dm644 "$REPO/etc/systemd/zram-generator.conf" /etc/systemd/zram-generator.conf
sudo systemctl daemon-reload
sudo systemctl enable --now dev-zram0.swap
# 4) Filesystem + trim
sudo cp /etc/fstab /etc/fstab.bak.$(date +%F)
# Ensure / and /boot use: noatime,lazytime
# Enable weekly discard:
sudo systemctl enable --now fstrim.timer
# 5) NVMe scheduler
sudo install -Dm644 "$REPO/udev/60-nvme-scheduler.rules" /etc/udev/rules.d/60-nvme-scheduler.rules
sudo udevadm control --reload && sudo udevadm trigger -s block
# 6) GPU: make sure kernel param is present
# Add 'i915.enable_guc=3' to GRUB/loader once, then reboot.Run the post‑install audit:
$REPO/scripts/perf-audit.shYou should see all checkmarks ✅ when on AC. On battery, the audit will show the expected battery values (lower perf).
System services
/etc/systemd/system/→ custom units (ours)/usr/lib/systemd/system/or/lib/systemd/system/→ distro units
User services
~/.config/systemd/user/
Ours
| Repo path | Target | Notes |
|---|---|---|
bin/ac-perf-toggle |
/usr/local/sbin/ac-perf-toggle |
The main AC/BAT switcher. Run `sudo /usr/local/sbin/ac-perf-toggle 1 |
bin/ac-perf-boot-wrapper |
/usr/local/sbin/ac-perf-boot-wrapper |
Helper to detect AC state if needed. |
udev/99-ac-perf-toggle.rules |
/etc/udev/rules.d/99-ac-perf-toggle.rules |
Auto‑switch on plug/unplug. |
systemd/ac-perf-on-ac.service |
/etc/systemd/system/ac-perf-on-ac.service |
Applies AC/perf profile at boot if on AC. |
systemd/ac-perf-on-battery.service |
/etc/systemd/system/ac-perf-on-battery.service |
Applies battery/balanced profile at boot if on battery. |
etc/systemd/zram-generator.conf |
/etc/systemd/zram-generator.conf |
zram, zstd, 75% RAM, priority 100. |
services/fix-pcm-volume.service |
~/.config/systemd/user/ |
User unit; manage with systemctl --user .... |
scripts/perf-audit.sh |
(run in place) | Verifies everything with ✅/❌. |
ac-perf-toggle flips (AC → Battery):
powerprofilesctl set performance→balancedand sets/sys/firmware/acpi/platform_profiletoperformance→balanced/low-powerif available.- Intel HWP Dynamic Boost:
1→0at/sys/devices/system/cpu/intel_pstate/hwp_dynamic_boost. - EPB (MSR 0x1B0):
0(max perf) →8(balanced power):wrmsr -a 0x1b0 0|8. - Governors:
performance→powersavefor all policies. - THP:
always→madvise. - VM:
swappiness=1,dirty_ratio=20,dirty_background_ratio=5→10/3on battery. - NVMe:
read_ahead_kb=2048. - Wi‑Fi power‑save: off → on.
Run manually:
sudo /usr/local/sbin/ac-perf-toggle 1 # AC / max perf
sudo /usr/local/sbin/ac-perf-toggle 0 # Battery / balancedBoot (choose based on AC presence):
# /etc/systemd/system/ac-perf-on-ac.service
[Unit]
Description=Apply aggressive profile on AC (at boot)
ConditionACPower=true
After=power-profiles-daemon.service
Wants=power-profiles-daemon.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ac-perf-toggle 1
[Install]
WantedBy=multi-user.target# /etc/systemd/system/ac-perf-on-battery.service
[Unit]
Description=Apply balanced profile on battery (at boot)
ConditionACPower=false
After=power-profiles-daemon.service
Wants=power-profiles-daemon.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ac-perf-toggle 0
[Install]
WantedBy=multi-user.targetHot‑plug (udev):
# /etc/udev/rules.d/99-ac-perf-toggle.rules
SUBSYSTEM=="power_supply", KERNEL=="ADP1", ATTR{{online}}=="1", RUN+="/usr/local/sbin/ac-perf-toggle 1"
SUBSYSTEM=="power_supply", KERNEL=="ADP1", ATTR{{online}}=="0", RUN+="/usr/local/sbin/ac-perf-toggle 0"
# USB‑C power sources (UCSI)
SUBSYSTEM=="power_supply", KERNEL=="ucsi-source-psy-*", ATTR{{online}}=="1", RUN+="/usr/local/sbin/ac-perf-toggle 1"
SUBSYSTEM=="power_supply", KERNEL=="ucsi-source-psy-*", ATTR{{online}}=="0", RUN+="/usr/local/sbin/ac-perf-toggle 0"
# /etc/systemd/zram-generator.conf
[zram0]
zram-size = ram * 0.75
compression-algorithm = zstd
swap-priority = 100Enable:
sudo systemctl enable --now dev-zram0.swap/and/bootmount options:noatime,lazytime(edit/etc/fstabthensudo mount -o remount ...).- Enable weekly discard:
sudo systemctl enable --now fstrim.timer. - NVMe scheduler rule:
# /etc/udev/rules.d/60-nvme-scheduler.rules
ACTION=="add|change", KERNEL=="nvme[0-9]n[0-9]", ATTR{{queue/scheduler}}="none"
(double braces above only to render in Markdown; in the real file it is ATTR{queue/scheduler})
- Kernel cmdline contains:
i915.enable_guc=3. - Verify after boot:
journalctl -k -b | grep -iE 'DMC firmware|GUC: submission enabled|HuC firmware'We keep a clean desktop entry and add safe flags:
--ozone-platform=wayland --use-gl=egl --enable-features=UseOzonePlatform --enable-zero-copy
Edit your local copy if needed:
cp /usr/share/applications/google-chrome.desktop ~/.local/share/applications/
sed -i 's#^Exec=.*google-chrome-stable.*#Exec=/usr/bin/google-chrome-stable --ozone-platform=wayland --use-gl=egl --enable-features=UseOzonePlatform --enable-zero-copy %U#' ~/.local/share/applications/google-chrome.desktop
update-desktop-database ~/.local/share/applications- Run the audit:
scripts/perf-audit.sh→ shows ✅/❌. - Nice live HUD:
MANGOHUD=1 glmark2orMANGOHUD=1 vkcube. - Term dashboards:
btop,s-tui,intel_gpu_top,iotop,iostat -xz 1. - One‑shot tmux monitor (example is in your shell history).
- Extensions I keep: Top Bar Organizer, Just Perfection, Blur My Shell, Vitals, AppIndicator, GSConnect, Tiling Assistant, Clipboard History.
- Theming: Adwaita‑ish (via Gradience) + matching GTK/Icons/Cursor. Login screen theming is optional and outside scope here.
System units
sudo systemctl status ac-perf-on-ac.service
sudo systemctl status ac-perf-on-battery.serviceUser units
systemctl --user status fix-pcm-volume.service
systemctl --user start|stop|restart fix-pcm-volume.service- Force a profile now:
sudo /usr/local/sbin/ac-perf-toggle 1 # AC / max perf sudo /usr/local/sbin/ac-perf-toggle 0 # Battery / balanced
- If EPB writes fail:
sudo modprobe msrthen try again. - If udev doesn’t trigger: run
sudo udevadm monitor --udev --subsystem-match=power_supplyand plug/unplug. - Revert mounts: restore
/etc/fstab.bak.*andmount -o remount / /boot. - Disable boot units:
sudo systemctl disable --now ac-perf-on-ac.service ac-perf-on-battery.service. - Remove udev rules in
/etc/udev/rules.d/and reload.
Systemd services are typically located in these directories:
System-wide services
•/etc/systemd/system/– custom services and overrides
•/usr/lib/systemd/system/– distribution-provided services
•/lib/systemd/system/– system services (on some distributions)User services
•~/.config/systemd/user/– user-specific servicesYour
fix-pcm-volume.serviceis a user service, managed with:
systemctl --user status fix-pcm-volume.service
systemctl --user start/stop/restart fix-pcm-volume.service
— Last updated: 2025-08-28