1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0+ 3# 4# Produce awk statements roughly depicting the system's CPU and cache 5# layout. If the required information is not available, produce 6# error messages as awk comments. Successful exit regardless. 7# 8# Usage: kvm-assign-cpus.sh /path/to/sysfs 9 10T=/tmp/kvm-assign-cpus.sh.$$ 11trap 'rm -rf $T' 0 2 12mkdir $T 13 14sysfsdir=${1-/sys/devices/system/node} 15if ! cd "$sysfsdir" > $T/msg 2>&1 16then 17 sed -e 's/^/# /' < $T/msg 18 exit 0 19fi 20nodelist="`ls -d node*`" 21for i in node* 22do 23 if ! test -d $i/ 24 then 25 echo "# Not a directory: $sysfsdir/node*" 26 exit 0 27 fi 28 for j in $i/cpu*/cache/index* 29 do 30 if ! test -d $j/ 31 then 32 echo "# Not a directory: $sysfsdir/$j" 33 exit 0 34 else 35 break 36 fi 37 done 38 indexlist="`ls -d $i/cpu* | grep 'cpu[0-9][0-9]*' | head -1 | sed -e 's,^.*$,ls -d &/cache/index*,' | sh | sed -e 's,^.*/,,'`" 39 break 40done 41for i in node*/cpu*/cache/index*/shared_cpu_list 42do 43 if ! test -f $i 44 then 45 echo "# Not a file: $sysfsdir/$i" 46 exit 0 47 else 48 break 49 fi 50done 51firstshared= 52for i in $indexlist 53do 54 rm -f $T/cpulist 55 for n in node* 56 do 57 f="$n/cpu*/cache/$i/shared_cpu_list" 58 if ! cat $f > $T/msg 2>&1 59 then 60 sed -e 's/^/# /' < $T/msg 61 exit 0 62 fi 63 cat $f >> $T/cpulist 64 done 65 if grep -q '[-,]' $T/cpulist 66 then 67 if test -z "$firstshared" 68 then 69 firstshared="$i" 70 fi 71 fi 72done 73if test -z "$firstshared" 74then 75 splitindex="`echo $indexlist | sed -e 's/ .*$//'`" 76else 77 splitindex="$firstshared" 78fi 79nodenum=0 80for n in node* 81do 82 cat $n/cpu*/cache/$splitindex/shared_cpu_list | sort -u -k1n | 83 awk -v nodenum="$nodenum" ' 84 BEGIN { 85 idx = 0; 86 } 87 88 { 89 nlists = split($0, cpulists, ","); 90 for (i = 1; i <= nlists; i++) { 91 listsize = split(cpulists[i], cpus, "-"); 92 if (listsize == 1) 93 cpus[2] = cpus[1]; 94 for (j = cpus[1]; j <= cpus[2]; j++) { 95 print "cpu[" nodenum "][" idx "] = " j ";"; 96 idx++; 97 } 98 } 99 } 100 101 END { 102 print "nodecpus[" nodenum "] = " idx ";"; 103 }' 104 nodenum=`expr $nodenum + 1` 105done 106echo "numnodes = $nodenum;" 107