]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
rcutorture: Make initrd/init execute in userspace
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Thu, 23 Aug 2018 22:23:23 +0000 (15:23 -0700)
committerPaul E. McKenney <paulmck@linux.ibm.com>
Fri, 9 Nov 2018 05:52:55 +0000 (21:52 -0800)
Currently, the initrd/init script and executable remain blocked almost
all the time.  However, it is necessary to test nohz_full userspace
execution, which both variants of initrd/init fail to do.  This commit
therefore causes initrd/init to spend about a millisecond per second
executing in userspace.

Reported-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
tools/testing/selftests/rcutorture/bin/mkinitrd.sh

index 87a87ffeaa85a15b464f310de9ca4e1515ceafd5..b48c504edfe12de01a66abc13df5078892401e8e 100755 (executable)
@@ -39,9 +39,22 @@ mkdir $T
 
 cat > $T/init << '__EOF___'
 #!/bin/sh
+# Run in userspace a few milliseconds every second.  This helps to
+# exercise the NO_HZ_FULL portions of RCU.
 while :
 do
-       sleep 1000000
+       q=
+       for i in \
+               a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \
+               a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \
+               a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \
+               a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \
+               a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \
+               a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
+       do
+               q="$q $i"
+       done
+       sleep 1
 done
 __EOF___
 
@@ -70,15 +83,37 @@ mkdir initrd
 cd initrd
 cat > init.c << '___EOF___'
 #include <unistd.h>
+#include <sys/time.h>
+
+volatile unsigned long delaycount;
 
 int main(int argc, int argv[])
 {
-       for (;;)
-               sleep(1000*1000*1000); /* One gigasecond is ~30 years. */
+       int i;
+       struct timeval tv;
+       struct timeval tvb;
+
+       for (;;) {
+               sleep(1);
+               /* Need some userspace time. */
+               if (gettimeofday(&tvb, NULL))
+                       continue;
+               do {
+                       for (i = 0; i < 1000 * 100; i++)
+                               delaycount = i * i;
+                       if (gettimeofday(&tv, NULL))
+                               break;
+                       tv.tv_sec -= tvb.tv_sec;
+                       if (tv.tv_sec > 1)
+                               break;
+                       tv.tv_usec += tv.tv_sec * 1000 * 1000;
+                       tv.tv_usec -= tvb.tv_usec;
+               } while (tv.tv_usec < 1000);
+       }
        return 0;
 }
 ___EOF___
-gcc -static -Os -o init init.c
+cc -static -Os -o init init.c
 strip init
 rm init.c
 echo "Done creating a statically linked C-language initrd"