diff options
Diffstat (limited to 'kernel/rcutorture.c')
| -rw-r--r-- | kernel/rcutorture.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index 2e2726d790b9..9d8e8fb2515f 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c | |||
| @@ -120,7 +120,7 @@ struct rcu_torture { | |||
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | static LIST_HEAD(rcu_torture_freelist); | 122 | static LIST_HEAD(rcu_torture_freelist); |
| 123 | static struct rcu_torture *rcu_torture_current; | 123 | static struct rcu_torture __rcu *rcu_torture_current; |
| 124 | static long rcu_torture_current_version; | 124 | static long rcu_torture_current_version; |
| 125 | static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN]; | 125 | static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN]; |
| 126 | static DEFINE_SPINLOCK(rcu_torture_lock); | 126 | static DEFINE_SPINLOCK(rcu_torture_lock); |
| @@ -153,8 +153,10 @@ int rcutorture_runnable = RCUTORTURE_RUNNABLE_INIT; | |||
| 153 | #define FULLSTOP_SHUTDOWN 1 /* System shutdown with rcutorture running. */ | 153 | #define FULLSTOP_SHUTDOWN 1 /* System shutdown with rcutorture running. */ |
| 154 | #define FULLSTOP_RMMOD 2 /* Normal rmmod of rcutorture. */ | 154 | #define FULLSTOP_RMMOD 2 /* Normal rmmod of rcutorture. */ |
| 155 | static int fullstop = FULLSTOP_RMMOD; | 155 | static int fullstop = FULLSTOP_RMMOD; |
| 156 | DEFINE_MUTEX(fullstop_mutex); /* Protect fullstop transitions and spawning */ | 156 | /* |
| 157 | /* of kthreads. */ | 157 | * Protect fullstop transitions and spawning of kthreads. |
| 158 | */ | ||
| 159 | static DEFINE_MUTEX(fullstop_mutex); | ||
| 158 | 160 | ||
| 159 | /* | 161 | /* |
| 160 | * Detect and respond to a system shutdown. | 162 | * Detect and respond to a system shutdown. |
| @@ -303,6 +305,10 @@ static void rcu_read_delay(struct rcu_random_state *rrsp) | |||
| 303 | mdelay(longdelay_ms); | 305 | mdelay(longdelay_ms); |
| 304 | if (!(rcu_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) | 306 | if (!(rcu_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) |
| 305 | udelay(shortdelay_us); | 307 | udelay(shortdelay_us); |
| 308 | #ifdef CONFIG_PREEMPT | ||
| 309 | if (!preempt_count() && !(rcu_random(rrsp) % (nrealreaders * 20000))) | ||
| 310 | preempt_schedule(); /* No QS if preempt_disable() in effect */ | ||
| 311 | #endif | ||
| 306 | } | 312 | } |
| 307 | 313 | ||
| 308 | static void rcu_torture_read_unlock(int idx) __releases(RCU) | 314 | static void rcu_torture_read_unlock(int idx) __releases(RCU) |
| @@ -536,6 +542,8 @@ static void srcu_read_delay(struct rcu_random_state *rrsp) | |||
| 536 | delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick); | 542 | delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay * uspertick); |
| 537 | if (!delay) | 543 | if (!delay) |
| 538 | schedule_timeout_interruptible(longdelay); | 544 | schedule_timeout_interruptible(longdelay); |
| 545 | else | ||
| 546 | rcu_read_delay(rrsp); | ||
| 539 | } | 547 | } |
| 540 | 548 | ||
| 541 | static void srcu_torture_read_unlock(int idx) __releases(&srcu_ctl) | 549 | static void srcu_torture_read_unlock(int idx) __releases(&srcu_ctl) |
| @@ -731,7 +739,8 @@ rcu_torture_writer(void *arg) | |||
| 731 | continue; | 739 | continue; |
| 732 | rp->rtort_pipe_count = 0; | 740 | rp->rtort_pipe_count = 0; |
| 733 | udelay(rcu_random(&rand) & 0x3ff); | 741 | udelay(rcu_random(&rand) & 0x3ff); |
| 734 | old_rp = rcu_torture_current; | 742 | old_rp = rcu_dereference_check(rcu_torture_current, |
| 743 | current == writer_task); | ||
| 735 | rp->rtort_mbtest = 1; | 744 | rp->rtort_mbtest = 1; |
| 736 | rcu_assign_pointer(rcu_torture_current, rp); | 745 | rcu_assign_pointer(rcu_torture_current, rp); |
| 737 | smp_wmb(); /* Mods to old_rp must follow rcu_assign_pointer() */ | 746 | smp_wmb(); /* Mods to old_rp must follow rcu_assign_pointer() */ |
