|
@@ -53,10 +53,11 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@fre
|
|
|
|
|
|
static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */
|
|
|
static int nfakewriters = 4; /* # fake writer threads */
|
|
|
-static int stat_interval; /* Interval between stats, in seconds. */
|
|
|
- /* Defaults to "only at end of test". */
|
|
|
+static int stat_interval = 60; /* Interval between stats, in seconds. */
|
|
|
+ /* Zero means "only at end of test". */
|
|
|
static bool verbose; /* Print more debug info. */
|
|
|
-static bool test_no_idle_hz; /* Test RCU's support for tickless idle CPUs. */
|
|
|
+static bool test_no_idle_hz = true;
|
|
|
+ /* Test RCU support for tickless idle CPUs. */
|
|
|
static int shuffle_interval = 3; /* Interval between shuffles (in sec)*/
|
|
|
static int stutter = 5; /* Start/stop testing interval (in sec) */
|
|
|
static int irqreader = 1; /* RCU readers from irq (timers). */
|
|
@@ -119,11 +120,11 @@ MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, srcu)");
|
|
|
|
|
|
#define TORTURE_FLAG "-torture:"
|
|
|
#define PRINTK_STRING(s) \
|
|
|
- do { printk(KERN_ALERT "%s" TORTURE_FLAG s "\n", torture_type); } while (0)
|
|
|
+ do { pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0)
|
|
|
#define VERBOSE_PRINTK_STRING(s) \
|
|
|
- do { if (verbose) printk(KERN_ALERT "%s" TORTURE_FLAG s "\n", torture_type); } while (0)
|
|
|
+ do { if (verbose) pr_alert("%s" TORTURE_FLAG s "\n", torture_type); } while (0)
|
|
|
#define VERBOSE_PRINTK_ERRSTRING(s) \
|
|
|
- do { if (verbose) printk(KERN_ALERT "%s" TORTURE_FLAG "!!! " s "\n", torture_type); } while (0)
|
|
|
+ do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! " s "\n", torture_type); } while (0)
|
|
|
|
|
|
static char printk_buf[4096];
|
|
|
|
|
@@ -176,8 +177,14 @@ static long n_rcu_torture_boosts;
|
|
|
static long n_rcu_torture_timers;
|
|
|
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 long n_barrier_attempts;
|
|
|
static long n_barrier_successes;
|
|
|
static struct list_head rcu_torture_removed;
|
|
@@ -235,7 +242,7 @@ rcutorture_shutdown_notify(struct notifier_block *unused1,
|
|
|
if (fullstop == FULLSTOP_DONTSTOP)
|
|
|
fullstop = FULLSTOP_SHUTDOWN;
|
|
|
else
|
|
|
- printk(KERN_WARNING /* but going down anyway, so... */
|
|
|
+ pr_warn(/* but going down anyway, so... */
|
|
|
"Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
|
|
|
mutex_unlock(&fullstop_mutex);
|
|
|
return NOTIFY_DONE;
|
|
@@ -248,7 +255,7 @@ rcutorture_shutdown_notify(struct notifier_block *unused1,
|
|
|
static void rcutorture_shutdown_absorb(char *title)
|
|
|
{
|
|
|
if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
|
|
|
- printk(KERN_NOTICE
|
|
|
+ pr_notice(
|
|
|
"rcutorture thread %s parking due to system shutdown\n",
|
|
|
title);
|
|
|
schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
|
|
@@ -1214,11 +1221,13 @@ rcu_torture_printk(char *page)
|
|
|
n_rcu_torture_boost_failure,
|
|
|
n_rcu_torture_boosts,
|
|
|
n_rcu_torture_timers);
|
|
|
- cnt += sprintf(&page[cnt], "onoff: %ld/%ld:%ld/%ld ",
|
|
|
- n_online_successes,
|
|
|
- n_online_attempts,
|
|
|
- n_offline_successes,
|
|
|
- n_offline_attempts);
|
|
|
+ cnt += sprintf(&page[cnt],
|
|
|
+ "onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ",
|
|
|
+ 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);
|
|
|
cnt += sprintf(&page[cnt], "barrier: %ld/%ld:%ld",
|
|
|
n_barrier_successes,
|
|
|
n_barrier_attempts,
|
|
@@ -1267,7 +1276,7 @@ rcu_torture_stats_print(void)
|
|
|
int cnt;
|
|
|
|
|
|
cnt = rcu_torture_printk(printk_buf);
|
|
|
- printk(KERN_ALERT "%s", printk_buf);
|
|
|
+ pr_alert("%s", printk_buf);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1380,20 +1389,20 @@ rcu_torture_stutter(void *arg)
|
|
|
static inline void
|
|
|
rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, char *tag)
|
|
|
{
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- "--- %s: nreaders=%d nfakewriters=%d "
|
|
|
- "stat_interval=%d verbose=%d test_no_idle_hz=%d "
|
|
|
- "shuffle_interval=%d stutter=%d irqreader=%d "
|
|
|
- "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d "
|
|
|
- "test_boost=%d/%d test_boost_interval=%d "
|
|
|
- "test_boost_duration=%d shutdown_secs=%d "
|
|
|
- "onoff_interval=%d onoff_holdoff=%d\n",
|
|
|
- torture_type, tag, nrealreaders, nfakewriters,
|
|
|
- stat_interval, verbose, test_no_idle_hz, shuffle_interval,
|
|
|
- stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
|
|
|
- test_boost, cur_ops->can_boost,
|
|
|
- test_boost_interval, test_boost_duration, shutdown_secs,
|
|
|
- onoff_interval, onoff_holdoff);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ "--- %s: nreaders=%d nfakewriters=%d "
|
|
|
+ "stat_interval=%d verbose=%d test_no_idle_hz=%d "
|
|
|
+ "shuffle_interval=%d stutter=%d irqreader=%d "
|
|
|
+ "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d "
|
|
|
+ "test_boost=%d/%d test_boost_interval=%d "
|
|
|
+ "test_boost_duration=%d shutdown_secs=%d "
|
|
|
+ "onoff_interval=%d onoff_holdoff=%d\n",
|
|
|
+ torture_type, tag, nrealreaders, nfakewriters,
|
|
|
+ stat_interval, verbose, test_no_idle_hz, shuffle_interval,
|
|
|
+ stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
|
|
|
+ test_boost, cur_ops->can_boost,
|
|
|
+ test_boost_interval, test_boost_duration, shutdown_secs,
|
|
|
+ onoff_interval, onoff_holdoff);
|
|
|
}
|
|
|
|
|
|
static struct notifier_block rcutorture_shutdown_nb = {
|
|
@@ -1460,9 +1469,9 @@ rcu_torture_shutdown(void *arg)
|
|
|
!kthread_should_stop()) {
|
|
|
delta = shutdown_time - jiffies_snap;
|
|
|
if (verbose)
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- "rcu_torture_shutdown task: %lu jiffies remaining\n",
|
|
|
- torture_type, delta);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ "rcu_torture_shutdown task: %lu jiffies remaining\n",
|
|
|
+ torture_type, delta);
|
|
|
schedule_timeout_interruptible(delta);
|
|
|
jiffies_snap = ACCESS_ONCE(jiffies);
|
|
|
}
|
|
@@ -1490,8 +1499,10 @@ static int __cpuinit
|
|
|
rcu_torture_onoff(void *arg)
|
|
|
{
|
|
|
int cpu;
|
|
|
+ unsigned long delta;
|
|
|
int maxcpu = -1;
|
|
|
DEFINE_RCU_RANDOM(rand);
|
|
|
+ unsigned long starttime;
|
|
|
|
|
|
VERBOSE_PRINTK_STRING("rcu_torture_onoff task started");
|
|
|
for_each_online_cpu(cpu)
|
|
@@ -1506,29 +1517,51 @@ rcu_torture_onoff(void *arg)
|
|
|
cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1);
|
|
|
if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) {
|
|
|
if (verbose)
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- "rcu_torture_onoff task: offlining %d\n",
|
|
|
- torture_type, cpu);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ "rcu_torture_onoff task: offlining %d\n",
|
|
|
+ torture_type, cpu);
|
|
|
+ starttime = jiffies;
|
|
|
n_offline_attempts++;
|
|
|
if (cpu_down(cpu) == 0) {
|
|
|
if (verbose)
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- "rcu_torture_onoff task: offlined %d\n",
|
|
|
- torture_type, cpu);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ "rcu_torture_onoff task: offlined %d\n",
|
|
|
+ torture_type, cpu);
|
|
|
n_offline_successes++;
|
|
|
+ delta = jiffies - starttime;
|
|
|
+ sum_offline += delta;
|
|
|
+ if (min_offline < 0) {
|
|
|
+ min_offline = delta;
|
|
|
+ max_offline = delta;
|
|
|
+ }
|
|
|
+ if (min_offline > delta)
|
|
|
+ min_offline = delta;
|
|
|
+ if (max_offline < delta)
|
|
|
+ max_offline = delta;
|
|
|
}
|
|
|
} else if (cpu_is_hotpluggable(cpu)) {
|
|
|
if (verbose)
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- "rcu_torture_onoff task: onlining %d\n",
|
|
|
- torture_type, cpu);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ "rcu_torture_onoff task: onlining %d\n",
|
|
|
+ torture_type, cpu);
|
|
|
+ starttime = jiffies;
|
|
|
n_online_attempts++;
|
|
|
if (cpu_up(cpu) == 0) {
|
|
|
if (verbose)
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- "rcu_torture_onoff task: onlined %d\n",
|
|
|
- torture_type, cpu);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ "rcu_torture_onoff task: onlined %d\n",
|
|
|
+ torture_type, cpu);
|
|
|
n_online_successes++;
|
|
|
+ delta = jiffies - starttime;
|
|
|
+ sum_online += delta;
|
|
|
+ if (min_online < 0) {
|
|
|
+ min_online = delta;
|
|
|
+ max_online = delta;
|
|
|
+ }
|
|
|
+ if (min_online > delta)
|
|
|
+ min_online = delta;
|
|
|
+ if (max_online < delta)
|
|
|
+ max_online = delta;
|
|
|
}
|
|
|
}
|
|
|
schedule_timeout_interruptible(onoff_interval * HZ);
|
|
@@ -1593,14 +1626,14 @@ static int __cpuinit rcu_torture_stall(void *args)
|
|
|
if (!kthread_should_stop()) {
|
|
|
stop_at = get_seconds() + stall_cpu;
|
|
|
/* RCU CPU stall is expected behavior in following code. */
|
|
|
- printk(KERN_ALERT "rcu_torture_stall start.\n");
|
|
|
+ pr_alert("rcu_torture_stall start.\n");
|
|
|
rcu_read_lock();
|
|
|
preempt_disable();
|
|
|
while (ULONG_CMP_LT(get_seconds(), stop_at))
|
|
|
continue; /* Induce RCU CPU stall warning. */
|
|
|
preempt_enable();
|
|
|
rcu_read_unlock();
|
|
|
- printk(KERN_ALERT "rcu_torture_stall end.\n");
|
|
|
+ pr_alert("rcu_torture_stall end.\n");
|
|
|
}
|
|
|
rcutorture_shutdown_absorb("rcu_torture_stall");
|
|
|
while (!kthread_should_stop())
|
|
@@ -1716,12 +1749,12 @@ static int rcu_torture_barrier_init(void)
|
|
|
if (n_barrier_cbs == 0)
|
|
|
return 0;
|
|
|
if (cur_ops->call == NULL || cur_ops->cb_barrier == NULL) {
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- " Call or barrier ops missing for %s,\n",
|
|
|
- torture_type, cur_ops->name);
|
|
|
- printk(KERN_ALERT "%s" TORTURE_FLAG
|
|
|
- " RCU barrier testing omitted from run.\n",
|
|
|
- torture_type);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ " Call or barrier ops missing for %s,\n",
|
|
|
+ torture_type, cur_ops->name);
|
|
|
+ pr_alert("%s" TORTURE_FLAG
|
|
|
+ " RCU barrier testing omitted from run.\n",
|
|
|
+ torture_type);
|
|
|
return 0;
|
|
|
}
|
|
|
atomic_set(&barrier_cbs_count, 0);
|
|
@@ -1814,7 +1847,7 @@ rcu_torture_cleanup(void)
|
|
|
mutex_lock(&fullstop_mutex);
|
|
|
rcutorture_record_test_transition();
|
|
|
if (fullstop == FULLSTOP_SHUTDOWN) {
|
|
|
- printk(KERN_WARNING /* but going down anyway, so... */
|
|
|
+ pr_warn(/* but going down anyway, so... */
|
|
|
"Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
|
|
|
mutex_unlock(&fullstop_mutex);
|
|
|
schedule_timeout_uninterruptible(10);
|
|
@@ -1938,17 +1971,17 @@ rcu_torture_init(void)
|
|
|
break;
|
|
|
}
|
|
|
if (i == ARRAY_SIZE(torture_ops)) {
|
|
|
- printk(KERN_ALERT "rcu-torture: invalid torture type: \"%s\"\n",
|
|
|
- torture_type);
|
|
|
- printk(KERN_ALERT "rcu-torture types:");
|
|
|
+ pr_alert("rcu-torture: invalid torture type: \"%s\"\n",
|
|
|
+ torture_type);
|
|
|
+ pr_alert("rcu-torture types:");
|
|
|
for (i = 0; i < ARRAY_SIZE(torture_ops); i++)
|
|
|
- printk(KERN_ALERT " %s", torture_ops[i]->name);
|
|
|
- printk(KERN_ALERT "\n");
|
|
|
+ pr_alert(" %s", torture_ops[i]->name);
|
|
|
+ pr_alert("\n");
|
|
|
mutex_unlock(&fullstop_mutex);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
if (cur_ops->fqs == NULL && fqs_duration != 0) {
|
|
|
- printk(KERN_ALERT "rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n");
|
|
|
+ pr_alert("rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n");
|
|
|
fqs_duration = 0;
|
|
|
}
|
|
|
if (cur_ops->init)
|
|
@@ -1996,14 +2029,15 @@ rcu_torture_init(void)
|
|
|
/* Start up the kthreads. */
|
|
|
|
|
|
VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
|
|
|
- writer_task = kthread_run(rcu_torture_writer, NULL,
|
|
|
- "rcu_torture_writer");
|
|
|
+ writer_task = kthread_create(rcu_torture_writer, NULL,
|
|
|
+ "rcu_torture_writer");
|
|
|
if (IS_ERR(writer_task)) {
|
|
|
firsterr = PTR_ERR(writer_task);
|
|
|
VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
|
|
|
writer_task = NULL;
|
|
|
goto unwind;
|
|
|
}
|
|
|
+ wake_up_process(writer_task);
|
|
|
fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
|
|
|
GFP_KERNEL);
|
|
|
if (fakewriter_tasks == NULL) {
|
|
@@ -2118,14 +2152,15 @@ rcu_torture_init(void)
|
|
|
}
|
|
|
if (shutdown_secs > 0) {
|
|
|
shutdown_time = jiffies + shutdown_secs * HZ;
|
|
|
- shutdown_task = kthread_run(rcu_torture_shutdown, NULL,
|
|
|
- "rcu_torture_shutdown");
|
|
|
+ shutdown_task = kthread_create(rcu_torture_shutdown, NULL,
|
|
|
+ "rcu_torture_shutdown");
|
|
|
if (IS_ERR(shutdown_task)) {
|
|
|
firsterr = PTR_ERR(shutdown_task);
|
|
|
VERBOSE_PRINTK_ERRSTRING("Failed to create shutdown");
|
|
|
shutdown_task = NULL;
|
|
|
goto unwind;
|
|
|
}
|
|
|
+ wake_up_process(shutdown_task);
|
|
|
}
|
|
|
i = rcu_torture_onoff_init();
|
|
|
if (i != 0) {
|