Initial commit
This commit is contained in:
149
scripts/optimize/kernel-params.sh
Normal file
149
scripts/optimize/kernel-params.sh
Normal 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"
|
||||
67
scripts/optimize/rollback.sh
Normal file
67
scripts/optimize/rollback.sh
Normal 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"
|
||||
56
scripts/optimize/tuned-profile.sh
Normal file
56
scripts/optimize/tuned-profile.sh
Normal 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
|
||||
97
scripts/optimize/verify.sh
Normal file
97
scripts/optimize/verify.sh
Normal 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 ""
|
||||
83
scripts/optimize/vram-gtt.sh
Normal file
83
scripts/optimize/vram-gtt.sh
Normal 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
|
||||
Reference in New Issue
Block a user