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 ---