rcutorture.c (6c7ed42c81a2d9a7e0646240599552040375fa02) | rcutorture.c (ca1d51ed9809a99d71c23a343b3acd3fd4ad8cbe) |
---|---|
1/* 2 * Read-Copy Update module-based torture test facility 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 227 unchanged lines hidden (view full) --- 236 237/* 238 * Operations vector for selecting different types of tests. 239 */ 240 241struct rcu_torture_ops { 242 int ttype; 243 void (*init)(void); | 1/* 2 * Read-Copy Update module-based torture test facility 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 227 unchanged lines hidden (view full) --- 236 237/* 238 * Operations vector for selecting different types of tests. 239 */ 240 241struct rcu_torture_ops { 242 int ttype; 243 void (*init)(void); |
244 void (*cleanup)(void); |
|
244 int (*readlock)(void); 245 void (*read_delay)(struct torture_random_state *rrsp); 246 void (*readunlock)(int idx); 247 unsigned long (*started)(void); 248 unsigned long (*completed)(void); 249 void (*deferred_free)(struct rcu_torture *p); 250 void (*sync)(void); 251 void (*exp_sync)(void); --- 220 unchanged lines hidden (view full) --- 472 .name = "rcu_busted" 473}; 474 475/* 476 * Definitions for srcu torture testing. 477 */ 478 479DEFINE_STATIC_SRCU(srcu_ctl); | 245 int (*readlock)(void); 246 void (*read_delay)(struct torture_random_state *rrsp); 247 void (*readunlock)(int idx); 248 unsigned long (*started)(void); 249 unsigned long (*completed)(void); 250 void (*deferred_free)(struct rcu_torture *p); 251 void (*sync)(void); 252 void (*exp_sync)(void); --- 220 unchanged lines hidden (view full) --- 473 .name = "rcu_busted" 474}; 475 476/* 477 * Definitions for srcu torture testing. 478 */ 479 480DEFINE_STATIC_SRCU(srcu_ctl); |
481static struct srcu_struct srcu_ctld; 482static struct srcu_struct *srcu_ctlp = &srcu_ctl; |
|
480 | 483 |
481static int srcu_torture_read_lock(void) __acquires(&srcu_ctl) | 484static int srcu_torture_read_lock(void) __acquires(srcu_ctlp) |
482{ | 485{ |
483 return srcu_read_lock(&srcu_ctl); | 486 return srcu_read_lock(srcu_ctlp); |
484} 485 486static void srcu_read_delay(struct torture_random_state *rrsp) 487{ 488 long delay; 489 const long uspertick = 1000000 / HZ; 490 const long longdelay = 10; 491 492 /* We want there to be long-running readers, but not all the time. */ 493 494 delay = torture_random(rrsp) % 495 (nrealreaders * 2 * longdelay * uspertick); 496 if (!delay) 497 schedule_timeout_interruptible(longdelay); 498 else 499 rcu_read_delay(rrsp); 500} 501 | 487} 488 489static void srcu_read_delay(struct torture_random_state *rrsp) 490{ 491 long delay; 492 const long uspertick = 1000000 / HZ; 493 const long longdelay = 10; 494 495 /* We want there to be long-running readers, but not all the time. */ 496 497 delay = torture_random(rrsp) % 498 (nrealreaders * 2 * longdelay * uspertick); 499 if (!delay) 500 schedule_timeout_interruptible(longdelay); 501 else 502 rcu_read_delay(rrsp); 503} 504 |
502static void srcu_torture_read_unlock(int idx) __releases(&srcu_ctl) | 505static void srcu_torture_read_unlock(int idx) __releases(srcu_ctlp) |
503{ | 506{ |
504 srcu_read_unlock(&srcu_ctl, idx); | 507 srcu_read_unlock(srcu_ctlp, idx); |
505} 506 507static unsigned long srcu_torture_completed(void) 508{ | 508} 509 510static unsigned long srcu_torture_completed(void) 511{ |
509 return srcu_batches_completed(&srcu_ctl); | 512 return srcu_batches_completed(srcu_ctlp); |
510} 511 512static void srcu_torture_deferred_free(struct rcu_torture *rp) 513{ | 513} 514 515static void srcu_torture_deferred_free(struct rcu_torture *rp) 516{ |
514 call_srcu(&srcu_ctl, &rp->rtort_rcu, rcu_torture_cb); | 517 call_srcu(srcu_ctlp, &rp->rtort_rcu, rcu_torture_cb); |
515} 516 517static void srcu_torture_synchronize(void) 518{ | 518} 519 520static void srcu_torture_synchronize(void) 521{ |
519 synchronize_srcu(&srcu_ctl); | 522 synchronize_srcu(srcu_ctlp); |
520} 521 522static void srcu_torture_call(struct rcu_head *head, 523 void (*func)(struct rcu_head *head)) 524{ | 523} 524 525static void srcu_torture_call(struct rcu_head *head, 526 void (*func)(struct rcu_head *head)) 527{ |
525 call_srcu(&srcu_ctl, head, func); | 528 call_srcu(srcu_ctlp, head, func); |
526} 527 528static void srcu_torture_barrier(void) 529{ | 529} 530 531static void srcu_torture_barrier(void) 532{ |
530 srcu_barrier(&srcu_ctl); | 533 srcu_barrier(srcu_ctlp); |
531} 532 533static void srcu_torture_stats(void) 534{ 535 int cpu; | 534} 535 536static void srcu_torture_stats(void) 537{ 538 int cpu; |
536 int idx = srcu_ctl.completed & 0x1; | 539 int idx = srcu_ctlp->completed & 0x1; |
537 538 pr_alert("%s%s per-CPU(idx=%d):", 539 torture_type, TORTURE_FLAG, idx); 540 for_each_possible_cpu(cpu) { 541 long c0, c1; 542 | 540 541 pr_alert("%s%s per-CPU(idx=%d):", 542 torture_type, TORTURE_FLAG, idx); 543 for_each_possible_cpu(cpu) { 544 long c0, c1; 545 |
543 c0 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[!idx]; 544 c1 = (long)per_cpu_ptr(srcu_ctl.per_cpu_ref, cpu)->c[idx]; | 546 c0 = (long)per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu)->c[!idx]; 547 c1 = (long)per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu)->c[idx]; |
545 pr_cont(" %d(%ld,%ld)", cpu, c0, c1); 546 } 547 pr_cont("\n"); 548} 549 550static void srcu_torture_synchronize_expedited(void) 551{ | 548 pr_cont(" %d(%ld,%ld)", cpu, c0, c1); 549 } 550 pr_cont("\n"); 551} 552 553static void srcu_torture_synchronize_expedited(void) 554{ |
552 synchronize_srcu_expedited(&srcu_ctl); | 555 synchronize_srcu_expedited(srcu_ctlp); |
553} 554 555static struct rcu_torture_ops srcu_ops = { 556 .ttype = SRCU_FLAVOR, 557 .init = rcu_sync_torture_init, 558 .readlock = srcu_torture_read_lock, 559 .read_delay = srcu_read_delay, 560 .readunlock = srcu_torture_read_unlock, 561 .started = NULL, 562 .completed = srcu_torture_completed, 563 .deferred_free = srcu_torture_deferred_free, 564 .sync = srcu_torture_synchronize, 565 .exp_sync = srcu_torture_synchronize_expedited, 566 .call = srcu_torture_call, 567 .cb_barrier = srcu_torture_barrier, 568 .stats = srcu_torture_stats, 569 .name = "srcu" 570}; 571 | 556} 557 558static struct rcu_torture_ops srcu_ops = { 559 .ttype = SRCU_FLAVOR, 560 .init = rcu_sync_torture_init, 561 .readlock = srcu_torture_read_lock, 562 .read_delay = srcu_read_delay, 563 .readunlock = srcu_torture_read_unlock, 564 .started = NULL, 565 .completed = srcu_torture_completed, 566 .deferred_free = srcu_torture_deferred_free, 567 .sync = srcu_torture_synchronize, 568 .exp_sync = srcu_torture_synchronize_expedited, 569 .call = srcu_torture_call, 570 .cb_barrier = srcu_torture_barrier, 571 .stats = srcu_torture_stats, 572 .name = "srcu" 573}; 574 |
575static void srcu_torture_init(void) 576{ 577 rcu_sync_torture_init(); 578 WARN_ON(init_srcu_struct(&srcu_ctld)); 579 srcu_ctlp = &srcu_ctld; 580} 581 582static void srcu_torture_cleanup(void) 583{ 584 cleanup_srcu_struct(&srcu_ctld); 585 srcu_ctlp = &srcu_ctl; /* In case of a later rcutorture run. */ 586} 587 588/* As above, but dynamically allocated. */ 589static struct rcu_torture_ops srcud_ops = { 590 .ttype = SRCU_FLAVOR, 591 .init = srcu_torture_init, 592 .cleanup = srcu_torture_cleanup, 593 .readlock = srcu_torture_read_lock, 594 .read_delay = srcu_read_delay, 595 .readunlock = srcu_torture_read_unlock, 596 .started = NULL, 597 .completed = srcu_torture_completed, 598 .deferred_free = srcu_torture_deferred_free, 599 .sync = srcu_torture_synchronize, 600 .exp_sync = srcu_torture_synchronize_expedited, 601 .call = srcu_torture_call, 602 .cb_barrier = srcu_torture_barrier, 603 .stats = srcu_torture_stats, 604 .name = "srcud" 605}; 606 |
|
572/* 573 * Definitions for sched torture testing. 574 */ 575 576static int sched_torture_read_lock(void) 577{ 578 preempt_disable(); 579 return 0; --- 468 unchanged lines hidden (view full) --- 1048 if (cur_ops->started) 1049 started = cur_ops->started(); 1050 else 1051 started = cur_ops->completed(); 1052 ts = rcu_trace_clock_local(); 1053 p = rcu_dereference_check(rcu_torture_current, 1054 rcu_read_lock_bh_held() || 1055 rcu_read_lock_sched_held() || | 607/* 608 * Definitions for sched torture testing. 609 */ 610 611static int sched_torture_read_lock(void) 612{ 613 preempt_disable(); 614 return 0; --- 468 unchanged lines hidden (view full) --- 1083 if (cur_ops->started) 1084 started = cur_ops->started(); 1085 else 1086 started = cur_ops->completed(); 1087 ts = rcu_trace_clock_local(); 1088 p = rcu_dereference_check(rcu_torture_current, 1089 rcu_read_lock_bh_held() || 1090 rcu_read_lock_sched_held() || |
1056 srcu_read_lock_held(&srcu_ctl)); | 1091 srcu_read_lock_held(srcu_ctlp)); |
1057 if (p == NULL) { 1058 /* Leave because rcu_torture_writer is not yet underway */ 1059 cur_ops->readunlock(idx); 1060 return; 1061 } 1062 if (p->rtort_mbtest == 0) 1063 atomic_inc(&n_rcu_torture_mberror); 1064 spin_lock(&rand_lock); --- 57 unchanged lines hidden (view full) --- 1122 if (cur_ops->started) 1123 started = cur_ops->started(); 1124 else 1125 started = cur_ops->completed(); 1126 ts = rcu_trace_clock_local(); 1127 p = rcu_dereference_check(rcu_torture_current, 1128 rcu_read_lock_bh_held() || 1129 rcu_read_lock_sched_held() || | 1092 if (p == NULL) { 1093 /* Leave because rcu_torture_writer is not yet underway */ 1094 cur_ops->readunlock(idx); 1095 return; 1096 } 1097 if (p->rtort_mbtest == 0) 1098 atomic_inc(&n_rcu_torture_mberror); 1099 spin_lock(&rand_lock); --- 57 unchanged lines hidden (view full) --- 1157 if (cur_ops->started) 1158 started = cur_ops->started(); 1159 else 1160 started = cur_ops->completed(); 1161 ts = rcu_trace_clock_local(); 1162 p = rcu_dereference_check(rcu_torture_current, 1163 rcu_read_lock_bh_held() || 1164 rcu_read_lock_sched_held() || |
1130 srcu_read_lock_held(&srcu_ctl)); | 1165 srcu_read_lock_held(srcu_ctlp)); |
1131 if (p == NULL) { 1132 /* Wait for rcu_torture_writer to get underway */ 1133 cur_ops->readunlock(idx); 1134 schedule_timeout_interruptible(HZ); 1135 continue; 1136 } 1137 if (p->rtort_mbtest == 0) 1138 atomic_inc(&n_rcu_torture_mberror); --- 446 unchanged lines hidden (view full) --- 1585 torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]); 1586 if ((test_boost == 1 && cur_ops->can_boost) || 1587 test_boost == 2) { 1588 unregister_cpu_notifier(&rcutorture_cpu_nb); 1589 for_each_possible_cpu(i) 1590 rcutorture_booster_cleanup(i); 1591 } 1592 | 1166 if (p == NULL) { 1167 /* Wait for rcu_torture_writer to get underway */ 1168 cur_ops->readunlock(idx); 1169 schedule_timeout_interruptible(HZ); 1170 continue; 1171 } 1172 if (p->rtort_mbtest == 0) 1173 atomic_inc(&n_rcu_torture_mberror); --- 446 unchanged lines hidden (view full) --- 1620 torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]); 1621 if ((test_boost == 1 && cur_ops->can_boost) || 1622 test_boost == 2) { 1623 unregister_cpu_notifier(&rcutorture_cpu_nb); 1624 for_each_possible_cpu(i) 1625 rcutorture_booster_cleanup(i); 1626 } 1627 |
1593 /* Wait for all RCU callbacks to fire. */ 1594 | 1628 /* 1629 * Wait for all RCU callbacks to fire, then do flavor-specific 1630 * cleanup operations. 1631 */ |
1595 if (cur_ops->cb_barrier != NULL) 1596 cur_ops->cb_barrier(); | 1632 if (cur_ops->cb_barrier != NULL) 1633 cur_ops->cb_barrier(); |
1634 if (cur_ops->cleanup != NULL) 1635 cur_ops->cleanup(); |
|
1597 1598 rcu_torture_stats_print(); /* -After- the stats thread is stopped! */ 1599 1600 if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error) 1601 rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE"); 1602 else if (torture_onoff_failures()) 1603 rcu_torture_print_module_parms(cur_ops, 1604 "End of test: RCU_HOTPLUG"); --- 60 unchanged lines hidden (view full) --- 1665 1666static int __init 1667rcu_torture_init(void) 1668{ 1669 int i; 1670 int cpu; 1671 int firsterr = 0; 1672 static struct rcu_torture_ops *torture_ops[] = { | 1636 1637 rcu_torture_stats_print(); /* -After- the stats thread is stopped! */ 1638 1639 if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error) 1640 rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE"); 1641 else if (torture_onoff_failures()) 1642 rcu_torture_print_module_parms(cur_ops, 1643 "End of test: RCU_HOTPLUG"); --- 60 unchanged lines hidden (view full) --- 1704 1705static int __init 1706rcu_torture_init(void) 1707{ 1708 int i; 1709 int cpu; 1710 int firsterr = 0; 1711 static struct rcu_torture_ops *torture_ops[] = { |
1673 &rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &sched_ops, 1674 RCUTORTURE_TASKS_OPS | 1712 &rcu_ops, &rcu_bh_ops, &rcu_busted_ops, &srcu_ops, &srcud_ops, 1713 &sched_ops, RCUTORTURE_TASKS_OPS |
1675 }; 1676 1677 if (!torture_init_begin(torture_type, verbose, &torture_runnable)) 1678 return -EBUSY; 1679 1680 /* Process args and tell the world that the torturer is on the job. */ 1681 for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { 1682 cur_ops = torture_ops[i]; --- 181 unchanged lines hidden --- | 1714 }; 1715 1716 if (!torture_init_begin(torture_type, verbose, &torture_runnable)) 1717 return -EBUSY; 1718 1719 /* Process args and tell the world that the torturer is on the job. */ 1720 for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { 1721 cur_ops = torture_ops[i]; --- 181 unchanged lines hidden --- |