~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/torture.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /kernel/torture.c (Version linux-6.12-rc7) and /kernel/torture.c (Version linux-6.6.58)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0+                1 
  2 /*                                                
  3  * Common functions for in-kernel torture test    
  4  *                                                
  5  * Copyright (C) IBM Corporation, 2014            
  6  *                                                
  7  * Author: Paul E. McKenney <paulmck@linux.ibm    
  8  *      Based on kernel/rcu/torture.c.            
  9  */                                               
 10                                                   
 11 #define pr_fmt(fmt) fmt                           
 12                                                   
 13 #include <linux/types.h>                          
 14 #include <linux/kernel.h>                         
 15 #include <linux/init.h>                           
 16 #include <linux/module.h>                         
 17 #include <linux/kthread.h>                        
 18 #include <linux/err.h>                            
 19 #include <linux/spinlock.h>                       
 20 #include <linux/smp.h>                            
 21 #include <linux/interrupt.h>                      
 22 #include <linux/sched.h>                          
 23 #include <linux/sched/clock.h>                    
 24 #include <linux/atomic.h>                         
 25 #include <linux/bitops.h>                         
 26 #include <linux/completion.h>                     
 27 #include <linux/moduleparam.h>                    
 28 #include <linux/percpu.h>                         
 29 #include <linux/notifier.h>                       
 30 #include <linux/reboot.h>                         
 31 #include <linux/freezer.h>                        
 32 #include <linux/cpu.h>                            
 33 #include <linux/delay.h>                          
 34 #include <linux/stat.h>                           
 35 #include <linux/slab.h>                           
 36 #include <linux/trace_clock.h>                    
 37 #include <linux/ktime.h>                          
 38 #include <asm/byteorder.h>                        
 39 #include <linux/torture.h>                        
 40 #include <linux/sched/rt.h>                       
 41 #include "rcu/rcu.h"                              
 42                                                   
 43 MODULE_DESCRIPTION("Common functions for in-ke    
 44 MODULE_LICENSE("GPL");                            
 45 MODULE_AUTHOR("Paul E. McKenney <paulmck@linux    
 46                                                   
 47 static bool disable_onoff_at_boot;                
 48 module_param(disable_onoff_at_boot, bool, 0444    
 49                                                   
 50 static bool ftrace_dump_at_shutdown;              
 51 module_param(ftrace_dump_at_shutdown, bool, 04    
 52                                                   
 53 static int verbose_sleep_frequency;               
 54 module_param(verbose_sleep_frequency, int, 044    
 55                                                   
 56 static int verbose_sleep_duration = 1;            
 57 module_param(verbose_sleep_duration, int, 0444    
 58                                                   
 59 static int random_shuffle;                        
 60 module_param(random_shuffle, int, 0444);          
 61                                                   
 62 static char *torture_type;                        
 63 static int verbose;                               
 64                                                   
 65 /* Mediate rmmod and system shutdown.  Concurr    
 66 #define FULLSTOP_DONTSTOP 0     /* Normal oper    
 67 #define FULLSTOP_SHUTDOWN 1     /* System shut    
 68 #define FULLSTOP_RMMOD    2     /* Normal rmmo    
 69 static int fullstop = FULLSTOP_RMMOD;             
 70 static DEFINE_MUTEX(fullstop_mutex);              
 71                                                   
 72 static atomic_t verbose_sleep_counter;            
 73                                                   
 74 /*                                                
 75  * Sleep if needed from VERBOSE_TOROUT*().        
 76  */                                               
 77 void verbose_torout_sleep(void)                   
 78 {                                                 
 79         if (verbose_sleep_frequency > 0 &&        
 80             verbose_sleep_duration > 0 &&         
 81             !(atomic_inc_return(&verbose_sleep    
 82                 schedule_timeout_uninterruptib    
 83 }                                                 
 84 EXPORT_SYMBOL_GPL(verbose_torout_sleep);          
 85                                                   
 86 /*                                                
 87  * Schedule a high-resolution-timer sleep in n    
 88  * nanosecond random fuzz.  This function and     
 89  * testing from the timer wheel.                  
 90  */                                               
 91 int torture_hrtimeout_ns(ktime_t baset_ns, u32    
 92                          struct torture_random    
 93 {                                                 
 94         ktime_t hto = baset_ns;                   
 95                                                   
 96         if (trsp)                                 
 97                 hto += torture_random(trsp) %     
 98         set_current_state(TASK_IDLE);             
 99         return schedule_hrtimeout(&hto, mode);    
100 }                                                 
101 EXPORT_SYMBOL_GPL(torture_hrtimeout_ns);          
102                                                   
103 /*                                                
104  * Schedule a high-resolution-timer sleep in m    
105  * nanosecond (not microsecond!) random fuzz.     
106  */                                               
107 int torture_hrtimeout_us(u32 baset_us, u32 fuz    
108 {                                                 
109         ktime_t baset_ns = baset_us * NSEC_PER    
110                                                   
111         return torture_hrtimeout_ns(baset_ns,     
112 }                                                 
113 EXPORT_SYMBOL_GPL(torture_hrtimeout_us);          
114                                                   
115 /*                                                
116  * Schedule a high-resolution-timer sleep in m    
117  * microsecond (not millisecond!) random fuzz.    
118  */                                               
119 int torture_hrtimeout_ms(u32 baset_ms, u32 fuz    
120 {                                                 
121         ktime_t baset_ns = baset_ms * NSEC_PER    
122         u32 fuzzt_ns;                             
123                                                   
124         if ((u32)~0U / NSEC_PER_USEC < fuzzt_u    
125                 fuzzt_ns = (u32)~0U;              
126         else                                      
127                 fuzzt_ns = fuzzt_us * NSEC_PER    
128         return torture_hrtimeout_ns(baset_ns,     
129 }                                                 
130 EXPORT_SYMBOL_GPL(torture_hrtimeout_ms);          
131                                                   
132 /*                                                
133  * Schedule a high-resolution-timer sleep in j    
134  * implied one-jiffy random fuzz.  This is int    
135  * schedule_timeout_interruptible() and friend    
136  */                                               
137 int torture_hrtimeout_jiffies(u32 baset_j, str    
138 {                                                 
139         ktime_t baset_ns = jiffies_to_nsecs(ba    
140                                                   
141         return torture_hrtimeout_ns(baset_ns,     
142 }                                                 
143 EXPORT_SYMBOL_GPL(torture_hrtimeout_jiffies);     
144                                                   
145 /*                                                
146  * Schedule a high-resolution-timer sleep in m    
147  * millisecond (not second!) random fuzz.         
148  */                                               
149 int torture_hrtimeout_s(u32 baset_s, u32 fuzzt    
150 {                                                 
151         ktime_t baset_ns = baset_s * NSEC_PER_    
152         u32 fuzzt_ns;                             
153                                                   
154         if ((u32)~0U / NSEC_PER_MSEC < fuzzt_m    
155                 fuzzt_ns = (u32)~0U;              
156         else                                      
157                 fuzzt_ns = fuzzt_ms * NSEC_PER    
158         return torture_hrtimeout_ns(baset_ns,     
159 }                                                 
160 EXPORT_SYMBOL_GPL(torture_hrtimeout_s);           
161                                                   
162 #ifdef CONFIG_HOTPLUG_CPU                         
163                                                   
164 /*                                                
165  * Variables for online-offline handling.  Onl    
166  * is enabled, otherwise does nothing.            
167  */                                               
168                                                   
169 static struct task_struct *onoff_task;            
170 static long onoff_holdoff;                        
171 static long onoff_interval;                       
172 static torture_ofl_func *onoff_f;                 
173 static long n_offline_attempts;                   
174 static long n_offline_successes;                  
175 static unsigned long sum_offline;                 
176 static int min_offline = -1;                      
177 static int max_offline;                           
178 static long n_online_attempts;                    
179 static long n_online_successes;                   
180 static unsigned long sum_online;                  
181 static int min_online = -1;                       
182 static int max_online;                            
183                                                   
184 static int torture_online_cpus = NR_CPUS;         
185                                                   
186 /*                                                
187  * Some torture testing leverages confusion as    
188  * CPUs.  This function returns the torture-te    
189  * which allows torture tests to load-balance     
190  */                                               
191 int torture_num_online_cpus(void)                 
192 {                                                 
193         return READ_ONCE(torture_online_cpus);    
194 }                                                 
195 EXPORT_SYMBOL_GPL(torture_num_online_cpus);       
196                                                   
197 /*                                                
198  * Attempt to take a CPU offline.  Return fals    
199  * offline or if it is not subject to CPU-hotp    
200  * caller can detect other failures by looking    
201  */                                               
202 bool torture_offline(int cpu, long *n_offl_att    
203                      unsigned long *sum_offl,     
204 {                                                 
205         unsigned long delta;                      
206         int ret;                                  
207         char *s;                                  
208         unsigned long starttime;                  
209                                                   
210         if (!cpu_online(cpu) || !cpu_is_hotplu    
211                 return false;                     
212         if (num_online_cpus() <= 1)               
213                 return false;  /* Can't offlin    
214                                                   
215         if (verbose > 1)                          
216                 pr_alert("%s" TORTURE_FLAG        
217                          "torture_onoff task:     
218                          torture_type, cpu);      
219         starttime = jiffies;                      
220         (*n_offl_attempts)++;                     
221         ret = remove_cpu(cpu);                    
222         if (ret) {                                
223                 s = "";                           
224                 if (!rcu_inkernel_boot_has_end    
225                         // PCI probe frequentl    
226                         (*n_offl_attempts)--;     
227                         s = " (-EBUSY forgiven    
228                 }                                 
229                 if (verbose)                      
230                         pr_alert("%s" TORTURE_    
231                                  "torture_onof    
232                                  torture_type,    
233         } else {                                  
234                 if (verbose > 1)                  
235                         pr_alert("%s" TORTURE_    
236                                  "torture_onof    
237                                  torture_type,    
238                 if (onoff_f)                      
239                         onoff_f();                
240                 (*n_offl_successes)++;            
241                 delta = jiffies - starttime;      
242                 *sum_offl += delta;               
243                 if (*min_offl < 0) {              
244                         *min_offl = delta;        
245                         *max_offl = delta;        
246                 }                                 
247                 if (*min_offl > delta)            
248                         *min_offl = delta;        
249                 if (*max_offl < delta)            
250                         *max_offl = delta;        
251                 WRITE_ONCE(torture_online_cpus    
252                 WARN_ON_ONCE(torture_online_cp    
253         }                                         
254                                                   
255         return true;                              
256 }                                                 
257 EXPORT_SYMBOL_GPL(torture_offline);               
258                                                   
259 /*                                                
260  * Attempt to bring a CPU online.  Return fals    
261  * online or if it is not subject to CPU-hotpl    
262  * caller can detect other failures by looking    
263  */                                               
264 bool torture_online(int cpu, long *n_onl_attem    
265                     unsigned long *sum_onl, in    
266 {                                                 
267         unsigned long delta;                      
268         int ret;                                  
269         char *s;                                  
270         unsigned long starttime;                  
271                                                   
272         if (cpu_online(cpu) || !cpu_is_hotplug    
273                 return false;                     
274                                                   
275         if (verbose > 1)                          
276                 pr_alert("%s" TORTURE_FLAG        
277                          "torture_onoff task:     
278                          torture_type, cpu);      
279         starttime = jiffies;                      
280         (*n_onl_attempts)++;                      
281         ret = add_cpu(cpu);                       
282         if (ret) {                                
283                 s = "";                           
284                 if (!rcu_inkernel_boot_has_end    
285                         // PCI probe frequentl    
286                         (*n_onl_attempts)--;      
287                         s = " (-EBUSY forgiven    
288                 }                                 
289                 if (verbose)                      
290                         pr_alert("%s" TORTURE_    
291                                  "torture_onof    
292                                  torture_type,    
293         } else {                                  
294                 if (verbose > 1)                  
295                         pr_alert("%s" TORTURE_    
296                                  "torture_onof    
297                                  torture_type,    
298                 (*n_onl_successes)++;             
299                 delta = jiffies - starttime;      
300                 *sum_onl += delta;                
301                 if (*min_onl < 0) {               
302                         *min_onl = delta;         
303                         *max_onl = delta;         
304                 }                                 
305                 if (*min_onl > delta)             
306                         *min_onl = delta;         
307                 if (*max_onl < delta)             
308                         *max_onl = delta;         
309                 WRITE_ONCE(torture_online_cpus    
310         }                                         
311                                                   
312         return true;                              
313 }                                                 
314 EXPORT_SYMBOL_GPL(torture_online);                
315                                                   
316 /*                                                
317  * Get everything online at the beginning and     
318  */                                               
319 static void torture_online_all(char *phase)       
320 {                                                 
321         int cpu;                                  
322         int ret;                                  
323                                                   
324         for_each_possible_cpu(cpu) {              
325                 if (cpu_online(cpu))              
326                         continue;                 
327                 ret = add_cpu(cpu);               
328                 if (ret && verbose) {             
329                         pr_alert("%s" TORTURE_    
330                                  "%s: %s onlin    
331                                  __func__, pha    
332                 }                                 
333         }                                         
334 }                                                 
335                                                   
336 /*                                                
337  * Execute random CPU-hotplug operations at th    
338  * by the onoff_interval.                         
339  */                                               
340 static int                                        
341 torture_onoff(void *arg)                          
342 {                                                 
343         int cpu;                                  
344         int maxcpu = -1;                          
345         DEFINE_TORTURE_RANDOM(rand);              
346                                                   
347         VERBOSE_TOROUT_STRING("torture_onoff t    
348         for_each_online_cpu(cpu)                  
349                 maxcpu = cpu;                     
350         WARN_ON(maxcpu < 0);                      
351         torture_online_all("Initial");            
352         if (maxcpu == 0) {                        
353                 VERBOSE_TOROUT_STRING("Only on    
354                 goto stop;                        
355         }                                         
356                                                   
357         if (onoff_holdoff > 0) {                  
358                 VERBOSE_TOROUT_STRING("torture    
359                 torture_hrtimeout_jiffies(onof    
360                 VERBOSE_TOROUT_STRING("torture    
361         }                                         
362         while (!torture_must_stop()) {            
363                 if (disable_onoff_at_boot && !    
364                         torture_hrtimeout_jiff    
365                         continue;                 
366                 }                                 
367                 cpu = torture_random(&rand) %     
368                 if (!torture_offline(cpu,         
369                                      &n_offlin    
370                                      &sum_offl    
371                         torture_online(cpu,       
372                                        &n_onli    
373                                        &sum_on    
374                 torture_hrtimeout_jiffies(onof    
375         }                                         
376                                                   
377 stop:                                             
378         torture_kthread_stopping("torture_onof    
379         torture_online_all("Final");              
380         return 0;                                 
381 }                                                 
382                                                   
383 #endif /* #ifdef CONFIG_HOTPLUG_CPU */            
384                                                   
385 /*                                                
386  * Initiate online-offline handling.              
387  */                                               
388 int torture_onoff_init(long ooholdoff, long oo    
389 {                                                 
390 #ifdef CONFIG_HOTPLUG_CPU                         
391         onoff_holdoff = ooholdoff;                
392         onoff_interval = oointerval;              
393         onoff_f = f;                              
394         if (onoff_interval <= 0)                  
395                 return 0;                         
396         return torture_create_kthread(torture_    
397 #else /* #ifdef CONFIG_HOTPLUG_CPU */             
398         return 0;                                 
399 #endif /* #else #ifdef CONFIG_HOTPLUG_CPU */      
400 }                                                 
401 EXPORT_SYMBOL_GPL(torture_onoff_init);            
402                                                   
403 /*                                                
404  * Clean up after online/offline testing.         
405  */                                               
406 static void torture_onoff_cleanup(void)           
407 {                                                 
408 #ifdef CONFIG_HOTPLUG_CPU                         
409         if (onoff_task == NULL)                   
410                 return;                           
411         VERBOSE_TOROUT_STRING("Stopping tortur    
412         kthread_stop(onoff_task);                 
413         onoff_task = NULL;                        
414 #endif /* #ifdef CONFIG_HOTPLUG_CPU */            
415 }                                                 
416                                                   
417 /*                                                
418  * Print online/offline testing statistics.       
419  */                                               
420 void torture_onoff_stats(void)                    
421 {                                                 
422 #ifdef CONFIG_HOTPLUG_CPU                         
423         pr_cont("onoff: %ld/%ld:%ld/%ld %d,%d:    
424                 n_online_successes, n_online_a    
425                 n_offline_successes, n_offline    
426                 min_online, max_online,           
427                 min_offline, max_offline,         
428                 sum_online, sum_offline, HZ);     
429 #endif /* #ifdef CONFIG_HOTPLUG_CPU */            
430 }                                                 
431 EXPORT_SYMBOL_GPL(torture_onoff_stats);           
432                                                   
433 /*                                                
434  * Were all the online/offline operations succ    
435  */                                               
436 bool torture_onoff_failures(void)                 
437 {                                                 
438 #ifdef CONFIG_HOTPLUG_CPU                         
439         return n_online_successes != n_online_    
440                n_offline_successes != n_offlin    
441 #else /* #ifdef CONFIG_HOTPLUG_CPU */             
442         return false;                             
443 #endif /* #else #ifdef CONFIG_HOTPLUG_CPU */      
444 }                                                 
445 EXPORT_SYMBOL_GPL(torture_onoff_failures);        
446                                                   
447 #define TORTURE_RANDOM_MULT     39916801  /* p    
448 #define TORTURE_RANDOM_ADD      479001701 /* p    
449 #define TORTURE_RANDOM_REFRESH  10000             
450                                                   
451 /*                                                
452  * Crude but fast random-number generator.  Us    
453  * generator, with occasional help from cpu_cl    
454  */                                               
455 unsigned long                                     
456 torture_random(struct torture_random_state *tr    
457 {                                                 
458         if (--trsp->trs_count < 0) {              
459                 trsp->trs_state += (unsigned l    
460                 trsp->trs_count = TORTURE_RAND    
461         }                                         
462         trsp->trs_state = trsp->trs_state * TO    
463                 TORTURE_RANDOM_ADD;               
464         return swahw32(trsp->trs_state);          
465 }                                                 
466 EXPORT_SYMBOL_GPL(torture_random);                
467                                                   
468 /*                                                
469  * Variables for shuffling.  The idea is to en    
470  * idle for an extended period to test interac    
471  * as well as interactions with any per-CPU va    
472  */                                               
473 struct shuffle_task {                             
474         struct list_head st_l;                    
475         struct task_struct *st_t;                 
476 };                                                
477                                                   
478 static long shuffle_interval;   /* In jiffies.    
479 static struct task_struct *shuffler_task;         
480 static cpumask_var_t shuffle_tmp_mask;            
481 static int shuffle_idle_cpu;    /* Force all t    
482 static struct list_head shuffle_task_list = LI    
483 static DEFINE_MUTEX(shuffle_task_mutex);          
484                                                   
485 /*                                                
486  * Register a task to be shuffled.  If there i    
487  * and don't bother registering.                  
488  */                                               
489 void torture_shuffle_task_register(struct task    
490 {                                                 
491         struct shuffle_task *stp;                 
492                                                   
493         if (WARN_ON_ONCE(tp == NULL))             
494                 return;                           
495         stp = kmalloc(sizeof(*stp), GFP_KERNEL    
496         if (WARN_ON_ONCE(stp == NULL))            
497                 return;                           
498         stp->st_t = tp;                           
499         mutex_lock(&shuffle_task_mutex);          
500         list_add(&stp->st_l, &shuffle_task_lis    
501         mutex_unlock(&shuffle_task_mutex);        
502 }                                                 
503 EXPORT_SYMBOL_GPL(torture_shuffle_task_registe    
504                                                   
505 /*                                                
506  * Unregister all tasks, for example, at the e    
507  */                                               
508 static void torture_shuffle_task_unregister_al    
509 {                                                 
510         struct shuffle_task *stp;                 
511         struct shuffle_task *p;                   
512                                                   
513         mutex_lock(&shuffle_task_mutex);          
514         list_for_each_entry_safe(stp, p, &shuf    
515                 list_del(&stp->st_l);             
516                 kfree(stp);                       
517         }                                         
518         mutex_unlock(&shuffle_task_mutex);        
519 }                                                 
520                                                   
521 /* Shuffle tasks such that we allow shuffle_id    
522  * A special case is when shuffle_idle_cpu = -    
523  * the tasks to run on all CPUs.                  
524  */                                               
525 static void torture_shuffle_tasks(struct tortu    
526 {                                                 
527         struct shuffle_task *stp;                 
528                                                   
529         cpumask_setall(shuffle_tmp_mask);         
530         cpus_read_lock();                         
531                                                   
532         /* No point in shuffling if there is o    
533         if (num_online_cpus() == 1) {             
534                 cpus_read_unlock();               
535                 return;                           
536         }                                         
537                                                   
538         /* Advance to the next CPU.  Upon over    
539         shuffle_idle_cpu = cpumask_next(shuffl    
540         if (shuffle_idle_cpu >= nr_cpu_ids)       
541                 shuffle_idle_cpu = -1;            
542         else                                      
543                 cpumask_clear_cpu(shuffle_idle    
544                                                   
545         mutex_lock(&shuffle_task_mutex);          
546         list_for_each_entry(stp, &shuffle_task    
547                 if (!random_shuffle || torture    
548                         set_cpus_allowed_ptr(s    
549         }                                         
550         mutex_unlock(&shuffle_task_mutex);        
551                                                   
552         cpus_read_unlock();                       
553 }                                                 
554                                                   
555 /* Shuffle tasks across CPUs, with the intent     
556  * system to become idle at a time and cut off    
557  * to test the support for such tickless idle     
558  */                                               
559 static int torture_shuffle(void *arg)             
560 {                                                 
561         DEFINE_TORTURE_RANDOM(rand);              
562                                                   
563         VERBOSE_TOROUT_STRING("torture_shuffle    
564         do {                                      
565                 torture_hrtimeout_jiffies(shuf    
566                 torture_shuffle_tasks(&rand);     
567                 torture_shutdown_absorb("tortu    
568         } while (!torture_must_stop());           
569         torture_kthread_stopping("torture_shuf    
570         return 0;                                 
571 }                                                 
572                                                   
573 /*                                                
574  * Start the shuffler, with shuffint in jiffie    
575  */                                               
576 int torture_shuffle_init(long shuffint)           
577 {                                                 
578         shuffle_interval = shuffint;              
579                                                   
580         shuffle_idle_cpu = -1;                    
581                                                   
582         if (!alloc_cpumask_var(&shuffle_tmp_ma    
583                 TOROUT_ERRSTRING("Failed to al    
584                 return -ENOMEM;                   
585         }                                         
586                                                   
587         /* Create the shuffler thread */          
588         return torture_create_kthread(torture_    
589 }                                                 
590 EXPORT_SYMBOL_GPL(torture_shuffle_init);          
591                                                   
592 /*                                                
593  * Stop the shuffling.                            
594  */                                               
595 static void torture_shuffle_cleanup(void)         
596 {                                                 
597         torture_shuffle_task_unregister_all();    
598         if (shuffler_task) {                      
599                 VERBOSE_TOROUT_STRING("Stoppin    
600                 kthread_stop(shuffler_task);      
601                 free_cpumask_var(shuffle_tmp_m    
602         }                                         
603         shuffler_task = NULL;                     
604 }                                                 
605                                                   
606 /*                                                
607  * Variables for auto-shutdown.  This allows "    
608  * to be fully scripted.                          
609  */                                               
610 static struct task_struct *shutdown_task;         
611 static ktime_t shutdown_time;           /* tim    
612 static void (*torture_shutdown_hook)(void);       
613                                                   
614 /*                                                
615  * Absorb kthreads into a kernel function that    
616  * they won't ever access module text or data     
617  */                                               
618 void torture_shutdown_absorb(const char *title    
619 {                                                 
620         while (READ_ONCE(fullstop) == FULLSTOP    
621                 pr_notice("torture thread %s p    
622                           title);                 
623                 schedule_timeout_uninterruptib    
624         }                                         
625 }                                                 
626 EXPORT_SYMBOL_GPL(torture_shutdown_absorb);       
627                                                   
628 /*                                                
629  * Cause the torture test to shutdown the syst    
630  * run for the time specified by the shutdown_    
631  */                                               
632 static int torture_shutdown(void *arg)            
633 {                                                 
634         ktime_t ktime_snap;                       
635                                                   
636         VERBOSE_TOROUT_STRING("torture_shutdow    
637         ktime_snap = ktime_get();                 
638         while (ktime_before(ktime_snap, shutdo    
639                !torture_must_stop()) {            
640                 if (verbose)                      
641                         pr_alert("%s" TORTURE_    
642                                  "torture_shut    
643                                  torture_type,    
644                                  ktime_ms_delt    
645                 set_current_state(TASK_INTERRU    
646                 schedule_hrtimeout(&shutdown_t    
647                 ktime_snap = ktime_get();         
648         }                                         
649         if (torture_must_stop()) {                
650                 torture_kthread_stopping("tort    
651                 return 0;                         
652         }                                         
653                                                   
654         /* OK, shut down the system. */           
655                                                   
656         VERBOSE_TOROUT_STRING("torture_shutdow    
657         shutdown_task = NULL;   /* Avoid self-    
658         if (torture_shutdown_hook)                
659                 torture_shutdown_hook();          
660         else                                      
661                 VERBOSE_TOROUT_STRING("No tort    
662         if (ftrace_dump_at_shutdown)              
663                 rcu_ftrace_dump(DUMP_ALL);        
664         kernel_power_off();     /* Shut down t    
665         return 0;                                 
666 }                                                 
667                                                   
668 /*                                                
669  * Start up the shutdown task.                    
670  */                                               
671 int torture_shutdown_init(int ssecs, void (*cl    
672 {                                                 
673         torture_shutdown_hook = cleanup;          
674         if (ssecs > 0) {                          
675                 shutdown_time = ktime_add(ktim    
676                 return torture_create_kthread(    
677                                                   
678         }                                         
679         return 0;                                 
680 }                                                 
681 EXPORT_SYMBOL_GPL(torture_shutdown_init);         
682                                                   
683 /*                                                
684  * Detect and respond to a system shutdown.       
685  */                                               
686 static int torture_shutdown_notify(struct noti    
687                                    unsigned lo    
688 {                                                 
689         mutex_lock(&fullstop_mutex);              
690         if (READ_ONCE(fullstop) == FULLSTOP_DO    
691                 VERBOSE_TOROUT_STRING("Unsched    
692                 WRITE_ONCE(fullstop, FULLSTOP_    
693         } else {                                  
694                 pr_warn("Concurrent rmmod and     
695         }                                         
696         mutex_unlock(&fullstop_mutex);            
697         return NOTIFY_DONE;                       
698 }                                                 
699                                                   
700 static struct notifier_block torture_shutdown_    
701         .notifier_call = torture_shutdown_noti    
702 };                                                
703                                                   
704 /*                                                
705  * Shut down the shutdown task.  Say what???      
706  * the torture module gets an rmmod before the    
707  */                                               
708 static void torture_shutdown_cleanup(void)        
709 {                                                 
710         unregister_reboot_notifier(&torture_sh    
711         if (shutdown_task != NULL) {              
712                 VERBOSE_TOROUT_STRING("Stoppin    
713                 kthread_stop(shutdown_task);      
714         }                                         
715         shutdown_task = NULL;                     
716 }                                                 
717                                                   
718 /*                                                
719  * Variables for stuttering, which means to pe    
720  * restart testing in order to catch bugs that    
721  * suddenly applied to or removed from the sys    
722  */                                               
723 static struct task_struct *stutter_task;          
724 static ktime_t stutter_till_abs_time;             
725 static int stutter;                               
726 static int stutter_gap;                           
727                                                   
728 /*                                                
729  * Block until the stutter interval ends.  Thi    
730  * by all running kthreads that need to be sub    
731  */                                               
732 bool stutter_wait(const char *title)              
733 {                                                 
734         bool ret = false;                         
735         ktime_t till_ns;                          
736                                                   
737         cond_resched_tasks_rcu_qs();              
738         till_ns = READ_ONCE(stutter_till_abs_t    
739         if (till_ns && ktime_before(ktime_get(    
740                 torture_hrtimeout_ns(till_ns,     
741                 ret = true;                       
742         }                                         
743         torture_shutdown_absorb(title);           
744         return ret;                               
745 }                                                 
746 EXPORT_SYMBOL_GPL(stutter_wait);                  
747                                                   
748 /*                                                
749  * Cause the torture test to "stutter", starti    
750  * threads periodically.                          
751  */                                               
752 static int torture_stutter(void *arg)             
753 {                                                 
754         ktime_t till_ns;                          
755                                                   
756         VERBOSE_TOROUT_STRING("torture_stutter    
757         do {                                      
758                 if (!torture_must_stop() && st    
759                         till_ns = ktime_add_ns    
760                                                   
761                         WRITE_ONCE(stutter_til    
762                         torture_hrtimeout_jiff    
763                 }                                 
764                 if (!torture_must_stop())         
765                         torture_hrtimeout_jiff    
766                 torture_shutdown_absorb("tortu    
767         } while (!torture_must_stop());           
768         torture_kthread_stopping("torture_stut    
769         return 0;                                 
770 }                                                 
771                                                   
772 /*                                                
773  * Initialize and kick off the torture_stutter    
774  */                                               
775 int torture_stutter_init(const int s, const in    
776 {                                                 
777         stutter = s;                              
778         stutter_gap = sgap;                       
779         return torture_create_kthread(torture_    
780 }                                                 
781 EXPORT_SYMBOL_GPL(torture_stutter_init);          
782                                                   
783 /*                                                
784  * Cleanup after the torture_stutter kthread.     
785  */                                               
786 static void torture_stutter_cleanup(void)         
787 {                                                 
788         if (!stutter_task)                        
789                 return;                           
790         VERBOSE_TOROUT_STRING("Stopping tortur    
791         kthread_stop(stutter_task);               
792         stutter_task = NULL;                      
793 }                                                 
794                                                   
795 static void                                       
796 torture_print_module_parms(void)                  
797 {                                                 
798         pr_alert("torture module --- %s:  disa    
799                  torture_type, disable_onoff_a    
800 }                                                 
801                                                   
802 /*                                                
803  * Initialize torture module.  Please note tha    
804  * the usual module_init() mechanism, but rath    
805  * the client torture module.  This call must     
806  * torture_init_end().                            
807  *                                                
808  * The runnable parameter points to a flag tha    
809  * the test is currently runnable.  If there i    
810  */                                               
811 bool torture_init_begin(char *ttype, int v)       
812 {                                                 
813         mutex_lock(&fullstop_mutex);              
814         if (torture_type != NULL) {               
815                 pr_alert("%s: Refusing %s init    
816                           __func__, ttype, tor    
817                 pr_alert("%s: One torture test    
818                 mutex_unlock(&fullstop_mutex);    
819                 return false;                     
820         }                                         
821         torture_type = ttype;                     
822         verbose = v;                              
823         fullstop = FULLSTOP_DONTSTOP;             
824         torture_print_module_parms();             
825         return true;                              
826 }                                                 
827 EXPORT_SYMBOL_GPL(torture_init_begin);            
828                                                   
829 /*                                                
830  * Tell the torture module that initialization    
831  */                                               
832 void torture_init_end(void)                       
833 {                                                 
834         mutex_unlock(&fullstop_mutex);            
835         register_reboot_notifier(&torture_shut    
836 }                                                 
837 EXPORT_SYMBOL_GPL(torture_init_end);              
838                                                   
839 /*                                                
840  * Clean up torture module.  Please note that     
841  * the usual module_exit() mechanism, but rath    
842  * the client torture module.  Returns true if    
843  * is detected, otherwise, all kthreads starte    
844  * will be shut down.                             
845  *                                                
846  * This must be called before the caller start    
847  * kthreads.                                      
848  *                                                
849  * Both torture_cleanup_begin() and torture_cl    
850  * in order to correctly perform the cleanup.     
851  * threads can still need to reference the tor    
852  * only after completing all other relevant ca    
853  */                                               
854 bool torture_cleanup_begin(void)                  
855 {                                                 
856         mutex_lock(&fullstop_mutex);              
857         if (READ_ONCE(fullstop) == FULLSTOP_SH    
858                 pr_warn("Concurrent rmmod and     
859                 mutex_unlock(&fullstop_mutex);    
860                 schedule_timeout_uninterruptib    
861                 return true;                      
862         }                                         
863         WRITE_ONCE(fullstop, FULLSTOP_RMMOD);     
864         mutex_unlock(&fullstop_mutex);            
865         torture_shutdown_cleanup();               
866         torture_shuffle_cleanup();                
867         torture_stutter_cleanup();                
868         torture_onoff_cleanup();                  
869         return false;                             
870 }                                                 
871 EXPORT_SYMBOL_GPL(torture_cleanup_begin);         
872                                                   
873 void torture_cleanup_end(void)                    
874 {                                                 
875         mutex_lock(&fullstop_mutex);              
876         torture_type = NULL;                      
877         mutex_unlock(&fullstop_mutex);            
878 }                                                 
879 EXPORT_SYMBOL_GPL(torture_cleanup_end);           
880                                                   
881 /*                                                
882  * Is it time for the current torture test to     
883  */                                               
884 bool torture_must_stop(void)                      
885 {                                                 
886         return torture_must_stop_irq() || kthr    
887 }                                                 
888 EXPORT_SYMBOL_GPL(torture_must_stop);             
889                                                   
890 /*                                                
891  * Is it time for the current torture test to     
892  * version, hence no check for kthread_should_    
893  */                                               
894 bool torture_must_stop_irq(void)                  
895 {                                                 
896         return READ_ONCE(fullstop) != FULLSTOP    
897 }                                                 
898 EXPORT_SYMBOL_GPL(torture_must_stop_irq);         
899                                                   
900 /*                                                
901  * Each kthread must wait for kthread_should_s    
902  * its top-level function, otherwise segfaults    
903  * prints a "stopping" message and waits for k    
904  * should be called from all torture kthreads     
905  * returning.                                     
906  */                                               
907 void torture_kthread_stopping(char *title)        
908 {                                                 
909         char buf[128];                            
910                                                   
911         snprintf(buf, sizeof(buf), "%s is stop    
912         VERBOSE_TOROUT_STRING(buf);               
913         while (!kthread_should_stop()) {          
914                 torture_shutdown_absorb(title)    
915                 schedule_timeout_uninterruptib    
916         }                                         
917 }                                                 
918 EXPORT_SYMBOL_GPL(torture_kthread_stopping);      
919                                                   
920 /*                                                
921  * Create a generic torture kthread that is im    
922  * need the kthread to be stopped so that you     
923  * it starts, you will need to open-code your     
924  */                                               
925 int _torture_create_kthread(int (*fn)(void *ar    
926                             char *f, struct ta    
927 {                                                 
928         int ret = 0;                              
929                                                   
930         VERBOSE_TOROUT_STRING(m);                 
931         *tp = kthread_create(fn, arg, "%s", s)    
932         if (IS_ERR(*tp)) {                        
933                 ret = PTR_ERR(*tp);               
934                 TOROUT_ERRSTRING(f);              
935                 *tp = NULL;                       
936                 return ret;                       
937         }                                         
938                                                   
939         if (cbf)                                  
940                 cbf(*tp);                         
941                                                   
942         wake_up_process(*tp);  // Process is s    
943         torture_shuffle_task_register(*tp);       
944         return ret;                               
945 }                                                 
946 EXPORT_SYMBOL_GPL(_torture_create_kthread);       
947                                                   
948 /*                                                
949  * Stop a generic kthread, emitting a message.    
950  */                                               
951 void _torture_stop_kthread(char *m, struct tas    
952 {                                                 
953         if (*tp == NULL)                          
954                 return;                           
955         VERBOSE_TOROUT_STRING(m);                 
956         kthread_stop(*tp);                        
957         *tp = NULL;                               
958 }                                                 
959 EXPORT_SYMBOL_GPL(_torture_stop_kthread);         
960                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php