summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/bridge_sems.sh
blob: f54801d89f5c70e375bc5f8ea18b96a0992f9345 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/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/<pid>/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/open_iov_vfio/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