Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull RCU updates from Ingo Molnar: - updates to the handling of expedited grace periods - updates to reduce lock contention in the rcu_node combining tree [ These are in preparation for the consolidation of RCU-bh, RCU-preempt, and RCU-sched into a single flavor, which was requested by Linus in response to a security flaw whose root cause included confusion between the multiple flavors of RCU ] - torture-test updates that save their users some time and effort - miscellaneous fixes * 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits) rcu/x86: Provide early rcu_cpu_starting() callback torture: Make kvm-find-errors.sh find build warnings rcutorture: Abbreviate kvm.sh summary lines rcutorture: Print end-of-test state in kvm.sh summary rcutorture: Print end-of-test state torture: Fold parse-torture.sh into parse-console.sh torture: Add a script to edit output from failed runs rcu: Update list of rcu_future_grace_period() trace events rcu: Drop early GP request check from rcu_gp_kthread() rcu: Simplify and inline cpu_needs_another_gp() rcu: The rcu_gp_cleanup() function does not need cpu_needs_another_gp() rcu: Make rcu_start_this_gp() check for out-of-range requests rcu: Add funnel locking to rcu_start_this_gp() rcu: Make rcu_start_future_gp() caller select grace period rcu: Inline rcu_start_gp_advanced() into rcu_start_future_gp() rcu: Clear request other than RCU_GP_FLAG_INIT at GP end rcu: Cleanup, don't put ->completed into an int rcu: Switch __rcu_process_callbacks() to rcu_accelerate_cbs() rcu: Avoid __call_rcu_core() root rcu_node ->lock acquisition rcu: Make rcu_migrate_callbacks wake GP kthread when needed ...
This commit is contained in:
56
tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh
Executable file
56
tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Invoke a text editor on all console.log files for all runs with diagnostics,
|
||||
# that is, on all such files having a console.log.diags counterpart.
|
||||
# Note that both console.log.diags and console.log are passed to the
|
||||
# editor (currently defaulting to "vi"), allowing the user to get an
|
||||
# idea of what to search for in the console.log file.
|
||||
#
|
||||
# Usage: kvm-find-errors.sh directory
|
||||
#
|
||||
# The "directory" above should end with the date/time directory, for example,
|
||||
# "tools/testing/selftests/rcutorture/res/2018.02.25-14:27:27".
|
||||
|
||||
rundir="${1}"
|
||||
if test -z "$rundir" -o ! -d "$rundir"
|
||||
then
|
||||
echo Usage: $0 directory
|
||||
fi
|
||||
editor=${EDITOR-vi}
|
||||
|
||||
# Find builds with errors
|
||||
files=
|
||||
for i in ${rundir}/*/Make.out
|
||||
do
|
||||
if egrep -q "error:|warning:" < $i
|
||||
then
|
||||
egrep "error:|warning:" < $i > $i.diags
|
||||
files="$files $i.diags $i"
|
||||
fi
|
||||
done
|
||||
if test -n "$files"
|
||||
then
|
||||
$editor $files
|
||||
else
|
||||
echo No build errors.
|
||||
fi
|
||||
if grep -q -e "--buildonly" < ${rundir}/log
|
||||
then
|
||||
echo Build-only run, no console logs to check.
|
||||
fi
|
||||
|
||||
# Find console logs with errors
|
||||
files=
|
||||
for i in ${rundir}/*/console.log
|
||||
do
|
||||
if test -r $i.diags
|
||||
then
|
||||
files="$files $i.diags $i"
|
||||
fi
|
||||
done
|
||||
if test -n "$files"
|
||||
then
|
||||
$editor $files
|
||||
else
|
||||
echo No errors in console logs.
|
||||
fi
|
@@ -34,11 +34,15 @@ fi
|
||||
|
||||
configfile=`echo $i | sed -e 's/^.*\///'`
|
||||
ngps=`grep ver: $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* ver: //' -e 's/ .*$//'`
|
||||
stopstate="`grep 'End-test grace-period state: g' $i/console.log 2> /dev/null |
|
||||
tail -1 | sed -e 's/^\[[ 0-9.]*] //' |
|
||||
awk '{ print \"[\" $1 \" \" $5 \" \" $6 \" \" $7 \"]\"; }' |
|
||||
tr -d '\012\015'`"
|
||||
if test -z "$ngps"
|
||||
then
|
||||
echo "$configfile -------"
|
||||
echo "$configfile ------- " $stopstate
|
||||
else
|
||||
title="$configfile ------- $ngps grace periods"
|
||||
title="$configfile ------- $ngps GPs"
|
||||
dur=`sed -e 's/^.* rcutorture.shutdown_secs=//' -e 's/ .*$//' < $i/qemu-cmd 2> /dev/null`
|
||||
if test -z "$dur"
|
||||
then
|
||||
@@ -46,9 +50,9 @@ else
|
||||
else
|
||||
ngpsps=`awk -v ngps=$ngps -v dur=$dur '
|
||||
BEGIN { print ngps / dur }' < /dev/null`
|
||||
title="$title ($ngpsps per second)"
|
||||
title="$title ($ngpsps/s)"
|
||||
fi
|
||||
echo $title
|
||||
echo $title $stopstate
|
||||
nclosecalls=`grep --binary-files=text 'torture: Reader Batch' $i/console.log | tail -1 | awk '{for (i=NF-8;i<=NF;i++) sum+=$i; } END {print sum}'`
|
||||
if test -z "$nclosecalls"
|
||||
then
|
||||
|
@@ -48,10 +48,6 @@ do
|
||||
cat $i/Make.oldconfig.err
|
||||
fi
|
||||
parse-build.sh $i/Make.out $configfile
|
||||
if test "$TORTURE_SUITE" != rcuperf
|
||||
then
|
||||
parse-torture.sh $i/console.log $configfile
|
||||
fi
|
||||
parse-console.sh $i/console.log $configfile
|
||||
if test -r $i/Warnings
|
||||
then
|
||||
|
@@ -267,5 +267,4 @@ then
|
||||
echo Unknown PID, cannot kill qemu command
|
||||
fi
|
||||
|
||||
parse-torture.sh $resdir/console.log $title
|
||||
parse-console.sh $resdir/console.log $title
|
||||
|
@@ -24,57 +24,146 @@
|
||||
#
|
||||
# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||
|
||||
T=${TMPDIR-/tmp}/parse-console.sh.$$
|
||||
file="$1"
|
||||
title="$2"
|
||||
|
||||
trap 'rm -f $T.seq $T.diags' 0
|
||||
|
||||
. functions.sh
|
||||
|
||||
# Check for presence and readability of console output file
|
||||
if test -f "$file" -a -r "$file"
|
||||
then
|
||||
:
|
||||
else
|
||||
echo $title unreadable console output file: $file
|
||||
exit 1
|
||||
fi
|
||||
if grep -Pq '\x00' < $file
|
||||
then
|
||||
print_warning Console output contains nul bytes, old qemu still running?
|
||||
fi
|
||||
egrep 'Badness|WARNING:|Warn|BUG|===========|Call Trace:|Oops:|detected stalls on CPUs/tasks:|self-detected stall on CPU|Stall ended before state dump start|\?\?\? Writer stall state|rcu_.*kthread starved for' < $file | grep -v 'ODEBUG: ' | grep -v 'Warning: unable to open an initial console' > $1.diags
|
||||
if test -s $1.diags
|
||||
cat /dev/null > $file.diags
|
||||
|
||||
# Check for proper termination, except that rcuperf runs don't indicate this.
|
||||
if test "$TORTURE_SUITE" != rcuperf
|
||||
then
|
||||
print_warning Assertion failure in $file $title
|
||||
# cat $1.diags
|
||||
# check for abject failure
|
||||
|
||||
if grep -q FAILURE $file || grep -q -e '-torture.*!!!' $file
|
||||
then
|
||||
nerrs=`grep --binary-files=text '!!!' $file |
|
||||
tail -1 |
|
||||
awk '
|
||||
{
|
||||
for (i=NF-8;i<=NF;i++)
|
||||
sum+=$i;
|
||||
}
|
||||
END { print sum }'`
|
||||
print_bug $title FAILURE, $nerrs instances
|
||||
exit
|
||||
fi
|
||||
|
||||
grep --binary-files=text 'torture:.*ver:' $file |
|
||||
egrep --binary-files=text -v '\(null\)|rtc: 000000000* ' |
|
||||
sed -e 's/^(initramfs)[^]]*] //' -e 's/^\[[^]]*] //' |
|
||||
awk '
|
||||
BEGIN {
|
||||
ver = 0;
|
||||
badseq = 0;
|
||||
}
|
||||
|
||||
{
|
||||
if (!badseq && ($5 + 0 != $5 || $5 <= ver)) {
|
||||
badseqno1 = ver;
|
||||
badseqno2 = $5;
|
||||
badseqnr = NR;
|
||||
badseq = 1;
|
||||
}
|
||||
ver = $5
|
||||
}
|
||||
|
||||
END {
|
||||
if (badseq) {
|
||||
if (badseqno1 == badseqno2 && badseqno2 == ver)
|
||||
print "GP HANG at " ver " torture stat " badseqnr;
|
||||
else
|
||||
print "BAD SEQ " badseqno1 ":" badseqno2 " last:" ver " version " badseqnr;
|
||||
}
|
||||
}' > $T.seq
|
||||
|
||||
if grep -q SUCCESS $file
|
||||
then
|
||||
if test -s $T.seq
|
||||
then
|
||||
print_warning $title `cat $T.seq`
|
||||
echo " " $file
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
if grep -q "_HOTPLUG:" $file
|
||||
then
|
||||
print_warning HOTPLUG FAILURES $title `cat $T.seq`
|
||||
echo " " $file
|
||||
exit 3
|
||||
fi
|
||||
echo $title no success message, `grep --binary-files=text 'ver:' $file | wc -l` successful version messages
|
||||
if test -s $T.seq
|
||||
then
|
||||
print_warning $title `cat $T.seq`
|
||||
fi
|
||||
exit 2
|
||||
fi
|
||||
fi | tee -a $file.diags
|
||||
|
||||
egrep 'Badness|WARNING:|Warn|BUG|===========|Call Trace:|Oops:|detected stalls on CPUs/tasks:|self-detected stall on CPU|Stall ended before state dump start|\?\?\? Writer stall state|rcu_.*kthread starved for' < $file |
|
||||
grep -v 'ODEBUG: ' |
|
||||
grep -v 'Warning: unable to open an initial console' > $T.diags
|
||||
if test -s $T.diags
|
||||
then
|
||||
print_warning "Assertion failure in $file $title"
|
||||
# cat $T.diags
|
||||
summary=""
|
||||
n_badness=`grep -c Badness $1`
|
||||
n_badness=`grep -c Badness $file`
|
||||
if test "$n_badness" -ne 0
|
||||
then
|
||||
summary="$summary Badness: $n_badness"
|
||||
fi
|
||||
n_warn=`grep -v 'Warning: unable to open an initial console' $1 | egrep -c 'WARNING:|Warn'`
|
||||
n_warn=`grep -v 'Warning: unable to open an initial console' $file | egrep -c 'WARNING:|Warn'`
|
||||
if test "$n_warn" -ne 0
|
||||
then
|
||||
summary="$summary Warnings: $n_warn"
|
||||
fi
|
||||
n_bugs=`egrep -c 'BUG|Oops:' $1`
|
||||
n_bugs=`egrep -c 'BUG|Oops:' $file`
|
||||
if test "$n_bugs" -ne 0
|
||||
then
|
||||
summary="$summary Bugs: $n_bugs"
|
||||
fi
|
||||
n_calltrace=`grep -c 'Call Trace:' $1`
|
||||
n_calltrace=`grep -c 'Call Trace:' $file`
|
||||
if test "$n_calltrace" -ne 0
|
||||
then
|
||||
summary="$summary Call Traces: $n_calltrace"
|
||||
fi
|
||||
n_lockdep=`grep -c =========== $1`
|
||||
n_lockdep=`grep -c =========== $file`
|
||||
if test "$n_badness" -ne 0
|
||||
then
|
||||
summary="$summary lockdep: $n_badness"
|
||||
fi
|
||||
n_stalls=`egrep -c 'detected stalls on CPUs/tasks:|self-detected stall on CPU|Stall ended before state dump start|\?\?\? Writer stall state' $1`
|
||||
n_stalls=`egrep -c 'detected stalls on CPUs/tasks:|self-detected stall on CPU|Stall ended before state dump start|\?\?\? Writer stall state' $file`
|
||||
if test "$n_stalls" -ne 0
|
||||
then
|
||||
summary="$summary Stalls: $n_stalls"
|
||||
fi
|
||||
n_starves=`grep -c 'rcu_.*kthread starved for' $1`
|
||||
n_starves=`grep -c 'rcu_.*kthread starved for' $file`
|
||||
if test "$n_starves" -ne 0
|
||||
then
|
||||
summary="$summary Starves: $n_starves"
|
||||
fi
|
||||
print_warning Summary: $summary
|
||||
else
|
||||
rm $1.diags
|
||||
cat $T.diags >> $file.diags
|
||||
fi
|
||||
if ! test -s $file.diags
|
||||
then
|
||||
rm -f $file.diags
|
||||
fi
|
||||
|
@@ -1,105 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Check the console output from a torture run for goodness.
|
||||
# The "file" is a pathname on the local system, and "title" is
|
||||
# a text string for error-message purposes.
|
||||
#
|
||||
# The file must contain torture output, but can be interspersed
|
||||
# with other dmesg text, as in console-log output.
|
||||
#
|
||||
# Usage: parse-torture.sh file title
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
# Copyright (C) IBM Corporation, 2011
|
||||
#
|
||||
# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||
|
||||
T=${TMPDIR-/tmp}/parse-torture.sh.$$
|
||||
file="$1"
|
||||
title="$2"
|
||||
|
||||
trap 'rm -f $T.seq' 0
|
||||
|
||||
. functions.sh
|
||||
|
||||
# check for presence of torture output file.
|
||||
|
||||
if test -f "$file" -a -r "$file"
|
||||
then
|
||||
:
|
||||
else
|
||||
echo $title unreadable torture output file: $file
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check for abject failure
|
||||
|
||||
if grep -q FAILURE $file || grep -q -e '-torture.*!!!' $file
|
||||
then
|
||||
nerrs=`grep --binary-files=text '!!!' $file | tail -1 | awk '{for (i=NF-8;i<=NF;i++) sum+=$i; } END {print sum}'`
|
||||
print_bug $title FAILURE, $nerrs instances
|
||||
echo " " $url
|
||||
exit
|
||||
fi
|
||||
|
||||
grep --binary-files=text 'torture:.*ver:' $file | egrep --binary-files=text -v '\(null\)|rtc: 000000000* ' | sed -e 's/^(initramfs)[^]]*] //' -e 's/^\[[^]]*] //' |
|
||||
awk '
|
||||
BEGIN {
|
||||
ver = 0;
|
||||
badseq = 0;
|
||||
}
|
||||
|
||||
{
|
||||
if (!badseq && ($5 + 0 != $5 || $5 <= ver)) {
|
||||
badseqno1 = ver;
|
||||
badseqno2 = $5;
|
||||
badseqnr = NR;
|
||||
badseq = 1;
|
||||
}
|
||||
ver = $5
|
||||
}
|
||||
|
||||
END {
|
||||
if (badseq) {
|
||||
if (badseqno1 == badseqno2 && badseqno2 == ver)
|
||||
print "GP HANG at " ver " torture stat " badseqnr;
|
||||
else
|
||||
print "BAD SEQ " badseqno1 ":" badseqno2 " last:" ver " version " badseqnr;
|
||||
}
|
||||
}' > $T.seq
|
||||
|
||||
if grep -q SUCCESS $file
|
||||
then
|
||||
if test -s $T.seq
|
||||
then
|
||||
print_warning $title $title `cat $T.seq`
|
||||
echo " " $file
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
if grep -q "_HOTPLUG:" $file
|
||||
then
|
||||
print_warning HOTPLUG FAILURES $title `cat $T.seq`
|
||||
echo " " $file
|
||||
exit 3
|
||||
fi
|
||||
echo $title no success message, `grep --binary-files=text 'ver:' $file | wc -l` successful version messages
|
||||
if test -s $T.seq
|
||||
then
|
||||
print_warning $title `cat $T.seq`
|
||||
fi
|
||||
exit 2
|
||||
fi
|
Reference in New Issue
Block a user