diff options
author | Paul E. McKenney <paulmck@us.ibm.com> | 2005-11-18 04:10:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-18 10:49:45 -0500 |
commit | 996417d2c4eb583e94553e4ede58974e0da1c38e (patch) | |
tree | 61a1c6dfa7e4d65ce1424f2225c1f46b15f16bb1 /kernel/rcutorture.c | |
parent | 2463ade2cb78224302998ee3c7dc7d53da88d258 (diff) |
[PATCH] add success/failure indication to RCU torture test
One issue with the RCU torture test is that the current error flagging can
be lost in dmesg. This patch adds a "SUCCESS"/"FAILURE" string to the line
that flags the end of the test, where it can easily be seen with "dmesg |
tail" at the end of the test. Also adds tests of architecture-specific
memory barriers -- or, more likely, of the RCU torture test itself.
Cc: <vatsa@in.ibm.com>
Signed-off-by: "Paul E. McKenney" <paulmck@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/rcutorture.c')
-rw-r--r-- | kernel/rcutorture.c | 30 |
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 | ||
85 | static int fullstop = 0; /* stop generating callbacks at test end. */ | 86 | static int fullstop = 0; /* stop generating callbacks at test end. */ |
@@ -96,6 +97,8 @@ static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1]; | |||
96 | atomic_t n_rcu_torture_alloc; | 97 | atomic_t n_rcu_torture_alloc; |
97 | atomic_t n_rcu_torture_alloc_fail; | 98 | atomic_t n_rcu_torture_alloc_fail; |
98 | atomic_t n_rcu_torture_free; | 99 | atomic_t n_rcu_torture_free; |
100 | atomic_t n_rcu_torture_mberror; | ||
101 | atomic_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 | ||
406 | static int | 421 | static 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) { |