Initial commit

This commit is contained in:
Felipe Cardoso
2026-03-25 20:13:15 +01:00
commit c596e38e9e
26 changed files with 2345 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
#!/usr/bin/env bash
# Configure kernel boot parameters for unified memory optimization
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../lib/common.sh"
source "$SCRIPT_DIR/../../lib/detect.sh"
source "$SCRIPT_DIR/../../lib/format.sh"
GRUB_FILE="/etc/default/grub"
log_header "Kernel Boot Parameter Optimization"
# ── Check root early ────────────────────────────────────
if [[ $EUID -ne 0 ]]; then
log_error "This script requires root. Re-run with: sudo make optimize-kernel"
exit 1
fi
# ── Show current state ───────────────────────────────────
log_info "Current kernel command line:"
printf " ${DIM}%s${RESET}\n" "$(cat /proc/cmdline)"
echo ""
param_iommu="$(detect_kernel_param 'iommu')"
param_gttsize="$(detect_gttsize_param)"
param_pages="$(detect_pages_limit_param)"
rec_gttsize="$(recommended_gttsize_mib)"
rec_pages="$(recommended_pages_limit)"
# ── Check what's needed ──────────────────────────────────
needs_change=false
log_info "Parameter status:"
if [[ "$param_iommu" == "pt" ]]; then
print_status pass "iommu=pt" "already set"
else
print_status fail "iommu=pt" "$([ -n "$param_iommu" ] && echo "current: $param_iommu" || echo "missing")"
needs_change=true
fi
if [[ -n "$param_gttsize" ]] && (( param_gttsize >= rec_gttsize )); then
print_status pass "amdgpu.gttsize" "current: $param_gttsize MiB"
else
print_status fail "amdgpu.gttsize" "$([ -n "$param_gttsize" ] && echo "current: $param_gttsize MiB, " || echo "missing, ")recommended: $rec_gttsize MiB (~$(human_mib "$rec_gttsize"))"
needs_change=true
fi
if [[ -n "$param_pages" ]] && (( param_pages >= rec_pages )); then
print_status pass "ttm.pages_limit" "current: $param_pages"
else
print_status fail "ttm.pages_limit" "$([ -n "$param_pages" ] && echo "current: $param_pages, " || echo "missing, ")recommended: $rec_pages"
needs_change=true
fi
if ! $needs_change; then
echo ""
log_success "All kernel parameters are already optimal!"
exit 0
fi
# ── Explain what we're doing ─────────────────────────────
echo ""
log_info "These parameters enable unified memory for the integrated GPU:"
echo " iommu=pt IOMMU passthrough — reduces memory access latency"
echo " amdgpu.gttsize=$rec_gttsize GPU can dynamically access ~$(human_mib "$rec_gttsize") system RAM"
echo " ttm.pages_limit=$rec_pages Pin limit for GPU memory pages ($(human_mib "$rec_gttsize") in 4K pages)"
echo ""
# ── Apply changes ────────────────────────────────────────
if ! confirm "Apply these kernel parameters to GRUB?"; then
log_info "Skipped. You can apply manually by editing $GRUB_FILE"
exit 0
fi
# Backup
BACKUP_DIR="$(data_dir backups)"
backup_file="$BACKUP_DIR/grub-$(timestamp).bak"
cp "$GRUB_FILE" "$backup_file"
log_success "GRUB backup saved: $backup_file"
# Parse current GRUB_CMDLINE_LINUX using Python (data via env vars, not interpolation)
current_cmdline="$(GRUB_PATH="$GRUB_FILE" python3 -c '
import re, os
with open(os.environ["GRUB_PATH"]) as f:
for line in f:
m = re.match(r"^GRUB_CMDLINE_LINUX=\"(.*)\"", line)
if m:
print(m.group(1))
raise SystemExit(0)
print("")
')"
# Remove any existing values of these params
new_cmdline="$current_cmdline"
new_cmdline="$(echo "$new_cmdline" | sed -E 's/\biommu=[^ ]*//g')"
new_cmdline="$(echo "$new_cmdline" | sed -E 's/\bamd_iommu=[^ ]*//g')"
new_cmdline="$(echo "$new_cmdline" | sed -E 's/\bamdgpu\.gttsize=[^ ]*//g')"
new_cmdline="$(echo "$new_cmdline" | sed -E 's/\bttm\.pages_limit=[^ ]*//g')"
# Clean up extra spaces
new_cmdline="$(echo "$new_cmdline" | xargs)"
# Add new params
new_cmdline="$new_cmdline iommu=pt amdgpu.gttsize=$rec_gttsize ttm.pages_limit=$rec_pages"
log_info "GRUB_CMDLINE_LINUX change:"
printf " ${RED}Before:${RESET} %s\n" "$current_cmdline"
printf " ${GREEN}After:${RESET} %s\n" "$new_cmdline"
echo ""
if ! confirm "Write this change?"; then
log_info "Aborted. Backup remains at: $backup_file"
exit 0
fi
# Apply using Python (all data via env vars — no shell interpolation into Python code)
GRUB_PATH="$GRUB_FILE" NEW_CMDLINE="$new_cmdline" python3 -c '
import re, os
grub_path = os.environ["GRUB_PATH"]
new_line = "GRUB_CMDLINE_LINUX=\"" + os.environ["NEW_CMDLINE"] + "\""
with open(grub_path) as f:
content = f.read()
content = re.sub(r"^GRUB_CMDLINE_LINUX=.*", new_line, content, count=1, flags=re.MULTILINE)
with open(grub_path, "w") as f:
f.write(content)
'
log_success "GRUB config updated"
# Regenerate GRUB — prefer grubby on modern Fedora (BLS), fall back to grub2-mkconfig
log_info "Regenerating boot configuration..."
if is_cmd grubby; then
grubby --update-kernel=ALL --args="iommu=pt amdgpu.gttsize=$rec_gttsize ttm.pages_limit=$rec_pages"
log_success "Boot entries updated via grubby"
elif [[ -d /boot/grub2 ]]; then
grub2-mkconfig -o /boot/grub2/grub.cfg
log_success "GRUB regenerated via grub2-mkconfig"
elif [[ -d /boot/grub ]]; then
grub-mkconfig -o /boot/grub/grub.cfg
log_success "GRUB regenerated via grub-mkconfig"
else
log_error "Could not find grubby or grub config directory. Regenerate manually."
exit 1
fi
echo ""
log_warn "REBOOT REQUIRED for kernel parameters to take effect."
log_info "After reboot, verify with: make audit"

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env bash
# Rollback optimization changes
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../lib/common.sh"
GRUB_FILE="/etc/default/grub"
BACKUP_DIR="$(data_dir backups)"
log_header "Rollback Optimizations"
# ── 1. GRUB rollback ────────────────────────────────────
log_info "GRUB backups:"
mapfile -t grub_backups < <(find "$BACKUP_DIR" -name 'grub-*.bak' -print 2>/dev/null | sort -r)
if (( ${#grub_backups[@]} == 0 )); then
log_info " No GRUB backups found"
else
for i in "${!grub_backups[@]}"; do
printf " [%d] %s\n" "$i" "${grub_backups[$i]}"
done
echo ""
if confirm "Restore most recent GRUB backup?"; then
require_root
backup="${grub_backups[0]}"
cp "$backup" "$GRUB_FILE"
log_success "GRUB restored from: $backup"
log_info "Regenerating boot configuration..."
if is_cmd grubby; then
# On BLS systems, also need to remove args via grubby
grubby --update-kernel=ALL --remove-args="iommu amdgpu.gttsize ttm.pages_limit" 2>/dev/null || true
log_success "Boot entries updated via grubby"
elif [[ -d /boot/grub2 ]]; then
grub2-mkconfig -o /boot/grub2/grub.cfg
log_success "GRUB regenerated via grub2-mkconfig"
elif [[ -d /boot/grub ]]; then
grub-mkconfig -o /boot/grub/grub.cfg
log_success "GRUB regenerated via grub-mkconfig"
else
log_error "Could not find grubby or grub config directory. Regenerate manually."
fi
log_warn "Reboot required for changes to take effect."
fi
fi
# ── 2. Tuned profile rollback ───────────────────────────
prev_profile_file="$BACKUP_DIR/tuned-previous-profile.txt"
if [[ -f "$prev_profile_file" ]]; then
prev_profile="$(cat "$prev_profile_file")"
current="$(tuned-adm active 2>/dev/null | sed 's/Current active profile: //' || echo "unknown")"
log_info "Tuned profile: $current (previous: $prev_profile)"
if [[ "$current" != "$prev_profile" ]] && confirm "Restore tuned profile to $prev_profile?"; then
sudo tuned-adm profile "$prev_profile"
log_success "Tuned profile restored to: $prev_profile"
fi
else
log_info "No previous tuned profile saved"
fi
# ── 3. BIOS reminder ────────────────────────────────────
echo ""
log_warn "BIOS VRAM changes cannot be rolled back automatically."
log_info "To revert: Reboot → F10 → Advanced → UMA Frame Buffer Size → restore previous value"

View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
# Switch tuned profile to accelerator-performance
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../lib/common.sh"
source "$SCRIPT_DIR/../../lib/detect.sh"
RECOMMENDED="accelerator-performance"
log_header "Tuned Profile Optimization"
if ! is_cmd tuned-adm; then
log_error "tuned is not installed. Install with: sudo dnf install tuned"
exit 1
fi
current="$(detect_tuned_profile)"
log_info "Current profile: $current"
if [[ "$current" == "$RECOMMENDED" ]]; then
log_success "Already using $RECOMMENDED"
exit 0
fi
# Check availability
if ! tuned-adm list 2>/dev/null | grep -q "$RECOMMENDED"; then
log_error "$RECOMMENDED profile not available"
log_info "Available profiles:"
tuned-adm list 2>/dev/null | grep "^-" | sed 's/^/ /'
exit 1
fi
echo ""
log_info "Recommended: $RECOMMENDED"
log_info "Description: Throughput performance with disabled higher latency STOP states"
log_info "Benefit: 5-8% improvement in prompt processing (pp) benchmarks"
log_info "No reboot required."
echo ""
if ! confirm "Switch to $RECOMMENDED?"; then
log_info "Skipped"
exit 0
fi
# Save current for rollback
echo "$current" > "$(data_dir backups)/tuned-previous-profile.txt"
sudo tuned-adm profile "$RECOMMENDED"
new_profile="$(detect_tuned_profile)"
if [[ "$new_profile" == "$RECOMMENDED" ]]; then
log_success "Profile switched to: $new_profile"
else
log_error "Profile switch may have failed. Current: $new_profile"
fi

View File

@@ -0,0 +1,97 @@
#!/usr/bin/env bash
# Post-optimization verification checklist
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../lib/common.sh"
source "$SCRIPT_DIR/../../lib/detect.sh"
source "$SCRIPT_DIR/../../lib/format.sh"
log_header "Optimization Verification"
score=0
total=0
check() {
local pass="$1" label="$2" detail="$3"
total=$(( total + 1 ))
if [[ "$pass" == "1" ]]; then
score=$(( score + 1 ))
print_status pass "$label" "$detail"
else
print_status fail "$label" "$detail"
fi
}
# Kernel version
kernel="$(detect_kernel_version)"
kernel_major=$(echo "$kernel" | cut -d. -f1)
kernel_minor=$(echo "$kernel" | cut -d. -f2)
kernel_ok=0
(( kernel_major > 6 || (kernel_major == 6 && kernel_minor >= 18) )) && kernel_ok=1
check "$kernel_ok" "Kernel >= 6.18.4" "$kernel"
# Firmware
fw_ok=1
detect_firmware_bad && fw_ok=0
check "$fw_ok" "Firmware (not 20251125)" "$(detect_firmware_version)"
# Kernel params
iommu_val="$(detect_kernel_param 'iommu')"
iommu_ok=0
[[ "$iommu_val" == "pt" ]] && iommu_ok=1
check "$iommu_ok" "iommu=pt" "${iommu_val:-not set}"
gttsize="$(detect_gttsize_param)"
rec_gttsize="$(recommended_gttsize_mib)"
gtt_ok=0
[[ -n "$gttsize" ]] && (( gttsize >= rec_gttsize )) && gtt_ok=1
check "$gtt_ok" "amdgpu.gttsize" "${gttsize:-not set} (recommended: $rec_gttsize)"
pages="$(detect_pages_limit_param)"
rec_pages="$(recommended_pages_limit)"
pages_ok=0
[[ -n "$pages" ]] && (( pages >= rec_pages )) && pages_ok=1
check "$pages_ok" "ttm.pages_limit" "${pages:-not set} (recommended: $rec_pages)"
# Tuned profile
tuned="$(detect_tuned_profile)"
tuned_ok=0
[[ "$tuned" == "accelerator-performance" ]] && tuned_ok=1
check "$tuned_ok" "Tuned profile" "$tuned"
# VRAM (should be <= 1 GiB)
vram="$(detect_vram_total)"
vram_gib=$(echo "scale=1; $vram / 1073741824" | bc)
vram_ok=0
(( vram <= 1073741824 )) && vram_ok=1
check "$vram_ok" "VRAM <= 1 GiB" "${vram_gib} GiB"
# GTT (should be close to recommended)
gtt="$(detect_gtt_total)"
gtt_gib=$(echo "scale=1; $gtt / 1073741824" | bc)
rec_gtt_bytes=$(( rec_gttsize * 1048576 ))
gtt_mem_ok=0
(( gtt >= rec_gtt_bytes * 3 / 4 )) && gtt_mem_ok=1
check "$gtt_mem_ok" "GTT >= $(human_mib "$rec_gttsize")" "${gtt_gib} GiB"
# GPU monitor installed
monitor_ok=0
is_cmd amdgpu_top && monitor_ok=1
check "$monitor_ok" "amdgpu_top installed" "$(is_cmd amdgpu_top && echo 'yes' || echo 'no — run make monitor-install')"
# Summary
echo ""
print_divider
printf "\n ${BOLD}Score: %d / %d${RESET}\n" "$score" "$total"
if (( score == total )); then
printf " ${GREEN}Fully optimized!${RESET} Run 'make benchmark' to measure performance.\n"
elif (( score >= total * 3 / 4 )); then
printf " ${YELLOW}Nearly there${RESET} — check the failed items above.\n"
elif (( score >= total / 2 )); then
printf " ${YELLOW}Partially optimized${RESET} — run 'make optimize' for the remaining items.\n"
else
printf " ${RED}Significant optimizations pending${RESET} — run 'make optimize'\n"
fi
echo ""

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env bash
# BIOS VRAM guidance + GTT verification
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../lib/common.sh"
source "$SCRIPT_DIR/../../lib/detect.sh"
source "$SCRIPT_DIR/../../lib/format.sh"
log_header "VRAM / GTT Memory Optimization"
vram_total="$(detect_vram_total)"
gtt_total="$(detect_gtt_total)"
vram_gib=$(echo "scale=1; $vram_total / 1073741824" | bc)
gtt_gib=$(echo "scale=1; $gtt_total / 1073741824" | bc)
log_info "Current memory allocation:"
print_kv "VRAM (dedicated)" "${vram_gib} GiB"
print_kv "GTT (dynamic)" "${gtt_gib} GiB"
print_kv "System RAM (visible)" "$(echo "scale=1; $(detect_system_ram_kb) / 1048576" | bc) GiB"
echo ""
# ── Check if BIOS VRAM change is needed ──────────────────
# Optimal: VRAM <= 1 GiB (0.5 GiB ideal), rest dynamically via GTT
if (( vram_total > 1073741824 )); then
log_warn "VRAM is ${vram_gib} GiB — this permanently locks memory away from the OS."
log_info "AMD recommends 512 MB dedicated VRAM for Strix Halo."
log_info "The GPU accesses additional memory dynamically via GTT (kernel params)."
echo ""
printf "${BOLD}BIOS Configuration Steps (HP ZBook Ultra G1a):${RESET}\n"
echo ""
echo " 1. Reboot the laptop"
echo " 2. Press F10 repeatedly during boot to enter BIOS Setup"
echo " 3. Navigate to: Advanced > Built-in Device Options"
echo " (or Advanced > Display > UMA Frame Buffer Size)"
echo " 4. Set UMA Frame Buffer Size to: 512 MB (or smallest available)"
echo " 5. Save and Exit (F10)"
echo ""
echo " NOTE: The exact menu path may vary by BIOS version."
echo " Look for 'UMA', 'Frame Buffer', 'VRAM', or 'iGPU Memory'."
echo ""
log_info "After BIOS change + reboot with kernel params, expected state:"
echo " VRAM: ~512 MiB"
echo " GTT: ~$(human_mib "$(recommended_gttsize_mib)") (with kernel params)"
echo " System RAM: ~$(echo "scale=1; $(detect_total_physical_ram_kb) / 1048576 - 0.5" | bc) GiB visible"
echo ""
elif (( vram_total <= 1073741824 )); then
log_success "VRAM is ${vram_gib} GiB — already optimal!"
fi
# ── Check GTT ────────────────────────────────────────────
rec_gttsize="$(recommended_gttsize_mib)"
rec_gtt_bytes=$(( rec_gttsize * 1048576 ))
if (( gtt_total >= rec_gtt_bytes * 3 / 4 )); then
log_success "GTT is ${gtt_gib} GiB — good (recommended: ~$(human_mib "$rec_gttsize"))"
else
log_warn "GTT is ${gtt_gib} GiB — low (recommended: ~$(human_mib "$rec_gttsize"))"
log_info "This requires kernel boot parameters. Run: make optimize-kernel"
fi
# ── Optional: amd-debug-tools ────────────────────────────
echo ""
log_header "Optional: amd-debug-tools (amd-ttm)"
log_info "AMD provides 'amd-debug-tools' for runtime GTT/TTM inspection."
if is_cmd amd-ttm; then
log_success "amd-ttm is installed"
log_info "Current GTT settings:"
amd-ttm 2>/dev/null || true
elif is_cmd pipx; then
log_info "Install with: pipx install amd-debug-tools"
if confirm "Install amd-debug-tools via pipx?"; then
pipx install amd-debug-tools
log_success "Installed. Run 'amd-ttm' to inspect GTT allocation."
fi
else
log_info "Install pipx first: sudo dnf install pipx"
log_info "Then: pipx install amd-debug-tools"
fi