]> Pileus Git - ~andy/linux/blobdiff - kernel/rcutorture.c
Merge branch 'slab/next' into slab/for-linus
[~andy/linux] / kernel / rcutorture.c
index 25b15033c61f88ff7d76854fd16401779d9d9f62..aaa7b9f3532a86c87580fa6202a20df8c9dcd249 100644 (file)
@@ -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) {