arm: Convert VFP hotplug notifiers to state machine
[cascardo/linux.git] / kernel / torture.c
index fa0bdee..75961b3 100644 (file)
@@ -81,6 +81,104 @@ static unsigned long sum_online;
 static int min_online = -1;
 static int max_online;
 
+/*
+ * Attempt to take a CPU offline.  Return false if the CPU is already
+ * offline or if it is not subject to CPU-hotplug operations.  The
+ * caller can detect other failures by looking at the statistics.
+ */
+bool torture_offline(int cpu, long *n_offl_attempts, long *n_offl_successes,
+                    unsigned long *sum_offl, int *min_offl, int *max_offl)
+{
+       unsigned long delta;
+       int ret;
+       unsigned long starttime;
+
+       if (!cpu_online(cpu) || !cpu_is_hotpluggable(cpu))
+               return false;
+
+       if (verbose)
+               pr_alert("%s" TORTURE_FLAG
+                        "torture_onoff task: offlining %d\n",
+                        torture_type, cpu);
+       starttime = jiffies;
+       (*n_offl_attempts)++;
+       ret = cpu_down(cpu);
+       if (ret) {
+               if (verbose)
+                       pr_alert("%s" TORTURE_FLAG
+                                "torture_onoff task: offline %d failed: errno %d\n",
+                                torture_type, cpu, ret);
+       } else {
+               if (verbose)
+                       pr_alert("%s" TORTURE_FLAG
+                                "torture_onoff task: offlined %d\n",
+                                torture_type, cpu);
+               (*n_offl_successes)++;
+               delta = jiffies - starttime;
+               sum_offl += delta;
+               if (*min_offl < 0) {
+                       *min_offl = delta;
+                       *max_offl = delta;
+               }
+               if (*min_offl > delta)
+                       *min_offl = delta;
+               if (*max_offl < delta)
+                       *max_offl = delta;
+       }
+
+       return true;
+}
+EXPORT_SYMBOL_GPL(torture_offline);
+
+/*
+ * Attempt to bring a CPU online.  Return false if the CPU is already
+ * online or if it is not subject to CPU-hotplug operations.  The
+ * caller can detect other failures by looking at the statistics.
+ */
+bool torture_online(int cpu, long *n_onl_attempts, long *n_onl_successes,
+                   unsigned long *sum_onl, int *min_onl, int *max_onl)
+{
+       unsigned long delta;
+       int ret;
+       unsigned long starttime;
+
+       if (cpu_online(cpu) || !cpu_is_hotpluggable(cpu))
+               return false;
+
+       if (verbose)
+               pr_alert("%s" TORTURE_FLAG
+                        "torture_onoff task: onlining %d\n",
+                        torture_type, cpu);
+       starttime = jiffies;
+       (*n_onl_attempts)++;
+       ret = cpu_up(cpu);
+       if (ret) {
+               if (verbose)
+                       pr_alert("%s" TORTURE_FLAG
+                                "torture_onoff task: online %d failed: errno %d\n",
+                                torture_type, cpu, ret);
+       } else {
+               if (verbose)
+                       pr_alert("%s" TORTURE_FLAG
+                                "torture_onoff task: onlined %d\n",
+                                torture_type, cpu);
+               (*n_onl_successes)++;
+               delta = jiffies - starttime;
+               *sum_onl += delta;
+               if (*min_onl < 0) {
+                       *min_onl = delta;
+                       *max_onl = delta;
+               }
+               if (*min_onl > delta)
+                       *min_onl = delta;
+               if (*max_onl < delta)
+                       *max_onl = delta;
+       }
+
+       return true;
+}
+EXPORT_SYMBOL_GPL(torture_online);
+
 /*
  * Execute random CPU-hotplug operations at the interval specified
  * by the onoff_interval.
@@ -89,16 +187,19 @@ static int
 torture_onoff(void *arg)
 {
        int cpu;
-       unsigned long delta;
        int maxcpu = -1;
        DEFINE_TORTURE_RANDOM(rand);
-       int ret;
-       unsigned long starttime;
 
        VERBOSE_TOROUT_STRING("torture_onoff task started");
        for_each_online_cpu(cpu)
                maxcpu = cpu;
        WARN_ON(maxcpu < 0);
+
+       if (maxcpu == 0) {
+               VERBOSE_TOROUT_STRING("Only one CPU, so CPU-hotplug testing is disabled");
+               goto stop;
+       }
+
        if (onoff_holdoff > 0) {
                VERBOSE_TOROUT_STRING("torture_onoff begin holdoff");
                schedule_timeout_interruptible(onoff_holdoff);
@@ -106,69 +207,16 @@ torture_onoff(void *arg)
        }
        while (!torture_must_stop()) {
                cpu = (torture_random(&rand) >> 4) % (maxcpu + 1);
-               if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) {
-                       if (verbose)
-                               pr_alert("%s" TORTURE_FLAG
-                                        "torture_onoff task: offlining %d\n",
-                                        torture_type, cpu);
-                       starttime = jiffies;
-                       n_offline_attempts++;
-                       ret = cpu_down(cpu);
-                       if (ret) {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "torture_onoff task: offline %d failed: errno %d\n",
-                                                torture_type, cpu, ret);
-                       } else {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "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)
-                               pr_alert("%s" TORTURE_FLAG
-                                        "torture_onoff task: onlining %d\n",
-                                        torture_type, cpu);
-                       starttime = jiffies;
-                       n_online_attempts++;
-                       ret = cpu_up(cpu);
-                       if (ret) {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "torture_onoff task: online %d failed: errno %d\n",
-                                                torture_type, cpu, ret);
-                       } else {
-                               if (verbose)
-                                       pr_alert("%s" TORTURE_FLAG
-                                                "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;
-                       }
-               }
+               if (!torture_offline(cpu,
+                                    &n_offline_attempts, &n_offline_successes,
+                                    &sum_offline, &min_offline, &max_offline))
+                       torture_online(cpu,
+                                      &n_online_attempts, &n_online_successes,
+                                      &sum_online, &min_online, &max_online);
                schedule_timeout_interruptible(onoff_interval);
        }
+
+stop:
        torture_kthread_stopping("torture_onoff");
        return 0;
 }