aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-01-31 14:57:43 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-02-23 12:02:54 -0500
commit628edaa5062282b6e3d76c886fd2cbccae5cb87b (patch)
treea21fe0f1b950f18859e8808b93fa4de57d05ffdd /kernel/rcu
parentfac480efcba6a9f0aea91947f151fd569538b0af (diff)
rcutorture: Abstract stutter_wait()
Because stuttering the test load (stopping and restarting it) is useful for non-RCU testing, this commit moves the load-stuttering functionality to kernel/torture.c. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcu')
-rw-r--r--kernel/rcu/rcutorture.c69
1 files changed, 12 insertions, 57 deletions
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 9357c88cc8cc..4329ad14f8dc 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -103,7 +103,6 @@ static struct task_struct *writer_task;
103static struct task_struct **fakewriter_tasks; 103static struct task_struct **fakewriter_tasks;
104static struct task_struct **reader_tasks; 104static struct task_struct **reader_tasks;
105static struct task_struct *stats_task; 105static struct task_struct *stats_task;
106static struct task_struct *stutter_task;
107static struct task_struct *fqs_task; 106static struct task_struct *fqs_task;
108static struct task_struct *boost_tasks[NR_CPUS]; 107static struct task_struct *boost_tasks[NR_CPUS];
109static struct task_struct *shutdown_task; 108static struct task_struct *shutdown_task;
@@ -145,8 +144,6 @@ static long n_barrier_attempts;
145static long n_barrier_successes; 144static long n_barrier_successes;
146static struct list_head rcu_torture_removed; 145static struct list_head rcu_torture_removed;
147 146
148static int stutter_pause_test;
149
150#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE) 147#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE)
151#define RCUTORTURE_RUNNABLE_INIT 1 148#define RCUTORTURE_RUNNABLE_INIT 1
152#else 149#else
@@ -222,18 +219,6 @@ rcu_torture_free(struct rcu_torture *p)
222 spin_unlock_bh(&rcu_torture_lock); 219 spin_unlock_bh(&rcu_torture_lock);
223} 220}
224 221
225static void
226rcu_stutter_wait(const char *title)
227{
228 while (stutter_pause_test || !rcutorture_runnable) {
229 if (rcutorture_runnable)
230 schedule_timeout_interruptible(1);
231 else
232 schedule_timeout_interruptible(round_jiffies_relative(HZ));
233 torture_shutdown_absorb(title);
234 }
235}
236
237/* 222/*
238 * Operations vector for selecting different types of tests. 223 * Operations vector for selecting different types of tests.
239 */ 224 */
@@ -571,7 +556,7 @@ static int rcu_torture_boost(void *arg)
571 oldstarttime = boost_starttime; 556 oldstarttime = boost_starttime;
572 while (ULONG_CMP_LT(jiffies, oldstarttime)) { 557 while (ULONG_CMP_LT(jiffies, oldstarttime)) {
573 schedule_timeout_interruptible(oldstarttime - jiffies); 558 schedule_timeout_interruptible(oldstarttime - jiffies);
574 rcu_stutter_wait("rcu_torture_boost"); 559 stutter_wait("rcu_torture_boost");
575 if (torture_must_stop()) 560 if (torture_must_stop())
576 goto checkwait; 561 goto checkwait;
577 } 562 }
@@ -593,7 +578,7 @@ static int rcu_torture_boost(void *arg)
593 call_rcu_time = jiffies; 578 call_rcu_time = jiffies;
594 } 579 }
595 cond_resched(); 580 cond_resched();
596 rcu_stutter_wait("rcu_torture_boost"); 581 stutter_wait("rcu_torture_boost");
597 if (torture_must_stop()) 582 if (torture_must_stop())
598 goto checkwait; 583 goto checkwait;
599 } 584 }
@@ -618,7 +603,7 @@ static int rcu_torture_boost(void *arg)
618 } 603 }
619 604
620 /* Go do the stutter. */ 605 /* Go do the stutter. */
621checkwait: rcu_stutter_wait("rcu_torture_boost"); 606checkwait: stutter_wait("rcu_torture_boost");
622 } while (!torture_must_stop()); 607 } while (!torture_must_stop());
623 608
624 /* Clean up and exit. */ 609 /* Clean up and exit. */
@@ -656,7 +641,7 @@ rcu_torture_fqs(void *arg)
656 udelay(fqs_holdoff); 641 udelay(fqs_holdoff);
657 fqs_burst_remaining -= fqs_holdoff; 642 fqs_burst_remaining -= fqs_holdoff;
658 } 643 }
659 rcu_stutter_wait("rcu_torture_fqs"); 644 stutter_wait("rcu_torture_fqs");
660 } while (!torture_must_stop()); 645 } while (!torture_must_stop());
661 VERBOSE_TOROUT_STRING("rcu_torture_fqs task stopping"); 646 VERBOSE_TOROUT_STRING("rcu_torture_fqs task stopping");
662 torture_shutdown_absorb("rcu_torture_fqs"); 647 torture_shutdown_absorb("rcu_torture_fqs");
@@ -728,7 +713,7 @@ rcu_torture_writer(void *arg)
728 } 713 }
729 } 714 }
730 rcutorture_record_progress(++rcu_torture_current_version); 715 rcutorture_record_progress(++rcu_torture_current_version);
731 rcu_stutter_wait("rcu_torture_writer"); 716 stutter_wait("rcu_torture_writer");
732 } while (!torture_must_stop()); 717 } while (!torture_must_stop());
733 VERBOSE_TOROUT_STRING("rcu_torture_writer task stopping"); 718 VERBOSE_TOROUT_STRING("rcu_torture_writer task stopping");
734 torture_shutdown_absorb("rcu_torture_writer"); 719 torture_shutdown_absorb("rcu_torture_writer");
@@ -765,7 +750,7 @@ rcu_torture_fakewriter(void *arg)
765 } else { 750 } else {
766 cur_ops->exp_sync(); 751 cur_ops->exp_sync();
767 } 752 }
768 rcu_stutter_wait("rcu_torture_fakewriter"); 753 stutter_wait("rcu_torture_fakewriter");
769 } while (!torture_must_stop()); 754 } while (!torture_must_stop());
770 755
771 VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task stopping"); 756 VERBOSE_TOROUT_STRING("rcu_torture_fakewriter task stopping");
@@ -910,7 +895,7 @@ rcu_torture_reader(void *arg)
910 preempt_enable(); 895 preempt_enable();
911 cur_ops->readunlock(idx); 896 cur_ops->readunlock(idx);
912 schedule(); 897 schedule();
913 rcu_stutter_wait("rcu_torture_reader"); 898 stutter_wait("rcu_torture_reader");
914 } while (!torture_must_stop()); 899 } while (!torture_must_stop());
915 VERBOSE_TOROUT_STRING("rcu_torture_reader task stopping"); 900 VERBOSE_TOROUT_STRING("rcu_torture_reader task stopping");
916 torture_shutdown_absorb("rcu_torture_reader"); 901 torture_shutdown_absorb("rcu_torture_reader");
@@ -1034,25 +1019,6 @@ rcu_torture_stats(void *arg)
1034 return 0; 1019 return 0;
1035} 1020}
1036 1021
1037/* Cause the rcutorture test to "stutter", starting and stopping all
1038 * threads periodically.
1039 */
1040static int
1041rcu_torture_stutter(void *arg)
1042{
1043 VERBOSE_TOROUT_STRING("rcu_torture_stutter task started");
1044 do {
1045 schedule_timeout_interruptible(stutter * HZ);
1046 stutter_pause_test = 1;
1047 if (!kthread_should_stop())
1048 schedule_timeout_interruptible(stutter * HZ);
1049 stutter_pause_test = 0;
1050 torture_shutdown_absorb("rcu_torture_stutter");
1051 } while (!kthread_should_stop());
1052 VERBOSE_TOROUT_STRING("rcu_torture_stutter task stopping");
1053 return 0;
1054}
1055
1056static inline void 1022static inline void
1057rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) 1023rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
1058{ 1024{
@@ -1403,11 +1369,7 @@ rcu_torture_cleanup(void)
1403 1369
1404 rcu_torture_barrier_cleanup(); 1370 rcu_torture_barrier_cleanup();
1405 rcu_torture_stall_cleanup(); 1371 rcu_torture_stall_cleanup();
1406 if (stutter_task) { 1372 torture_stutter_cleanup();
1407 VERBOSE_TOROUT_STRING("Stopping rcu_torture_stutter task");
1408 kthread_stop(stutter_task);
1409 }
1410 stutter_task = NULL;
1411 1373
1412 if (writer_task) { 1374 if (writer_task) {
1413 VERBOSE_TOROUT_STRING("Stopping rcu_torture_writer task"); 1375 VERBOSE_TOROUT_STRING("Stopping rcu_torture_writer task");
@@ -1548,7 +1510,7 @@ rcu_torture_init(void)
1548 &rcu_ops, &rcu_bh_ops, &srcu_ops, &sched_ops, 1510 &rcu_ops, &rcu_bh_ops, &srcu_ops, &sched_ops,
1549 }; 1511 };
1550 1512
1551 torture_init_begin(torture_type, verbose); 1513 torture_init_begin(torture_type, verbose, &rcutorture_runnable);
1552 1514
1553 /* Process args and tell the world that the torturer is on the job. */ 1515 /* Process args and tell the world that the torturer is on the job. */
1554 for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { 1516 for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
@@ -1682,21 +1644,14 @@ rcu_torture_init(void)
1682 if (stutter < 0) 1644 if (stutter < 0)
1683 stutter = 0; 1645 stutter = 0;
1684 if (stutter) { 1646 if (stutter) {
1685 /* Create the stutter thread */ 1647 firsterr = torture_stutter_init(stutter * HZ);
1686 stutter_task = kthread_run(rcu_torture_stutter, NULL, 1648 if (firsterr)
1687 "rcu_torture_stutter");
1688 if (IS_ERR(stutter_task)) {
1689 firsterr = PTR_ERR(stutter_task);
1690 VERBOSE_TOROUT_ERRSTRING("Failed to create stutter");
1691 stutter_task = NULL;
1692 goto unwind; 1649 goto unwind;
1693 }
1694 torture_shuffle_task_register(stutter_task);
1695 } 1650 }
1696 if (fqs_duration < 0) 1651 if (fqs_duration < 0)
1697 fqs_duration = 0; 1652 fqs_duration = 0;
1698 if (fqs_duration) { 1653 if (fqs_duration) {
1699 /* Create the stutter thread */ 1654 /* Create the fqs thread */
1700 fqs_task = kthread_run(rcu_torture_fqs, NULL, 1655 fqs_task = kthread_run(rcu_torture_fqs, NULL,
1701 "rcu_torture_fqs"); 1656 "rcu_torture_fqs");
1702 if (IS_ERR(fqs_task)) { 1657 if (IS_ERR(fqs_task)) {