Waketorture, not for inclusion
Subsystems (4)
cover Waketorture, not for inclusion
Hello!
And for your amusement, this series provides a waketorture module. It is intended to increase the probability of a heisenbug or three I have been chasing for longer than I care to admit. Should it someday actually significantly increase that probability, I might consider submitting it for acceptance. In the meantime, for your amusement:
1. Add a wakeup-torture module.
2. Update scripting to accommodate waketorture.
3. Don't kick kthreads unless grace period or request.
4. Add utilization measurement.
5. Add hrtimer support for fine-grained event scheduling.
6. Make waketorture always hotplug the same CPU.
7. Make waketorture kill test if no hotpluggable CPUs.
8. Affinity waiter tasks away from hotpluggable CPU.
Thanx, Paul
------------------------------------------------------------------------
kernel/rcu/Makefile | 3 kernel/rcu/tree.c | 3 kernel/rcu/waketorture.c | 567 +++++++++- lib/Kconfig.debug | 18 tools/testing/selftests/rcutorture/bin/kvm-recheck-wake.sh | 39 tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | 2 tools/testing/selftests/rcutorture/bin/kvm.sh | 2 tools/testing/selftests/rcutorture/configs/wake/CFLIST | 1 tools/testing/selftests/rcutorture/configs/wake/CFcommon | 2 tools/testing/selftests/rcutorture/configs/wake/SH | 19 tools/testing/selftests/rcutorture/configs/wake/SH.boot | 1 tools/testing/selftests/rcutorture/configs/wake/STI | 19 tools/testing/selftests/rcutorture/configs/wake/STI.boot | 1 tools/testing/selftests/rcutorture/configs/wake/ver_functions.sh | 43 14 files changed, 701 insertions(+), 19 deletions(-)
PATCH 1/8 waketorture: Add a wakeup-torture module
This commit adds a wakeup-torture module to assist tracking down an elusive lost-wakeup problem.
--- kernel/rcu/Makefile | 3 +- kernel/rcu/waketorture.c | 371 +++++++++++++++++++++++++++++++++++++++++++++++ lib/Kconfig.debug | 17 +++ 3 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 kernel/rcu/waketorture.c
kernel/rcu/Makefile +2 -1
@@ -4,9 +4,10 @@ KCOV_INSTRUMENT := n obj-y += update.o sync.o obj-$(CONFIG_SRCU) += srcu.o -obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o obj-$(CONFIG_RCU_PERF_TEST) += rcuperf.o +obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o obj-$(CONFIG_TREE_RCU) += tree.o obj-$(CONFIG_PREEMPT_RCU) += tree.o obj-$(CONFIG_TREE_RCU_TRACE) += tree_trace.o obj-$(CONFIG_TINY_RCU) += tiny.o +obj-$(CONFIG_WAKE_TORTURE_TEST) += waketorture.o
kernel/rcu/waketorture.c new file +371 -0
371 lines not on this page · raw message
lib/Kconfig.debug +17 -0
@@ -1399,6 +1399,23 @@ config RCU_TORTURE_TEST_SLOW_CLEANUP_DELAY This option specifies the number of jiffies to wait between each rcu_node structure cleanup operation. +config WAKE_TORTURE_TEST + tristate "Torture test for wakeups and CPU hotplug" + depends on DEBUG_KERNEL + depends on 64BIT + select TORTURE_TEST + default n + help + This option provides a kernel module that runs torture tests + on wakeups from timed waits in the presence of CPU hotplug. + The kernel module may be built after the fact on the running + kernel to be tested, if desired. + + Say Y here if you want wakeup torture tests to be built into + the kernel. + Say M if you want the wakeup torture tests to build as a module. + Say N if you are unsure. + config RCU_CPU_STALL_TIMEOUT int "RCU CPU stall timeout in seconds" depends on RCU_STALL_COMMON
Signature · 1 line
2.5.2
PATCH 2/8 waketorture: Update scripting to accommodate waketorture
In reply to Paul E. McKenneyThis commit adds the scripting changes to add support for the shiny new waketorture kernel module.
--- .../selftests/rcutorture/bin/kvm-recheck-wake.sh | 39 ++++++++++++++++++++ .../selftests/rcutorture/bin/kvm-recheck.sh | 2 +- tools/testing/selftests/rcutorture/bin/kvm.sh | 2 +- .../selftests/rcutorture/configs/wake/CFLIST | 1 + .../selftests/rcutorture/configs/wake/CFcommon | 2 + .../testing/selftests/rcutorture/configs/wake/STI | 19 ++++++++++ .../selftests/rcutorture/configs/wake/STI.boot | 1 + .../rcutorture/configs/wake/ver_functions.sh | 43 ++++++++++++++++++++++ 8 files changed, 107 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/rcutorture/bin/kvm-recheck-wake.sh create mode 100644 tools/testing/selftests/rcutorture/configs/wake/CFLIST create mode 100644 tools/testing/selftests/rcutorture/configs/wake/CFcommon create mode 100644 tools/testing/selftests/rcutorture/configs/wake/STI create mode 100644 tools/testing/selftests/rcutorture/configs/wake/STI.boot create mode 100644 tools/testing/selftests/rcutorture/configs/wake/ver_functions.sh
tools/testing/selftests/rcutorture/bin/kvm-recheck-wake.sh new file +39 -0
@@ -0,0 +1,39 @@ +#!/bin/bash +# +# Analyze a given results directory for waketorture diagnostics. +# +# Usage: kvm-recheck-wake resdir +# +# 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, 2016 +# +# Authors: Paul E. McKenney <[email protected]> + +i="$1" +if test -d $i +then + : +else + echo Unreadable results directory: $i + exit 1 +fi +PATH=`pwd`/tools/testing/selftests/rcutorture/bin:$PATH; export PATH +. tools/testing/selftests/rcutorture/bin/functions.sh + +configfile=`echo $i | sed -e 's/^.*\///'` + +sed -e 's/^\[[^]]*]//' < $i/console.log | grep -e -torture | + grep "Tardy kthreads" | tail -1
tools/testing/selftests/rcutorture/bin/kvm-recheck.sh +1 -1
@@ -48,7 +48,7 @@ do cat $i/Make.oldconfig.err fi parse-build.sh $i/Make.out $configfile - if test "$TORTURE_SUITE" != rcuperf + if test "$TORTURE_SUITE" != rcuperf -a "$TORTURE_SUITE" != wake then parse-torture.sh $i/console.log $configfile fi
tools/testing/selftests/rcutorture/bin/kvm.sh +1 -1
@@ -163,7 +163,7 @@ do shift ;; --torture) - checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\|rcuperf\)$' '^--' + checkarg --torture "(suite name)" "$#" "$2" '^\(lock\|rcu\|rcuperf\|wake\)$' '^--' TORTURE_SUITE=$2 shift ;;
tools/testing/selftests/rcutorture/configs/wake/CFLIST new file +1 -0
@@ -0,0 +1 @@ +STI
tools/testing/selftests/rcutorture/configs/wake/CFcommon new file +2 -0
@@ -0,0 +1,2 @@ +CONFIG_WAKE_TORTURE_TEST=y +CONFIG_PRINTK_TIME=y
tools/testing/selftests/rcutorture/configs/wake/STI new file +19 -0
@@ -0,0 +1,19 @@ +CONFIG_SMP=y +CONFIG_NR_CPUS=16 +CONFIG_PREEMPT_NONE=n +CONFIG_PREEMPT_VOLUNTARY=n +CONFIG_PREEMPT=y +#CHECK#CONFIG_PREEMPT_RCU=y +CONFIG_HZ_PERIODIC=y +CONFIG_NO_HZ_IDLE=n +CONFIG_NO_HZ_FULL=n +CONFIG_RCU_TRACE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_RCU_FANOUT=2 +CONFIG_RCU_FANOUT_LEAF=2 +CONFIG_RCU_NOCB_CPU=n +CONFIG_DEBUG_LOCK_ALLOC=n +CONFIG_RCU_BOOST=y +CONFIG_RCU_KTHREAD_PRIO=2 +CONFIG_DEBUG_OBJECTS_RCU_HEAD=n +CONFIG_RCU_EXPERT=y
tools/testing/selftests/rcutorture/configs/wake/STI.boot new file +1 -0
@@ -0,0 +1 @@ +rcupdate.rcu_expedited waketorture.torture_type=sti
tools/testing/selftests/rcutorture/configs/wake/ver_functions.sh new file +43 -0
43 lines not on this page · raw message
Signature · 1 line
2.5.2
PATCH 3/8 waketorture: Don't kick unless grace period or request
In reply to Paul E. McKenneyThe current code can result in spurious kicks when there are no grace periods in progress and no grace-period-related requests. This is sort of OK for a diagnostic aid, but the resulting ftrace-dump messages in dmesg are annoying. This commit therefore avoids spurious kicks in the common case.
--- kernel/rcu/tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/rcu/tree.c +2 -1
@@ -1306,7 +1306,8 @@ static void rcu_stall_kick_kthreads(struct rcu_state *rsp)if (!rcu_kick_kthreads)return ; j =READ_ONCE (rsp->jiffies_kick_kthreads); -if (time_after (jiffies, j) && rsp->gp_kthread) { +if (time_after (jiffies, j) && rsp->gp_kthread && + (rcu_gp_in_progress (rsp) ||READ_ONCE (rsp->gp_flags))) {WARN_ONCE (1 ,"Kicking %s grace-period kthread\n" , rsp->name);rcu_ftrace_dump (DUMP_ALL );wake_up_process (rsp->gp_kthread);
Signature · 1 line
2.5.2
PATCH 4/8 waketorture: Add utilization measurement
In reply to Paul E. McKenney--- kernel/rcu/waketorture.c | 29 ++++++++++++++++++++++++++++- lib/Kconfig.debug | 1 + 2 files changed, 29 insertions(+), 1 deletion(-)
kernel/rcu/waketorture.c +28 -1
@@ -81,7 +81,9 @@ static unsigned long *waiter_iter; /* Number of wait iterations. */static bool *waiter_cts;/* Waiter already checked. */ static unsigned long *waiter_kicks;/* Number of waiter starvations. */ static unsigned long *waiter_ts;/* Jiffies last run. */ -DEFINE_MUTEX (waiter_mutex); +static DEFINE_MUTEX (waiter_mutex); +static DEFINE_PER_CPU(u64, waiter_cputime); /* Nanoseconds. */ +static u64 starttime;static int torture_runnable =IS_ENABLED (MODULE );module_param (torture_runnable, int,0444 );
@@ -133,16 +135,23 @@ static int wake_torture_waiter(void *arg) { int i; long me = (long)arg; + u64 ts; VERBOSE_TOROUT_STRING("wake_torture_waiter task started"); set_user_nice(current, MAX_NICE); + preempt_disable(); + ts = trace_clock_local(); do { waiter_ts[me] = jiffies; smp_mb(); /* Ensure waiter_ts[] written before waiter_cts[]. */ /* Pairs with [A]. */ waiter_cts[me] = false; + __this_cpu_add(waiter_cputime, trace_clock_local() - ts); + preempt_enable(); cur_ops->wait(wait_duration); + preempt_disable(); + ts = trace_clock_local(); waiter_iter[me]++; for (i = 0; i < nrealwaiters; i++) { if (waiter_done[i] ||
@@ -164,8 +173,14 @@ static int wake_torture_waiter(void *arg)mutex_unlock (&waiter_mutex); } } +__this_cpu_add (waiter_cputime,trace_clock_local () - ts); +preempt_enable ();torture_shutdown_absorb ("wake_torture_waiter" ); +preempt_disable (); + ts =trace_clock_local (); }while (!torture_must_stop ()); +__this_cpu_add (waiter_cputime,trace_clock_local () - ts); +preempt_enable ();mutex_lock (&waiter_mutex); waiter_done[me] = true;mutex_unlock (&waiter_mutex);
@@ -189,6 +204,8 @@ wake_torture_stats_print(void) {int i;bool tardy = false; +u64 timediff; +u64 timetot;if (!waiter_done || !waiter_iter || !waiter_cts || !waiter_kicks || !waiter_ts) {
@@ -212,6 +229,15 @@ wake_torture_stats_print(void)pr_cont ("\n" ); else TOROUT_STRING(" No tardy kthreads"); + timediff = (trace_clock_global () - starttime) /1000 ; + timetot =0 ; +for_each_possible_cpu (i) + timetot +=READ_ONCE (per_cpu (waiter_cputime, i)); + timetot /= nr_cpu_ids; + timetot /= timediff; +pr_alert ("%s" TORTURE_FLAG " timediff: %llu utilization: %llu.%llu nr_cpu_ids: %d\n" , + torture_type, timediff, + timetot /1000ULL , timetot %1000ULL , nr_cpu_ids); }/*
@@ -290,6 +316,7 @@ wake_torture_init(void)if (!torture_init_begin (torture_type, verbose, &torture_runnable))return -EBUSY ; + starttime =trace_clock_global ();/* Process args and tell the world that the torturer is on the job. */ for (i =0 ; i <ARRAY_SIZE (torture_ops); i++) {
lib/Kconfig.debug +1 -0
@@ -1403,6 +1403,7 @@ config WAKE_TORTURE_TEST tristate "Torture test for wakeups and CPU hotplug" depends on DEBUG_KERNEL depends on 64BIT + depends on TRACE_CLOCK select TORTURE_TEST default n help
Signature · 1 line
2.5.2
PATCH 5/8 waketorture: Add hrtimer support
In reply to Paul E. McKenney--- kernel/rcu/waketorture.c | 50 ++++++++++++++++++---- tools/testing/selftests/rcutorture/configs/wake/SH | 19 ++++++++ .../selftests/rcutorture/configs/wake/SH.boot | 1 + 3 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 tools/testing/selftests/rcutorture/configs/wake/SH create mode 100644 tools/testing/selftests/rcutorture/configs/wake/SH.boot
kernel/rcu/waketorture.c +41 -9
@@ -62,12 +62,12 @@ torture_param(int, stat_interval, 60, "Number of seconds between stats printk()s");torture_param (bool, verbose, true,"Enable verbose debugging printk()s" ); -torture_param (int, wait_duration,3 , -"Number of jiffies to wait each iteration" ); +torture_param (int, wait_duration,127 , +"Number of microseconds to wait each iteration" );torture_param (int, wait_grace,20 ,"Number of jiffies before complaining about long wait" ); -static char *torture_type ="sti" ; +static char *torture_type ="sh" ;module_param (torture_type, charp,0444 );MODULE_PARM_DESC (torture_type,"Type of wait to torture (sti, stui, ...)" );
@@ -94,18 +94,40 @@ MODULE_PARM_DESC(torture_runnable, "Start waketorture at boot");*/ struct wake_torture_ops { -signed long (*wait)(signed long timeout); +void (*wait)(void );const char *name; };static struct wake_torture_ops *cur_ops;/* +* Definitions for schedule_hrtimeout() torture testing. +*/ + +static void wait_schedule_hrtimeout (void ) +{ +ktime_t wait =ns_to_ktime (wait_duration *1000 ); + +set_current_state (TASK_UNINTERRUPTIBLE ); +schedule_hrtimeout (&wait,HRTIMER_MODE_REL ); +} + +static struct wake_torture_ops sh_ops = { + .wait = wait_schedule_hrtimeout, + .name ="sh" +}; + +/* * Definitions for schedule_timeout_interruptible() torture testing. */ +static void wait_schedule_timeout_interruptible (void ) +{ +schedule_timeout_interruptible ((wait_duration +999 ) /1000 ); +} +static struct wake_torture_ops sti_ops = { - .wait = schedule_timeout_interruptible, + .wait = wait_schedule_timeout_interruptible, .name ="sti" };
@@ -113,8 +135,13 @@ static struct wake_torture_ops sti_ops = {* Definitions for schedule_timeout_uninterruptible() torture testing. */ +static void wait_schedule_timeout_uninterruptible (void ) +{ +schedule_timeout_uninterruptible ((wait_duration +999 ) /1000 ); +} +static struct wake_torture_ops stui_ops = { - .wait = schedule_timeout_uninterruptible, + .wait = wait_schedule_timeout_uninterruptible, .name ="stui" };
@@ -149,7 +176,7 @@ static int wake_torture_waiter(void *arg) waiter_cts[me] = false;__this_cpu_add (waiter_cputime,trace_clock_local () - ts);preempt_enable (); - cur_ops->wait (wait_duration); + cur_ops->wait ();preempt_disable (); ts =trace_clock_local (); waiter_iter[me]++;
@@ -167,7 +194,10 @@ static int wake_torture_waiter(void *arg) }else { waiter_cts[i] = true; waiter_kicks[i]++; -pr_alert ("%s%s wake_torture_waiter(): P%d failing to awaken!\n" , torture_type,TORTURE_FLAG , waiter_tasks[i]->pid); +pr_alert ("%s%s wake_torture_waiter(): P%d (%#lx) failing to awaken!\n" , + torture_type,TORTURE_FLAG , + waiter_tasks[i]->pid, + waiter_tasks[i]->state);rcu_ftrace_dump (DUMP_ALL );wake_up_process (waiter_tasks[i]);mutex_unlock (&waiter_mutex);
@@ -312,7 +342,9 @@ wake_torture_init(void) {int i;int firsterr =0 ; -static struct wake_torture_ops *torture_ops[] = { &sti_ops, &stui_ops }; +static struct wake_torture_ops *torture_ops[] = { + &sh_ops, &sti_ops, &stui_ops + };if (!torture_init_begin (torture_type, verbose, &torture_runnable))return -EBUSY ;
tools/testing/selftests/rcutorture/configs/wake/SH new file +19 -0
@@ -0,0 +1,19 @@ +CONFIG_SMP=y +CONFIG_NR_CPUS=16 +CONFIG_PREEMPT_NONE=n +CONFIG_PREEMPT_VOLUNTARY=n +CONFIG_PREEMPT=y +#CHECK#CONFIG_PREEMPT_RCU=y +CONFIG_HZ_PERIODIC=y +CONFIG_NO_HZ_IDLE=n +CONFIG_NO_HZ_FULL=n +CONFIG_RCU_TRACE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_RCU_FANOUT=2 +CONFIG_RCU_FANOUT_LEAF=2 +CONFIG_RCU_NOCB_CPU=n +CONFIG_DEBUG_LOCK_ALLOC=n +CONFIG_RCU_BOOST=y +CONFIG_RCU_KTHREAD_PRIO=2 +CONFIG_DEBUG_OBJECTS_RCU_HEAD=n +CONFIG_RCU_EXPERT=y
tools/testing/selftests/rcutorture/configs/wake/SH.boot new file +1 -0
@@ -0,0 +1 @@ +rcupdate.rcu_expedited waketorture.torture_type=sh
Signature · 1 line
2.5.2
PATCH 6/8 torture: Make waketorture always hotplug the same CPU
In reply to Paul E. McKenneyThis commit causes waketorture to always hotplug the same CPU, namely, the highest-numbered CPU that can be hotplugged. This will be used by later commits to force race conditions with higher probability.
--- kernel/rcu/waketorture.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 3 deletions(-)
kernel/rcu/waketorture.c +85 -3
@@ -74,6 +74,7 @@ MODULE_PARM_DESC(torture_type, "Type of wait to torture (sti, stui, ...)");static int nrealwaiters;static struct task_struct **waiter_tasks;static struct task_struct *stats_task; +static struct task_struct *onoff_task;/* Yes, these cache-thrash, and it is inherent to the concurrency design. */ static bool *waiter_done;/* Waiter is done, don't wake. */
@@ -85,6 +86,18 @@ static DEFINE_MUTEX(waiter_mutex); static DEFINE_PER_CPU(u64, waiter_cputime); /* Nanoseconds. */static u64 starttime; +static int onoff_cpu =-1 ; +static long n_offline_attempts; +static long n_offline_successes; +static unsigned long sum_offline; +static int min_offline =-1 ; +static int max_offline; +static long n_online_attempts; +static long n_online_successes; +static unsigned long sum_online; +static int min_online =-1 ; +static int max_online; +static int torture_runnable =IS_ENABLED (MODULE );module_param (torture_runnable, int,0444 );MODULE_PARM_DESC (torture_runnable,"Start waketorture at boot" );
@@ -219,6 +232,67 @@ static int wake_torture_waiter(void *arg) }/* +* Find a hotpluggable CPU and repeatedly take it online and offline. +*/ +static int wake_torture_onoff (void *args) +{ +int cpu; + +VERBOSE_TOROUT_STRING ("wake_torture_onoff task started" ); +if (onoff_holdoff >0 ) { +VERBOSE_TOROUT_STRING ("wake_torture_onoff begin holdoff" ); +schedule_timeout_interruptible (onoff_holdoff *HZ ); +VERBOSE_TOROUT_STRING ("wake_torture_onoff end holdoff" ); + } +for_each_online_cpu (cpu) { +if (cpu_is_hotpluggable (cpu)) + onoff_cpu = cpu; + } +pr_alert ("%s" TORTURE_FLAG " wake_torture_onoff: onoff_cpu: %d\n" , torture_type, onoff_cpu); +if (onoff_cpu <0 ) +VERBOSE_TOROUT_STRING ("wake_torture_onoff: no hotpluggable CPUs!" ); +while (!torture_must_stop () && onoff_cpu >=0 ) { +if (!torture_offline (onoff_cpu, + &n_offline_attempts, &n_offline_successes, + &sum_offline, &min_offline, &max_offline)) +torture_online (onoff_cpu, + &n_online_attempts, &n_online_successes, + &sum_online, &min_online, &max_online); +schedule_timeout_interruptible (onoff_interval); + } +torture_kthread_stopping ("wake_torture_onoff" ); +return 0 ; +} + +/* +* Initiate waketorture-specific online-offline handling, which +* focuses on a single CPU. +*/ +static int wake_torture_onoff_init (void ) +{ +int ret =0 ; + +if (!IS_ENABLED (CONFIG_HOTPLUG_CPU )) +return ret; +if (onoff_interval <=0 ) +return 0 ; + ret =torture_create_kthread (wake_torture_onoff,NULL , onoff_task); +return ret; +} + +/* +* Clean up after waketorture-specific online-offline handling. +*/ +static void wake_torture_onoff_cleanup (void ) +{ +if (!IS_ENABLED (CONFIG_HOTPLUG_CPU )) +return ; +VERBOSE_TOROUT_STRING ("Stopping wake_torture_onoff task" ); +kthread_stop (onoff_task); + onoff_task =NULL ; +} + +/* * Print torture statistics. Caller must ensure that there is only one * call to this function at a given time!!! This is normally accomplished * by relying on the module system to only have one copy of the module
@@ -265,9 +339,14 @@ wake_torture_stats_print(void) timetot +=READ_ONCE (per_cpu (waiter_cputime, i)); timetot /= nr_cpu_ids; timetot /= timediff; -pr_alert ("%s" TORTURE_FLAG " timediff: %llu utilization: %llu.%llu nr_cpu_ids: %d\n" , +pr_alert ("%s" TORTURE_FLAG " timediff: %llu utilization: %llu.%llu nr_cpu_ids: %d onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d)\n" , torture_type, timediff, - timetot /1000ULL , timetot %1000ULL , nr_cpu_ids); + timetot /1000ULL , timetot %1000ULL , nr_cpu_ids, + n_online_successes, n_online_attempts, + n_offline_successes, n_offline_attempts, + min_online, max_online, + min_offline, max_offline, + sum_online, sum_offline,HZ ); }/*
@@ -307,6 +386,9 @@ wake_torture_cleanup(void) (void )torture_cleanup_begin (); +if (onoff_task) +wake_torture_onoff_cleanup (); +if (waiter_tasks) {for (i =0 ; i < nrealwaiters; i++) torture_stop_kthread(wake_torture_waiter,
@@ -414,7 +496,7 @@ wake_torture_init(void) firsterr =torture_shutdown_init (shutdown_secs, wake_torture_cleanup);if (firsterr) goto unwind; - firsterr =torture_onoff_init (onoff_holdoff *HZ , onoff_interval); + firsterr =wake_torture_onoff_init ();if (firsterr) goto unwind;torture_init_end ();
Signature · 1 line
2.5.2
PATCH 7/8 torture: Make waketorture kill test if no hotpluggable CPUs
In reply to Paul E. McKenneyThis commit shuts down the kernel if a shutdown time was specified and if there were no hotpluggable CPUs.
--- kernel/rcu/waketorture.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
kernel/rcu/waketorture.c +8 -2
@@ -248,9 +248,15 @@ static int wake_torture_onoff(void *args)if (cpu_is_hotpluggable (cpu)) onoff_cpu = cpu; } -pr_alert ("%s" TORTURE_FLAG " wake_torture_onoff: onoff_cpu: %d\n" , torture_type, onoff_cpu); -if (onoff_cpu <0 ) +if (onoff_cpu <0 ) {VERBOSE_TOROUT_STRING ("wake_torture_onoff: no hotpluggable CPUs!" ); +if (shutdown_secs >0 ) { +VERBOSE_TOROUT_STRING ("wake_torture_onoff: Shutting down" ); +kernel_power_off (); +VERBOSE_TOROUT_STRING ("wake_torture_onoff: Survived kernel_power_off()?" ); + } + } +pr_alert ("%s" TORTURE_FLAG " wake_torture_onoff: onoff_cpu: %d\n" , torture_type, onoff_cpu); while (!torture_must_stop() && onoff_cpu >= 0) { if (!torture_offline(onoff_cpu, &n_offline_attempts, &n_offline_successes,
Signature · 1 line
2.5.2
PATCH 8/8 torture: Affinity waiter tasks away from hotpluggable CPU
In reply to Paul E. McKenney--- kernel/rcu/waketorture.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
kernel/rcu/waketorture.c +19 -0
@@ -236,7 +236,9 @@ static int wake_torture_waiter(void *arg)*/ static int wake_torture_onoff (void *args) { +cpumask_var_t cm;int cpu; +int i;VERBOSE_TOROUT_STRING ("wake_torture_onoff task started" );if (onoff_holdoff >0 ) {
@@ -244,6 +246,11 @@ static int wake_torture_onoff(void *args)schedule_timeout_interruptible (onoff_holdoff *HZ );VERBOSE_TOROUT_STRING ("wake_torture_onoff end holdoff" ); } + +/* +* Find the last hotpluggable CPU, and affinity the waiter +* tasks elsewhere. +*/ for_each_online_cpu (cpu) {if (cpu_is_hotpluggable (cpu)) onoff_cpu = cpu;
@@ -257,6 +264,18 @@ static int wake_torture_onoff(void *args) } }pr_alert ("%s" TORTURE_FLAG " wake_torture_onoff: onoff_cpu: %d\n" , torture_type, onoff_cpu); +if (!zalloc_cpumask_var (&cm,GFP_KERNEL )) { +VERBOSE_TOROUT_STRING ("wake_torture_onoff: Out of memory, no affinity" ); + }else { +cpumask_copy (cm, cpu_online_mask); +cpumask_clear_cpu (onoff_cpu, cm); +if (cpumask_weight (cm) ==0 ) +cpumask_setall (cm); +for (i =0 ; i < nrealwaiters; i++) +set_cpus_allowed_ptr (waiter_tasks[i], cm); + } + +/* Cycle the victim CPU online and offline! */ while (!torture_must_stop() && onoff_cpu >= 0) { if (!torture_offline(onoff_cpu, &n_offline_attempts, &n_offline_successes,
Signature · 1 line
2.5.2