diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-02-06 11:45:56 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-02-23 12:04:30 -0500 |
commit | ff20e251c409da81f2b850c81964908fb4c6fe66 (patch) | |
tree | d19bd865cb6f1e9038630b35ffff4b99662cb68b /kernel/rcu/rcutorture.c | |
parent | 0af3fe1efa534a43385fe2694c42ffec7a310e46 (diff) |
rcutorture: Add an rcu_busted to test the test
This commit adds a deliberately buggy RCU implementation into rcutorture
to allow easy checking that rcutorture correctly flags buggy RCU
implementations.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcu/rcutorture.c')
-rw-r--r-- | kernel/rcu/rcutorture.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 40792e76a116..da6c38d909f1 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c | |||
@@ -372,6 +372,48 @@ static struct rcu_torture_ops rcu_bh_ops = { | |||
372 | }; | 372 | }; |
373 | 373 | ||
374 | /* | 374 | /* |
375 | * Don't even think about trying any of these in real life!!! | ||
376 | * The names includes "busted", and they really means it! | ||
377 | * The only purpose of these functions is to provide a buggy RCU | ||
378 | * implementation to make sure that rcutorture correctly emits | ||
379 | * buggy-RCU error messages. | ||
380 | */ | ||
381 | static void rcu_busted_torture_deferred_free(struct rcu_torture *p) | ||
382 | { | ||
383 | /* This is a deliberate bug for testing purposes only! */ | ||
384 | rcu_torture_cb(&p->rtort_rcu); | ||
385 | } | ||
386 | |||
387 | static void synchronize_rcu_busted(void) | ||
388 | { | ||
389 | /* This is a deliberate bug for testing purposes only! */ | ||
390 | } | ||
391 | |||
392 | static void | ||
393 | call_rcu_busted(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) | ||
394 | { | ||
395 | /* This is a deliberate bug for testing purposes only! */ | ||
396 | func(head); | ||
397 | } | ||
398 | |||
399 | static struct rcu_torture_ops rcu_busted_ops = { | ||
400 | .init = rcu_sync_torture_init, | ||
401 | .readlock = rcu_torture_read_lock, | ||
402 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | ||
403 | .readunlock = rcu_torture_read_unlock, | ||
404 | .completed = rcu_no_completed, | ||
405 | .deferred_free = rcu_busted_torture_deferred_free, | ||
406 | .sync = synchronize_rcu_busted, | ||
407 | .exp_sync = synchronize_rcu_busted, | ||
408 | .call = call_rcu_busted, | ||
409 | .cb_barrier = NULL, | ||
410 | .fqs = NULL, | ||
411 | .stats = NULL, | ||
412 | .irq_capable = 1, | ||
413 | .name = "rcu_busted" | ||
414 | }; | ||
415 | |||
416 | /* | ||
375 | * Definitions for srcu torture testing. | 417 | * Definitions for srcu torture testing. |
376 | */ | 418 | */ |
377 | 419 | ||
@@ -1371,7 +1413,7 @@ rcu_torture_init(void) | |||
1371 | int cpu; | 1413 | int cpu; |
1372 | int firsterr = 0; | 1414 | int firsterr = 0; |
1373 | static struct rcu_torture_ops *torture_ops[] = { | 1415 | static struct rcu_torture_ops *torture_ops[] = { |
1374 | &rcu_ops, &rcu_bh_ops, &srcu_ops, &sched_ops, | 1416 | &rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &sched_ops, |
1375 | }; | 1417 | }; |
1376 | 1418 | ||
1377 | torture_init_begin(torture_type, verbose, &rcutorture_runnable); | 1419 | torture_init_begin(torture_type, verbose, &rcutorture_runnable); |