aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/torture.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-01-28 18:58:22 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-02-23 12:01:06 -0500
commit2e9e8081d2e7a4efb582a240aa7fee991bbbabb0 (patch)
tree21b3850bb6568d7bc61b432305c20b2423de24d7 /kernel/torture.c
parent3808dc9fab05913060626d7f0edd0f195cb9dcab (diff)
rcutorture: Abstract torture_onoff()
Because online/offline torturing is not specific to RCU, this commit abstracts it into the kernel/torture.c module to allow other torture tests to use it. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/torture.c')
-rw-r--r--kernel/torture.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/kernel/torture.c b/kernel/torture.c
index 26058f20ee83..a7ec8a7d561e 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -54,6 +54,192 @@ EXPORT_SYMBOL_GPL(fullstop);
54DEFINE_MUTEX(fullstop_mutex); 54DEFINE_MUTEX(fullstop_mutex);
55EXPORT_SYMBOL_GPL(fullstop_mutex); 55EXPORT_SYMBOL_GPL(fullstop_mutex);
56 56
57#ifdef CONFIG_HOTPLUG_CPU
58
59/*
60 * Variables for online-offline handling. Only present if CPU hotplug
61 * is enabled, otherwise does nothing.
62 */
63
64static struct task_struct *onoff_task;
65static long onoff_holdoff;
66static long onoff_interval;
67static long n_offline_attempts;
68static long n_offline_successes;
69static unsigned long sum_offline;
70static int min_offline = -1;
71static int max_offline;
72static long n_online_attempts;
73static long n_online_successes;
74static unsigned long sum_online;
75static int min_online = -1;
76static int max_online;
77
78/*
79 * Execute random CPU-hotplug operations at the interval specified
80 * by the onoff_interval.
81 */
82static int
83torture_onoff(void *arg)
84{
85 int cpu;
86 unsigned long delta;
87 int maxcpu = -1;
88 DEFINE_TORTURE_RANDOM(rand);
89 int ret;
90 unsigned long starttime;
91
92 VERBOSE_TOROUT_STRING("torture_onoff task started");
93 for_each_online_cpu(cpu)
94 maxcpu = cpu;
95 WARN_ON(maxcpu < 0);
96 if (onoff_holdoff > 0) {
97 VERBOSE_TOROUT_STRING("torture_onoff begin holdoff");
98 schedule_timeout_interruptible(onoff_holdoff);
99 VERBOSE_TOROUT_STRING("torture_onoff end holdoff");
100 }
101 while (!torture_must_stop()) {
102 cpu = (torture_random(&rand) >> 4) % (maxcpu + 1);
103 if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) {
104 if (verbose)
105 pr_alert("%s" TORTURE_FLAG
106 "torture_onoff task: offlining %d\n",
107 torture_type, cpu);
108 starttime = jiffies;
109 n_offline_attempts++;
110 ret = cpu_down(cpu);
111 if (ret) {
112 if (verbose)
113 pr_alert("%s" TORTURE_FLAG
114 "torture_onoff task: offline %d failed: errno %d\n",
115 torture_type, cpu, ret);
116 } else {
117 if (verbose)
118 pr_alert("%s" TORTURE_FLAG
119 "torture_onoff task: offlined %d\n",
120 torture_type, cpu);
121 n_offline_successes++;
122 delta = jiffies - starttime;
123 sum_offline += delta;
124 if (min_offline < 0) {
125 min_offline = delta;
126 max_offline = delta;
127 }
128 if (min_offline > delta)
129 min_offline = delta;
130 if (max_offline < delta)
131 max_offline = delta;
132 }
133 } else if (cpu_is_hotpluggable(cpu)) {
134 if (verbose)
135 pr_alert("%s" TORTURE_FLAG
136 "torture_onoff task: onlining %d\n",
137 torture_type, cpu);
138 starttime = jiffies;
139 n_online_attempts++;
140 ret = cpu_up(cpu);
141 if (ret) {
142 if (verbose)
143 pr_alert("%s" TORTURE_FLAG
144 "torture_onoff task: online %d failed: errno %d\n",
145 torture_type, cpu, ret);
146 } else {
147 if (verbose)
148 pr_alert("%s" TORTURE_FLAG
149 "torture_onoff task: onlined %d\n",
150 torture_type, cpu);
151 n_online_successes++;
152 delta = jiffies - starttime;
153 sum_online += delta;
154 if (min_online < 0) {
155 min_online = delta;
156 max_online = delta;
157 }
158 if (min_online > delta)
159 min_online = delta;
160 if (max_online < delta)
161 max_online = delta;
162 }
163 }
164 schedule_timeout_interruptible(onoff_interval);
165 }
166 VERBOSE_TOROUT_STRING("torture_onoff task stopping");
167 return 0;
168}
169
170#endif /* #ifdef CONFIG_HOTPLUG_CPU */
171
172/*
173 * Initiate online-offline handling.
174 */
175int torture_onoff_init(long ooholdoff, long oointerval)
176{
177#ifdef CONFIG_HOTPLUG_CPU
178 int ret;
179
180 onoff_holdoff = ooholdoff;
181 onoff_interval = oointerval;
182 if (onoff_interval <= 0)
183 return 0;
184 onoff_task = kthread_run(torture_onoff, NULL, "torture_onoff");
185 if (IS_ERR(onoff_task)) {
186 ret = PTR_ERR(onoff_task);
187 onoff_task = NULL;
188 return ret;
189 }
190 torture_shuffle_task_register(onoff_task);
191#endif /* #ifdef CONFIG_HOTPLUG_CPU */
192 return 0;
193}
194EXPORT_SYMBOL_GPL(torture_onoff_init);
195
196/*
197 * Clean up after online/offline testing.
198 */
199void torture_onoff_cleanup(void)
200{
201#ifdef CONFIG_HOTPLUG_CPU
202 if (onoff_task == NULL)
203 return;
204 VERBOSE_TOROUT_STRING("Stopping torture_onoff task");
205 kthread_stop(onoff_task);
206 onoff_task = NULL;
207#endif /* #ifdef CONFIG_HOTPLUG_CPU */
208}
209EXPORT_SYMBOL_GPL(torture_onoff_cleanup);
210
211/*
212 * Print online/offline testing statistics.
213 */
214char *torture_onoff_stats(char *page)
215{
216#ifdef CONFIG_HOTPLUG_CPU
217 page += sprintf(page,
218 "onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ",
219 n_online_successes, n_online_attempts,
220 n_offline_successes, n_offline_attempts,
221 min_online, max_online,
222 min_offline, max_offline,
223 sum_online, sum_offline, HZ);
224#endif /* #ifdef CONFIG_HOTPLUG_CPU */
225 return page;
226}
227EXPORT_SYMBOL_GPL(torture_onoff_stats);
228
229/*
230 * Were all the online/offline operations successful?
231 */
232bool torture_onoff_failures(void)
233{
234#ifdef CONFIG_HOTPLUG_CPU
235 return n_online_successes != n_online_attempts ||
236 n_offline_successes != n_offline_attempts;
237#else /* #ifdef CONFIG_HOTPLUG_CPU */
238 return false;
239#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
240}
241EXPORT_SYMBOL_GPL(torture_onoff_failures);
242
57#define TORTURE_RANDOM_MULT 39916801 /* prime */ 243#define TORTURE_RANDOM_MULT 39916801 /* prime */
58#define TORTURE_RANDOM_ADD 479001701 /* prime */ 244#define TORTURE_RANDOM_ADD 479001701 /* prime */
59#define TORTURE_RANDOM_REFRESH 10000 245#define TORTURE_RANDOM_REFRESH 10000