diff options
Diffstat (limited to 'kernel/rcutorture.c')
| -rw-r--r-- | kernel/rcutorture.c | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index 697c0a0229d4..a621a67ef4e3 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c | |||
| @@ -327,6 +327,11 @@ rcu_torture_cb(struct rcu_head *p) | |||
| 327 | cur_ops->deferred_free(rp); | 327 | cur_ops->deferred_free(rp); |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | static int rcu_no_completed(void) | ||
| 331 | { | ||
| 332 | return 0; | ||
| 333 | } | ||
| 334 | |||
| 330 | static void rcu_torture_deferred_free(struct rcu_torture *p) | 335 | static void rcu_torture_deferred_free(struct rcu_torture *p) |
| 331 | { | 336 | { |
| 332 | call_rcu(&p->rtort_rcu, rcu_torture_cb); | 337 | call_rcu(&p->rtort_rcu, rcu_torture_cb); |
| @@ -388,6 +393,21 @@ static struct rcu_torture_ops rcu_sync_ops = { | |||
| 388 | .name = "rcu_sync" | 393 | .name = "rcu_sync" |
| 389 | }; | 394 | }; |
| 390 | 395 | ||
| 396 | static struct rcu_torture_ops rcu_expedited_ops = { | ||
| 397 | .init = rcu_sync_torture_init, | ||
| 398 | .cleanup = NULL, | ||
| 399 | .readlock = rcu_torture_read_lock, | ||
| 400 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | ||
| 401 | .readunlock = rcu_torture_read_unlock, | ||
| 402 | .completed = rcu_no_completed, | ||
| 403 | .deferred_free = rcu_sync_torture_deferred_free, | ||
| 404 | .sync = synchronize_rcu_expedited, | ||
| 405 | .cb_barrier = NULL, | ||
| 406 | .stats = NULL, | ||
| 407 | .irq_capable = 1, | ||
| 408 | .name = "rcu_expedited" | ||
| 409 | }; | ||
| 410 | |||
| 391 | /* | 411 | /* |
| 392 | * Definitions for rcu_bh torture testing. | 412 | * Definitions for rcu_bh torture testing. |
| 393 | */ | 413 | */ |
| @@ -547,6 +567,25 @@ static struct rcu_torture_ops srcu_ops = { | |||
| 547 | .name = "srcu" | 567 | .name = "srcu" |
| 548 | }; | 568 | }; |
| 549 | 569 | ||
| 570 | static void srcu_torture_synchronize_expedited(void) | ||
| 571 | { | ||
| 572 | synchronize_srcu_expedited(&srcu_ctl); | ||
| 573 | } | ||
| 574 | |||
| 575 | static struct rcu_torture_ops srcu_expedited_ops = { | ||
| 576 | .init = srcu_torture_init, | ||
| 577 | .cleanup = srcu_torture_cleanup, | ||
| 578 | .readlock = srcu_torture_read_lock, | ||
| 579 | .read_delay = srcu_read_delay, | ||
| 580 | .readunlock = srcu_torture_read_unlock, | ||
| 581 | .completed = srcu_torture_completed, | ||
| 582 | .deferred_free = rcu_sync_torture_deferred_free, | ||
| 583 | .sync = srcu_torture_synchronize_expedited, | ||
| 584 | .cb_barrier = NULL, | ||
| 585 | .stats = srcu_torture_stats, | ||
| 586 | .name = "srcu_expedited" | ||
| 587 | }; | ||
| 588 | |||
| 550 | /* | 589 | /* |
| 551 | * Definitions for sched torture testing. | 590 | * Definitions for sched torture testing. |
| 552 | */ | 591 | */ |
| @@ -562,11 +601,6 @@ static void sched_torture_read_unlock(int idx) | |||
| 562 | preempt_enable(); | 601 | preempt_enable(); |
| 563 | } | 602 | } |
| 564 | 603 | ||
| 565 | static int sched_torture_completed(void) | ||
| 566 | { | ||
| 567 | return 0; | ||
| 568 | } | ||
| 569 | |||
| 570 | static void rcu_sched_torture_deferred_free(struct rcu_torture *p) | 604 | static void rcu_sched_torture_deferred_free(struct rcu_torture *p) |
| 571 | { | 605 | { |
| 572 | call_rcu_sched(&p->rtort_rcu, rcu_torture_cb); | 606 | call_rcu_sched(&p->rtort_rcu, rcu_torture_cb); |
| @@ -583,7 +617,7 @@ static struct rcu_torture_ops sched_ops = { | |||
| 583 | .readlock = sched_torture_read_lock, | 617 | .readlock = sched_torture_read_lock, |
| 584 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 618 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ |
| 585 | .readunlock = sched_torture_read_unlock, | 619 | .readunlock = sched_torture_read_unlock, |
| 586 | .completed = sched_torture_completed, | 620 | .completed = rcu_no_completed, |
| 587 | .deferred_free = rcu_sched_torture_deferred_free, | 621 | .deferred_free = rcu_sched_torture_deferred_free, |
| 588 | .sync = sched_torture_synchronize, | 622 | .sync = sched_torture_synchronize, |
| 589 | .cb_barrier = rcu_barrier_sched, | 623 | .cb_barrier = rcu_barrier_sched, |
| @@ -592,13 +626,13 @@ static struct rcu_torture_ops sched_ops = { | |||
| 592 | .name = "sched" | 626 | .name = "sched" |
| 593 | }; | 627 | }; |
| 594 | 628 | ||
| 595 | static struct rcu_torture_ops sched_ops_sync = { | 629 | static struct rcu_torture_ops sched_sync_ops = { |
| 596 | .init = rcu_sync_torture_init, | 630 | .init = rcu_sync_torture_init, |
| 597 | .cleanup = NULL, | 631 | .cleanup = NULL, |
| 598 | .readlock = sched_torture_read_lock, | 632 | .readlock = sched_torture_read_lock, |
| 599 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 633 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ |
| 600 | .readunlock = sched_torture_read_unlock, | 634 | .readunlock = sched_torture_read_unlock, |
| 601 | .completed = sched_torture_completed, | 635 | .completed = rcu_no_completed, |
| 602 | .deferred_free = rcu_sync_torture_deferred_free, | 636 | .deferred_free = rcu_sync_torture_deferred_free, |
| 603 | .sync = sched_torture_synchronize, | 637 | .sync = sched_torture_synchronize, |
| 604 | .cb_barrier = NULL, | 638 | .cb_barrier = NULL, |
| @@ -612,7 +646,7 @@ static struct rcu_torture_ops sched_expedited_ops = { | |||
| 612 | .readlock = sched_torture_read_lock, | 646 | .readlock = sched_torture_read_lock, |
| 613 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 647 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ |
| 614 | .readunlock = sched_torture_read_unlock, | 648 | .readunlock = sched_torture_read_unlock, |
| 615 | .completed = sched_torture_completed, | 649 | .completed = rcu_no_completed, |
| 616 | .deferred_free = rcu_sync_torture_deferred_free, | 650 | .deferred_free = rcu_sync_torture_deferred_free, |
| 617 | .sync = synchronize_sched_expedited, | 651 | .sync = synchronize_sched_expedited, |
| 618 | .cb_barrier = NULL, | 652 | .cb_barrier = NULL, |
| @@ -1097,9 +1131,10 @@ rcu_torture_init(void) | |||
| 1097 | int cpu; | 1131 | int cpu; |
| 1098 | int firsterr = 0; | 1132 | int firsterr = 0; |
| 1099 | static struct rcu_torture_ops *torture_ops[] = | 1133 | static struct rcu_torture_ops *torture_ops[] = |
| 1100 | { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops, | 1134 | { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops, |
| 1101 | &sched_expedited_ops, | 1135 | &rcu_bh_ops, &rcu_bh_sync_ops, |
| 1102 | &srcu_ops, &sched_ops, &sched_ops_sync, }; | 1136 | &srcu_ops, &srcu_expedited_ops, |
| 1137 | &sched_ops, &sched_sync_ops, &sched_expedited_ops, }; | ||
| 1103 | 1138 | ||
| 1104 | mutex_lock(&fullstop_mutex); | 1139 | mutex_lock(&fullstop_mutex); |
| 1105 | 1140 | ||
| @@ -1110,8 +1145,12 @@ rcu_torture_init(void) | |||
| 1110 | break; | 1145 | break; |
| 1111 | } | 1146 | } |
| 1112 | if (i == ARRAY_SIZE(torture_ops)) { | 1147 | if (i == ARRAY_SIZE(torture_ops)) { |
| 1113 | printk(KERN_ALERT "rcutorture: invalid torture type: \"%s\"\n", | 1148 | printk(KERN_ALERT "rcu-torture: invalid torture type: \"%s\"\n", |
| 1114 | torture_type); | 1149 | torture_type); |
| 1150 | printk(KERN_ALERT "rcu-torture types:"); | ||
| 1151 | for (i = 0; i < ARRAY_SIZE(torture_ops); i++) | ||
| 1152 | printk(KERN_ALERT " %s", torture_ops[i]->name); | ||
| 1153 | printk(KERN_ALERT "\n"); | ||
| 1115 | mutex_unlock(&fullstop_mutex); | 1154 | mutex_unlock(&fullstop_mutex); |
| 1116 | return -EINVAL; | 1155 | return -EINVAL; |
| 1117 | } | 1156 | } |
