aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/rcutorture.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-01-29 10:40:27 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-02-23 12:01:04 -0500
commitf67a33561e6e5463b548219df98130da95f2e4a7 (patch)
tree6cdbf7152900045acb4f0f9d5426f995adf0ba66 /kernel/rcu/rcutorture.c
parentc2884de38e01134ae040d55aa5644049d1bb850f (diff)
rcutorture: Abstract torture_shutdown_absorb()
Because handling races between rmmod and normal shutdown is not specific to rcutorture, this commit renames rcutorture_shutdown_absorb() to torture_shutdown_absorb() and pulls it out into then kernel/torture.c module. This implies pulling the fullstop mechanism into kernel/torture.c as well. The exporting of fullstop and fullstop_mutex is ugly and must die. And it does in fact die in later commits that introduce higher-level APIs that encapsulate both of these variables. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>`
Diffstat (limited to 'kernel/rcu/rcutorture.c')
-rw-r--r--kernel/rcu/rcutorture.c57
1 files changed, 18 insertions, 39 deletions
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 86fd8c11257b..a868758a6f9c 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -91,11 +91,15 @@ torture_param(int, test_boost_interval, 7,
91 "Interval between boost tests, seconds."); 91 "Interval between boost tests, seconds.");
92torture_param(bool, test_no_idle_hz, true, 92torture_param(bool, test_no_idle_hz, true,
93 "Test support for tickless idle CPUs"); 93 "Test support for tickless idle CPUs");
94torture_param(bool, verbose, false, "Enable verbose debugging printk()s");
95 94
96static char *torture_type = "rcu"; 95char *torture_type = "rcu";
96EXPORT_SYMBOL_GPL(torture_type);
97module_param(torture_type, charp, 0444); 97module_param(torture_type, charp, 0444);
98MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, ...)"); 98MODULE_PARM_DESC(torture_type, "Type of RCU to torture (rcu, rcu_bh, ...)");
99bool verbose;
100EXPORT_SYMBOL_GPL(verbose);
101module_param(verbose, bool, 0444);
102MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
99 103
100static int nrealreaders; 104static int nrealreaders;
101static struct task_struct *writer_task; 105static struct task_struct *writer_task;
@@ -200,17 +204,6 @@ static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */
200static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */ 204static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */
201static DECLARE_WAIT_QUEUE_HEAD(barrier_wq); 205static DECLARE_WAIT_QUEUE_HEAD(barrier_wq);
202 206
203/* Mediate rmmod and system shutdown. Concurrent rmmod & shutdown illegal! */
204
205#define FULLSTOP_DONTSTOP 0 /* Normal operation. */
206#define FULLSTOP_SHUTDOWN 1 /* System shutdown with rcutorture running. */
207#define FULLSTOP_RMMOD 2 /* Normal rmmod of rcutorture. */
208static int fullstop = FULLSTOP_RMMOD;
209/*
210 * Protect fullstop transitions and spawning of kthreads.
211 */
212static DEFINE_MUTEX(fullstop_mutex);
213
214/* Forward reference. */ 207/* Forward reference. */
215static void rcu_torture_cleanup(void); 208static void rcu_torture_cleanup(void);
216 209
@@ -232,20 +225,6 @@ rcutorture_shutdown_notify(struct notifier_block *unused1,
232} 225}
233 226
234/* 227/*
235 * Absorb kthreads into a kernel function that won't return, so that
236 * they won't ever access module text or data again.
237 */
238static void rcutorture_shutdown_absorb(const char *title)
239{
240 if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
241 pr_notice(
242 "rcutorture thread %s parking due to system shutdown\n",
243 title);
244 schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
245 }
246}
247
248/*
249 * Allocate an element from the rcu_tortures pool. 228 * Allocate an element from the rcu_tortures pool.
250 */ 229 */
251static struct rcu_torture * 230static struct rcu_torture *
@@ -286,7 +265,7 @@ rcu_stutter_wait(const char *title)
286 schedule_timeout_interruptible(1); 265 schedule_timeout_interruptible(1);
287 else 266 else
288 schedule_timeout_interruptible(round_jiffies_relative(HZ)); 267 schedule_timeout_interruptible(round_jiffies_relative(HZ));
289 rcutorture_shutdown_absorb(title); 268 torture_shutdown_absorb(title);
290 } 269 }
291} 270}
292 271
@@ -681,7 +660,7 @@ checkwait: rcu_stutter_wait("rcu_torture_boost");
681 660
682 /* Clean up and exit. */ 661 /* Clean up and exit. */
683 VERBOSE_TOROUT_STRING("rcu_torture_boost task stopping"); 662 VERBOSE_TOROUT_STRING("rcu_torture_boost task stopping");
684 rcutorture_shutdown_absorb("rcu_torture_boost"); 663 torture_shutdown_absorb("rcu_torture_boost");
685 while (!kthread_should_stop() || rbi.inflight) 664 while (!kthread_should_stop() || rbi.inflight)
686 schedule_timeout_uninterruptible(1); 665 schedule_timeout_uninterruptible(1);
687 smp_mb(); /* order accesses to ->inflight before stack-frame death. */ 666 smp_mb(); /* order accesses to ->inflight before stack-frame death. */
@@ -717,7 +696,7 @@ rcu_torture_fqs(void *arg)
717 rcu_stutter_wait("rcu_torture_fqs"); 696 rcu_stutter_wait("rcu_torture_fqs");
718 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); 697 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
719 VERBOSE_TOROUT_STRING("rcu_torture_fqs task stopping"); 698 VERBOSE_TOROUT_STRING("rcu_torture_fqs task stopping");
720 rcutorture_shutdown_absorb("rcu_torture_fqs"); 699 torture_shutdown_absorb("rcu_torture_fqs");
721 while (!kthread_should_stop()) 700 while (!kthread_should_stop())
722 schedule_timeout_uninterruptible(1); 701 schedule_timeout_uninterruptible(1);
723 return 0; 702 return 0;
@@ -789,7 +768,7 @@ rcu_torture_writer(void *arg)
789 rcu_stutter_wait("rcu_torture_writer"); 768 rcu_stutter_wait("rcu_torture_writer");
790 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); 769 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
791 VERBOSE_TOROUT_STRING("rcu_torture_writer task stopping"); 770 VERBOSE_TOROUT_STRING("rcu_torture_writer task stopping");
792 rcutorture_shutdown_absorb("rcu_torture_writer"); 771 torture_shutdown_absorb("rcu_torture_writer");
793 while (!kthread_should_stop()) 772 while (!kthread_should_stop())
794 schedule_timeout_uninterruptible(1); 773 schedule_timeout_uninterruptible(1);
795 return 0; 774 return 0;
@@ -827,7 +806,7 @@ rcu_torture_fakewriter(void *arg)
827 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); 806 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
828 807
829 VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task stopping"); 808 VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task stopping");
830 rcutorture_shutdown_absorb("rcu_torture_fakewriter"); 809 torture_shutdown_absorb("rcu_torture_fakewriter");
831 while (!kthread_should_stop()) 810 while (!kthread_should_stop())
832 schedule_timeout_uninterruptible(1); 811 schedule_timeout_uninterruptible(1);
833 return 0; 812 return 0;
@@ -971,7 +950,7 @@ rcu_torture_reader(void *arg)
971 rcu_stutter_wait("rcu_torture_reader"); 950 rcu_stutter_wait("rcu_torture_reader");
972 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); 951 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
973 VERBOSE_TOROUT_STRING("rcu_torture_reader task stopping"); 952 VERBOSE_TOROUT_STRING("rcu_torture_reader task stopping");
974 rcutorture_shutdown_absorb("rcu_torture_reader"); 953 torture_shutdown_absorb("rcu_torture_reader");
975 if (irqreader && cur_ops->irq_capable) 954 if (irqreader && cur_ops->irq_capable)
976 del_timer_sync(&t); 955 del_timer_sync(&t);
977 while (!kthread_should_stop()) 956 while (!kthread_should_stop())
@@ -1095,7 +1074,7 @@ rcu_torture_stats(void *arg)
1095 do { 1074 do {
1096 schedule_timeout_interruptible(stat_interval * HZ); 1075 schedule_timeout_interruptible(stat_interval * HZ);
1097 rcu_torture_stats_print(); 1076 rcu_torture_stats_print();
1098 rcutorture_shutdown_absorb("rcu_torture_stats"); 1077 torture_shutdown_absorb("rcu_torture_stats");
1099 } while (!kthread_should_stop()); 1078 } while (!kthread_should_stop());
1100 VERBOSE_TOROUT_STRING("rcu_torture_stats task stopping"); 1079 VERBOSE_TOROUT_STRING("rcu_torture_stats task stopping");
1101 return 0; 1080 return 0;
@@ -1179,7 +1158,7 @@ rcu_torture_shuffle(void *arg)
1179 do { 1158 do {
1180 schedule_timeout_interruptible(shuffle_interval * HZ); 1159 schedule_timeout_interruptible(shuffle_interval * HZ);
1181 rcu_torture_shuffle_tasks(); 1160 rcu_torture_shuffle_tasks();
1182 rcutorture_shutdown_absorb("rcu_torture_shuffle"); 1161 torture_shutdown_absorb("rcu_torture_shuffle");
1183 } while (!kthread_should_stop()); 1162 } while (!kthread_should_stop());
1184 VERBOSE_TOROUT_STRING("rcu_torture_shuffle task stopping"); 1163 VERBOSE_TOROUT_STRING("rcu_torture_shuffle task stopping");
1185 return 0; 1164 return 0;
@@ -1198,7 +1177,7 @@ rcu_torture_stutter(void *arg)
1198 if (!kthread_should_stop()) 1177 if (!kthread_should_stop())
1199 schedule_timeout_interruptible(stutter * HZ); 1178 schedule_timeout_interruptible(stutter * HZ);
1200 stutter_pause_test = 0; 1179 stutter_pause_test = 0;
1201 rcutorture_shutdown_absorb("rcu_torture_stutter"); 1180 torture_shutdown_absorb("rcu_torture_stutter");
1202 } while (!kthread_should_stop()); 1181 } while (!kthread_should_stop());
1203 VERBOSE_TOROUT_STRING("rcu_torture_stutter task stopping"); 1182 VERBOSE_TOROUT_STRING("rcu_torture_stutter task stopping");
1204 return 0; 1183 return 0;
@@ -1470,7 +1449,7 @@ static int rcu_torture_stall(void *args)
1470 rcu_read_unlock(); 1449 rcu_read_unlock();
1471 pr_alert("rcu_torture_stall end.\n"); 1450 pr_alert("rcu_torture_stall end.\n");
1472 } 1451 }
1473 rcutorture_shutdown_absorb("rcu_torture_stall"); 1452 torture_shutdown_absorb("rcu_torture_stall");
1474 while (!kthread_should_stop()) 1453 while (!kthread_should_stop())
1475 schedule_timeout_interruptible(10 * HZ); 1454 schedule_timeout_interruptible(10 * HZ);
1476 return 0; 1455 return 0;
@@ -1534,7 +1513,7 @@ static int rcu_torture_barrier_cbs(void *arg)
1534 wake_up(&barrier_wq); 1513 wake_up(&barrier_wq);
1535 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); 1514 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
1536 VERBOSE_TOROUT_STRING("rcu_torture_barrier_cbs task stopping"); 1515 VERBOSE_TOROUT_STRING("rcu_torture_barrier_cbs task stopping");
1537 rcutorture_shutdown_absorb("rcu_torture_barrier_cbs"); 1516 torture_shutdown_absorb("rcu_torture_barrier_cbs");
1538 while (!kthread_should_stop()) 1517 while (!kthread_should_stop())
1539 schedule_timeout_interruptible(1); 1518 schedule_timeout_interruptible(1);
1540 cur_ops->cb_barrier(); 1519 cur_ops->cb_barrier();
@@ -1571,7 +1550,7 @@ static int rcu_torture_barrier(void *arg)
1571 schedule_timeout_interruptible(HZ / 10); 1550 schedule_timeout_interruptible(HZ / 10);
1572 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); 1551 } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
1573 VERBOSE_TOROUT_STRING("rcu_torture_barrier task stopping"); 1552 VERBOSE_TOROUT_STRING("rcu_torture_barrier task stopping");
1574 rcutorture_shutdown_absorb("rcu_torture_barrier"); 1553 torture_shutdown_absorb("rcu_torture_barrier");
1575 while (!kthread_should_stop()) 1554 while (!kthread_should_stop())
1576 schedule_timeout_interruptible(1); 1555 schedule_timeout_interruptible(1);
1577 return 0; 1556 return 0;