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