diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-01-31 14:57:43 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-02-23 12:02:54 -0500 |
commit | 628edaa5062282b6e3d76c886fd2cbccae5cb87b (patch) | |
tree | a21fe0f1b950f18859e8808b93fa4de57d05ffdd /kernel/rcu | |
parent | fac480efcba6a9f0aea91947f151fd569538b0af (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.c | 69 |
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; | |||
103 | static struct task_struct **fakewriter_tasks; | 103 | static struct task_struct **fakewriter_tasks; |
104 | static struct task_struct **reader_tasks; | 104 | static struct task_struct **reader_tasks; |
105 | static struct task_struct *stats_task; | 105 | static struct task_struct *stats_task; |
106 | static struct task_struct *stutter_task; | ||
107 | static struct task_struct *fqs_task; | 106 | static struct task_struct *fqs_task; |
108 | static struct task_struct *boost_tasks[NR_CPUS]; | 107 | static struct task_struct *boost_tasks[NR_CPUS]; |
109 | static struct task_struct *shutdown_task; | 108 | static struct task_struct *shutdown_task; |
@@ -145,8 +144,6 @@ static long n_barrier_attempts; | |||
145 | static long n_barrier_successes; | 144 | static long n_barrier_successes; |
146 | static struct list_head rcu_torture_removed; | 145 | static struct list_head rcu_torture_removed; |
147 | 146 | ||
148 | static 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 | ||
225 | static void | ||
226 | rcu_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. */ |
621 | checkwait: rcu_stutter_wait("rcu_torture_boost"); | 606 | checkwait: 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 | */ | ||
1040 | static int | ||
1041 | rcu_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 | |||
1056 | static inline void | 1022 | static inline void |
1057 | rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) | 1023 | rcu_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)) { |