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