#!/bin/bash # bridge_sems.sh - bridge the guest's own page table view into the host service. # # The emulation cannot (yet) translate the CUDA client's sysmem semaphores # (guest RAM pages mapped at VAs above the vidmem window base), so releases # for them are counted as misses. This helper translates the client's # /dev/nvidia* mappings through the guest's /proc//pagemap (the guest # kernel owns the mapping) and injects each present page into the service as # a sysmem pin. # # Usage: tools/guest-diag/bridge_sems.sh [iterations] [prefix-hex] set -u cd "$(dirname "$0")/../.." ITER=${1:-1} START=${2:-0} VMEXEC=./scripts/vgpu_vm.py for i in $(seq 1 "$ITER"); do pid=$(timeout 20 $VMEXEC exec --timeout 15 'pgrep -x cdt | head -1' 2>/dev/null | tail -1) [ -n "$pid" ] || { echo "no cdt pid"; exit 1; } b64=$(base64 -w0 tools/guest-diag/guest_pmap_all.py) timeout 30 $VMEXEC exec --timeout 25 "echo '$b64' | base64 -d > /tmp/pmapall.py" >/dev/null 2>&1 cursor=$START total=0 # Keep each guest-agent reply small: large outputs come back truncated # ("Unterminated string"), which silently drops all but the last line. for chunk in $(seq 1 120); do mapfile -t lines < <(timeout 60 $VMEXEC exec --timeout 50 "sudo python3 /tmp/pmapall.py $pid $cursor 32" 2>/dev/null | grep -aE '^0x[0-9a-f]+,0x[0-9a-f]+$') [ "${#lines[@]}" -gt 0 ] || break for l in "${lines[@]}"; do va=${l%%,*} pa=${l##*,} echo "$va,$pa,0x1000,1" | sudo tee /sys/module/vgsp/parameters/sema_map_add >/dev/null done total=$((total + ${#lines[@]})) last_va=${lines[-1]%%,*} cursor=$(printf '0x%x' $(( 16#${last_va#0x} + 0x1000 ))) done echo "iter $i: pinned $total pages (pid $pid)" sleep 2 done