aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutorture.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcutorture.c')
-rw-r--r--kernel/rcutorture.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index eb6719c50b4e..88c28d476550 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -80,6 +80,7 @@ struct rcu_torture {
80 struct rcu_head rtort_rcu; 80 struct rcu_head rtort_rcu;
81 int rtort_pipe_count; 81 int rtort_pipe_count;
82 struct list_head rtort_free; 82 struct list_head rtort_free;
83 int rtort_mbtest;
83}; 84};
84 85
85static int fullstop = 0; /* stop generating callbacks at test end. */ 86static int fullstop = 0; /* stop generating callbacks at test end. */
@@ -96,6 +97,8 @@ static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
96atomic_t n_rcu_torture_alloc; 97atomic_t n_rcu_torture_alloc;
97atomic_t n_rcu_torture_alloc_fail; 98atomic_t n_rcu_torture_alloc_fail;
98atomic_t n_rcu_torture_free; 99atomic_t n_rcu_torture_free;
100atomic_t n_rcu_torture_mberror;
101atomic_t n_rcu_torture_error;
99 102
100/* 103/*
101 * Allocate an element from the rcu_tortures pool. 104 * Allocate an element from the rcu_tortures pool.
@@ -145,9 +148,10 @@ rcu_torture_cb(struct rcu_head *p)
145 if (i > RCU_TORTURE_PIPE_LEN) 148 if (i > RCU_TORTURE_PIPE_LEN)
146 i = RCU_TORTURE_PIPE_LEN; 149 i = RCU_TORTURE_PIPE_LEN;
147 atomic_inc(&rcu_torture_wcount[i]); 150 atomic_inc(&rcu_torture_wcount[i]);
148 if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) 151 if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
152 rp->rtort_mbtest = 0;
149 rcu_torture_free(rp); 153 rcu_torture_free(rp);
150 else 154 } else
151 call_rcu(p, rcu_torture_cb); 155 call_rcu(p, rcu_torture_cb);
152} 156}
153 157
@@ -206,6 +210,7 @@ rcu_torture_writer(void *arg)
206 rp->rtort_pipe_count = 0; 210 rp->rtort_pipe_count = 0;
207 udelay(rcu_random(&rand) & 0x3ff); 211 udelay(rcu_random(&rand) & 0x3ff);
208 old_rp = rcu_torture_current; 212 old_rp = rcu_torture_current;
213 rp->rtort_mbtest = 1;
209 rcu_assign_pointer(rcu_torture_current, rp); 214 rcu_assign_pointer(rcu_torture_current, rp);
210 smp_wmb(); 215 smp_wmb();
211 if (old_rp != NULL) { 216 if (old_rp != NULL) {
@@ -252,6 +257,8 @@ rcu_torture_reader(void *arg)
252 schedule_timeout_interruptible(HZ); 257 schedule_timeout_interruptible(HZ);
253 continue; 258 continue;
254 } 259 }
260 if (p->rtort_mbtest == 0)
261 atomic_inc(&n_rcu_torture_mberror);
255 udelay(rcu_random(&rand) & 0x7f); 262 udelay(rcu_random(&rand) & 0x7f);
256 preempt_disable(); 263 preempt_disable();
257 pipe_count = p->rtort_pipe_count; 264 pipe_count = p->rtort_pipe_count;
@@ -300,16 +307,22 @@ rcu_torture_printk(char *page)
300 } 307 }
301 cnt += sprintf(&page[cnt], "rcutorture: "); 308 cnt += sprintf(&page[cnt], "rcutorture: ");
302 cnt += sprintf(&page[cnt], 309 cnt += sprintf(&page[cnt],
303 "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d", 310 "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d "
311 "rtmbe: %d",
304 rcu_torture_current, 312 rcu_torture_current,
305 rcu_torture_current_version, 313 rcu_torture_current_version,
306 list_empty(&rcu_torture_freelist), 314 list_empty(&rcu_torture_freelist),
307 atomic_read(&n_rcu_torture_alloc), 315 atomic_read(&n_rcu_torture_alloc),
308 atomic_read(&n_rcu_torture_alloc_fail), 316 atomic_read(&n_rcu_torture_alloc_fail),
309 atomic_read(&n_rcu_torture_free)); 317 atomic_read(&n_rcu_torture_free),
318 atomic_read(&n_rcu_torture_mberror));
319 if (atomic_read(&n_rcu_torture_mberror) != 0)
320 cnt += sprintf(&page[cnt], " !!!");
310 cnt += sprintf(&page[cnt], "\nrcutorture: "); 321 cnt += sprintf(&page[cnt], "\nrcutorture: ");
311 if (i > 1) 322 if (i > 1) {
312 cnt += sprintf(&page[cnt], "!!! "); 323 cnt += sprintf(&page[cnt], "!!! ");
324 atomic_inc(&n_rcu_torture_error);
325 }
313 cnt += sprintf(&page[cnt], "Reader Pipe: "); 326 cnt += sprintf(&page[cnt], "Reader Pipe: ");
314 for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) 327 for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
315 cnt += sprintf(&page[cnt], " %ld", pipesummary[i]); 328 cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
@@ -400,7 +413,9 @@ rcu_torture_cleanup(void)
400 for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++) 413 for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
401 synchronize_rcu(); 414 synchronize_rcu();
402 rcu_torture_stats_print(); /* -After- the stats thread is stopped! */ 415 rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
403 PRINTK_STRING("--- End of test"); 416 printk(KERN_ALERT TORTURE_FLAG
417 "--- End of test: %s\n",
418 atomic_read(&n_rcu_torture_error) == 0 ? "SUCCESS" : "FAILURE");
404} 419}
405 420
406static int 421static int
@@ -425,6 +440,7 @@ rcu_torture_init(void)
425 440
426 INIT_LIST_HEAD(&rcu_torture_freelist); 441 INIT_LIST_HEAD(&rcu_torture_freelist);
427 for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) { 442 for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
443 rcu_tortures[i].rtort_mbtest = 0;
428 list_add_tail(&rcu_tortures[i].rtort_free, 444 list_add_tail(&rcu_tortures[i].rtort_free,
429 &rcu_torture_freelist); 445 &rcu_torture_freelist);
430 } 446 }
@@ -436,6 +452,8 @@ rcu_torture_init(void)
436 atomic_set(&n_rcu_torture_alloc, 0); 452 atomic_set(&n_rcu_torture_alloc, 0);
437 atomic_set(&n_rcu_torture_alloc_fail, 0); 453 atomic_set(&n_rcu_torture_alloc_fail, 0);
438 atomic_set(&n_rcu_torture_free, 0); 454 atomic_set(&n_rcu_torture_free, 0);
455 atomic_set(&n_rcu_torture_mberror, 0);
456 atomic_set(&n_rcu_torture_error, 0);
439 for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) 457 for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
440 atomic_set(&rcu_torture_wcount[i], 0); 458 atomic_set(&rcu_torture_wcount[i], 0);
441 for_each_cpu(cpu) { 459 for_each_cpu(cpu) {