xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/rcutorture/bin/jitter.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0+
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Alternate sleeping and spinning on randomly selected CPUs.  The purpose
5*4882a593Smuzhiyun# of this script is to inflict random OS jitter on a concurrently running
6*4882a593Smuzhiyun# test.
7*4882a593Smuzhiyun#
8*4882a593Smuzhiyun# Usage: jitter.sh me duration [ sleepmax [ spinmax ] ]
9*4882a593Smuzhiyun#
10*4882a593Smuzhiyun# me: Random-number-generator seed salt.
11*4882a593Smuzhiyun# duration: Time to run in seconds.
12*4882a593Smuzhiyun# sleepmax: Maximum microseconds to sleep, defaults to one second.
13*4882a593Smuzhiyun# spinmax: Maximum microseconds to spin, defaults to one millisecond.
14*4882a593Smuzhiyun#
15*4882a593Smuzhiyun# Copyright (C) IBM Corporation, 2016
16*4882a593Smuzhiyun#
17*4882a593Smuzhiyun# Authors: Paul E. McKenney <paulmck@linux.ibm.com>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyunme=$(($1 * 1000))
20*4882a593Smuzhiyunduration=$2
21*4882a593Smuzhiyunsleepmax=${3-1000000}
22*4882a593Smuzhiyunspinmax=${4-1000}
23*4882a593Smuzhiyun
24*4882a593Smuzhiyunn=1
25*4882a593Smuzhiyun
26*4882a593Smuzhiyunstarttime=`gawk 'BEGIN { print systime(); }' < /dev/null`
27*4882a593Smuzhiyun
28*4882a593Smuzhiyunnohotplugcpus=
29*4882a593Smuzhiyunfor i in /sys/devices/system/cpu/cpu[0-9]*
30*4882a593Smuzhiyundo
31*4882a593Smuzhiyun	if test -f $i/online
32*4882a593Smuzhiyun	then
33*4882a593Smuzhiyun		:
34*4882a593Smuzhiyun	else
35*4882a593Smuzhiyun		curcpu=`echo $i | sed -e 's/^[^0-9]*//'`
36*4882a593Smuzhiyun		nohotplugcpus="$nohotplugcpus $curcpu"
37*4882a593Smuzhiyun	fi
38*4882a593Smuzhiyundone
39*4882a593Smuzhiyun
40*4882a593Smuzhiyunwhile :
41*4882a593Smuzhiyundo
42*4882a593Smuzhiyun	# Check for done.
43*4882a593Smuzhiyun	t=`gawk -v s=$starttime 'BEGIN { print systime() - s; }' < /dev/null`
44*4882a593Smuzhiyun	if test "$t" -gt "$duration"
45*4882a593Smuzhiyun	then
46*4882a593Smuzhiyun		exit 0;
47*4882a593Smuzhiyun	fi
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun	# Check for stop request.
50*4882a593Smuzhiyun	if test -f "$TORTURE_STOPFILE"
51*4882a593Smuzhiyun	then
52*4882a593Smuzhiyun		exit 1;
53*4882a593Smuzhiyun	fi
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun	# Set affinity to randomly selected online CPU
56*4882a593Smuzhiyun	if cpus=`grep 1 /sys/devices/system/cpu/*/online 2>&1 |
57*4882a593Smuzhiyun		 sed -e 's,/[^/]*$,,' -e 's/^[^0-9]*//'`
58*4882a593Smuzhiyun	then
59*4882a593Smuzhiyun		:
60*4882a593Smuzhiyun	else
61*4882a593Smuzhiyun		cpus=
62*4882a593Smuzhiyun	fi
63*4882a593Smuzhiyun	# Do not leave out non-hot-pluggable CPUs
64*4882a593Smuzhiyun	cpus="$cpus $nohotplugcpus"
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun	cpumask=`awk -v cpus="$cpus" -v me=$me -v n=$n 'BEGIN {
67*4882a593Smuzhiyun		srand(n + me + systime());
68*4882a593Smuzhiyun		ncpus = split(cpus, ca);
69*4882a593Smuzhiyun		curcpu = ca[int(rand() * ncpus + 1)];
70*4882a593Smuzhiyun		mask = lshift(1, curcpu);
71*4882a593Smuzhiyun		if (mask + 0 <= 0)
72*4882a593Smuzhiyun			mask = 1;
73*4882a593Smuzhiyun		printf("%#x\n", mask);
74*4882a593Smuzhiyun	}' < /dev/null`
75*4882a593Smuzhiyun	n=$(($n+1))
76*4882a593Smuzhiyun	if ! taskset -p $cpumask $$ > /dev/null 2>&1
77*4882a593Smuzhiyun	then
78*4882a593Smuzhiyun		echo taskset failure: '"taskset -p ' $cpumask $$ '"'
79*4882a593Smuzhiyun		exit 1
80*4882a593Smuzhiyun	fi
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun	# Sleep a random duration
83*4882a593Smuzhiyun	sleeptime=`awk -v me=$me -v n=$n -v sleepmax=$sleepmax 'BEGIN {
84*4882a593Smuzhiyun		srand(n + me + systime());
85*4882a593Smuzhiyun		printf("%06d", int(rand() * sleepmax));
86*4882a593Smuzhiyun	}' < /dev/null`
87*4882a593Smuzhiyun	n=$(($n+1))
88*4882a593Smuzhiyun	sleep .$sleeptime
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun	# Spin a random duration
91*4882a593Smuzhiyun	limit=`awk -v me=$me -v n=$n -v spinmax=$spinmax 'BEGIN {
92*4882a593Smuzhiyun		srand(n + me + systime());
93*4882a593Smuzhiyun		printf("%06d", int(rand() * spinmax));
94*4882a593Smuzhiyun	}' < /dev/null`
95*4882a593Smuzhiyun	n=$(($n+1))
96*4882a593Smuzhiyun	for i in {1..$limit}
97*4882a593Smuzhiyun	do
98*4882a593Smuzhiyun		echo > /dev/null
99*4882a593Smuzhiyun	done
100*4882a593Smuzhiyundone
101*4882a593Smuzhiyun
102*4882a593Smuzhiyunexit 1
103