162306a36Sopenharmony_ci#!/bin/sh
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0+
362306a36Sopenharmony_ci#
462306a36Sopenharmony_ci# Produce awk statements roughly depicting the system's CPU and cache
562306a36Sopenharmony_ci# layout.  If the required information is not available, produce
662306a36Sopenharmony_ci# error messages as awk comments.  Successful exit regardless.
762306a36Sopenharmony_ci#
862306a36Sopenharmony_ci# Usage: kvm-assign-cpus.sh /path/to/sysfs
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciT="`mktemp -d ${TMPDIR-/tmp}/kvm-assign-cpus.sh.XXXXXX`"
1162306a36Sopenharmony_citrap 'rm -rf $T' 0 2
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cisysfsdir=${1-/sys/devices/system/node}
1462306a36Sopenharmony_ciif ! cd "$sysfsdir" > $T/msg 2>&1
1562306a36Sopenharmony_cithen
1662306a36Sopenharmony_ci	sed -e 's/^/# /' < $T/msg
1762306a36Sopenharmony_ci	exit 0
1862306a36Sopenharmony_cifi
1962306a36Sopenharmony_cinodelist="`ls -d node*`"
2062306a36Sopenharmony_cifor i in node*
2162306a36Sopenharmony_cido
2262306a36Sopenharmony_ci	if ! test -d $i/
2362306a36Sopenharmony_ci	then
2462306a36Sopenharmony_ci		echo "# Not a directory: $sysfsdir/node*"
2562306a36Sopenharmony_ci		exit 0
2662306a36Sopenharmony_ci	fi
2762306a36Sopenharmony_ci	for j in $i/cpu*/cache/index*
2862306a36Sopenharmony_ci	do
2962306a36Sopenharmony_ci		if ! test -d $j/
3062306a36Sopenharmony_ci		then
3162306a36Sopenharmony_ci			echo "# Not a directory: $sysfsdir/$j"
3262306a36Sopenharmony_ci			exit 0
3362306a36Sopenharmony_ci		else
3462306a36Sopenharmony_ci			break
3562306a36Sopenharmony_ci		fi
3662306a36Sopenharmony_ci	done
3762306a36Sopenharmony_ci	indexlist="`ls -d $i/cpu* | grep 'cpu[0-9][0-9]*' | head -1 | sed -e 's,^.*$,ls -d &/cache/index*,' | sh | sed -e 's,^.*/,,'`"
3862306a36Sopenharmony_ci	break
3962306a36Sopenharmony_cidone
4062306a36Sopenharmony_cifor i in node*/cpu*/cache/index*/shared_cpu_list
4162306a36Sopenharmony_cido
4262306a36Sopenharmony_ci	if ! test -f $i
4362306a36Sopenharmony_ci	then
4462306a36Sopenharmony_ci		echo "# Not a file: $sysfsdir/$i"
4562306a36Sopenharmony_ci		exit 0
4662306a36Sopenharmony_ci	else
4762306a36Sopenharmony_ci		break
4862306a36Sopenharmony_ci	fi
4962306a36Sopenharmony_cidone
5062306a36Sopenharmony_cifirstshared=
5162306a36Sopenharmony_cifor i in $indexlist
5262306a36Sopenharmony_cido
5362306a36Sopenharmony_ci	rm -f $T/cpulist
5462306a36Sopenharmony_ci	for n in node*
5562306a36Sopenharmony_ci	do
5662306a36Sopenharmony_ci		f="$n/cpu*/cache/$i/shared_cpu_list"
5762306a36Sopenharmony_ci		if ! cat $f > $T/msg 2>&1
5862306a36Sopenharmony_ci		then
5962306a36Sopenharmony_ci			sed -e 's/^/# /' < $T/msg
6062306a36Sopenharmony_ci			exit 0
6162306a36Sopenharmony_ci		fi
6262306a36Sopenharmony_ci		cat $f >> $T/cpulist
6362306a36Sopenharmony_ci	done
6462306a36Sopenharmony_ci	if grep -q '[-,]' $T/cpulist
6562306a36Sopenharmony_ci	then
6662306a36Sopenharmony_ci		if test -z "$firstshared"
6762306a36Sopenharmony_ci		then
6862306a36Sopenharmony_ci			firstshared="$i"
6962306a36Sopenharmony_ci		fi
7062306a36Sopenharmony_ci	fi
7162306a36Sopenharmony_cidone
7262306a36Sopenharmony_ciif test -z "$firstshared"
7362306a36Sopenharmony_cithen
7462306a36Sopenharmony_ci	splitindex="`echo $indexlist | sed -e 's/ .*$//'`"
7562306a36Sopenharmony_cielse
7662306a36Sopenharmony_ci	splitindex="$firstshared"
7762306a36Sopenharmony_cifi
7862306a36Sopenharmony_cinodenum=0
7962306a36Sopenharmony_cifor n in node*
8062306a36Sopenharmony_cido
8162306a36Sopenharmony_ci	cat $n/cpu*/cache/$splitindex/shared_cpu_list | sort -u -k1n |
8262306a36Sopenharmony_ci	awk -v nodenum="$nodenum" '
8362306a36Sopenharmony_ci	BEGIN {
8462306a36Sopenharmony_ci		idx = 0;
8562306a36Sopenharmony_ci	}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	{
8862306a36Sopenharmony_ci		nlists = split($0, cpulists, ",");
8962306a36Sopenharmony_ci		for (i = 1; i <= nlists; i++) {
9062306a36Sopenharmony_ci			listsize = split(cpulists[i], cpus, "-");
9162306a36Sopenharmony_ci			if (listsize == 1)
9262306a36Sopenharmony_ci				cpus[2] = cpus[1];
9362306a36Sopenharmony_ci			for (j = cpus[1]; j <= cpus[2]; j++) {
9462306a36Sopenharmony_ci				print "cpu[" nodenum "][" idx "] = " j ";";
9562306a36Sopenharmony_ci				idx++;
9662306a36Sopenharmony_ci			}
9762306a36Sopenharmony_ci		}
9862306a36Sopenharmony_ci	}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	END {
10162306a36Sopenharmony_ci		print "nodecpus[" nodenum "] = " idx ";";
10262306a36Sopenharmony_ci	}'
10362306a36Sopenharmony_ci	nodenum=`expr $nodenum + 1`
10462306a36Sopenharmony_cidone
10562306a36Sopenharmony_ciecho "numnodes = $nodenum;"
106