diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2018-04-27 14:39:34 -0400 | 
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2018-07-12 17:27:47 -0400 | 
| commit | 17ef2fe97c8c8e754e4a702c42f8e5b0ffadf4dd (patch) | |
| tree | 57f08e5a676a2432fea98077ea5ff02626761e79 | |
| parent | dee4f42298bba030e84035aca5c114f9fee8fa6a (diff) | |
rcu: Make rcutorture's batches-completed API use ->gp_seq
The rcutorture test invokes rcu_batches_started(),
rcu_batches_completed(), rcu_batches_started_bh(),
rcu_batches_completed_bh(), rcu_batches_started_sched(), and
rcu_batches_completed_sched() to do grace-period consistency checks,
and rcuperf uses the _completed variants for statistics.
These functions use ->gpnum and ->completed.  This commit therefore
replaces them with rcu_get_gp_seq(), rcu_bh_get_gp_seq(), and
rcu_sched_get_gp_seq(), adjusting rcutorture and rcuperf to make
use of them.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
| -rw-r--r-- | kernel/rcu/rcu.h | 18 | ||||
| -rw-r--r-- | kernel/rcu/rcuperf.c | 26 | ||||
| -rw-r--r-- | kernel/rcu/rcutorture.c | 50 | ||||
| -rw-r--r-- | kernel/rcu/tree.c | 51 | 
4 files changed, 45 insertions, 100 deletions
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index db0870acfdff..f0907f9f6cd0 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h  | |||
| @@ -463,12 +463,9 @@ void srcutorture_get_gp_data(enum rcutorture_type test_type, | |||
| 463 | #endif | 463 | #endif | 
| 464 | 464 | ||
| 465 | #ifdef CONFIG_TINY_RCU | 465 | #ifdef CONFIG_TINY_RCU | 
| 466 | static inline unsigned long rcu_batches_started(void) { return 0; } | 466 | static inline unsigned long rcu_get_gp_seq(void) { return 0; } | 
| 467 | static inline unsigned long rcu_batches_started_bh(void) { return 0; } | 467 | static inline unsigned long rcu_bh_get_gp_seq(void) { return 0; } | 
| 468 | static inline unsigned long rcu_batches_started_sched(void) { return 0; } | 468 | static inline unsigned long rcu_sched_get_gp_seq(void) { return 0; } | 
| 469 | static inline unsigned long rcu_batches_completed(void) { return 0; } | ||
| 470 | static inline unsigned long rcu_batches_completed_bh(void) { return 0; } | ||
| 471 | static inline unsigned long rcu_batches_completed_sched(void) { return 0; } | ||
| 472 | static inline unsigned long rcu_exp_batches_completed(void) { return 0; } | 469 | static inline unsigned long rcu_exp_batches_completed(void) { return 0; } | 
| 473 | static inline unsigned long rcu_exp_batches_completed_sched(void) { return 0; } | 470 | static inline unsigned long rcu_exp_batches_completed_sched(void) { return 0; } | 
| 474 | static inline unsigned long | 471 | static inline unsigned long | 
| @@ -480,12 +477,9 @@ static inline void show_rcu_gp_kthreads(void) { } | |||
| 480 | #else /* #ifdef CONFIG_TINY_RCU */ | 477 | #else /* #ifdef CONFIG_TINY_RCU */ | 
| 481 | extern unsigned long rcutorture_testseq; | 478 | extern unsigned long rcutorture_testseq; | 
| 482 | extern unsigned long rcutorture_vernum; | 479 | extern unsigned long rcutorture_vernum; | 
| 483 | unsigned long rcu_batches_started(void); | 480 | unsigned long rcu_get_gp_seq(void); | 
| 484 | unsigned long rcu_batches_started_bh(void); | 481 | unsigned long rcu_bh_get_gp_seq(void); | 
| 485 | unsigned long rcu_batches_started_sched(void); | 482 | unsigned long rcu_sched_get_gp_seq(void); | 
| 486 | unsigned long rcu_batches_completed(void); | ||
| 487 | unsigned long rcu_batches_completed_bh(void); | ||
| 488 | unsigned long rcu_batches_completed_sched(void); | ||
| 489 | unsigned long rcu_exp_batches_completed(void); | 483 | unsigned long rcu_exp_batches_completed(void); | 
| 490 | unsigned long rcu_exp_batches_completed_sched(void); | 484 | unsigned long rcu_exp_batches_completed_sched(void); | 
| 491 | unsigned long srcu_batches_completed(struct srcu_struct *sp); | 485 | unsigned long srcu_batches_completed(struct srcu_struct *sp); | 
diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c index df29119b2013..2b5a613afcf3 100644 --- a/kernel/rcu/rcuperf.c +++ b/kernel/rcu/rcuperf.c  | |||
| @@ -138,8 +138,7 @@ struct rcu_perf_ops { | |||
| 138 | void (*cleanup)(void); | 138 | void (*cleanup)(void); | 
| 139 | int (*readlock)(void); | 139 | int (*readlock)(void); | 
| 140 | void (*readunlock)(int idx); | 140 | void (*readunlock)(int idx); | 
| 141 | unsigned long (*started)(void); | 141 | unsigned long (*get_gp_seq)(void); | 
| 142 | unsigned long (*completed)(void); | ||
| 143 | unsigned long (*exp_completed)(void); | 142 | unsigned long (*exp_completed)(void); | 
| 144 | void (*async)(struct rcu_head *head, rcu_callback_t func); | 143 | void (*async)(struct rcu_head *head, rcu_callback_t func); | 
| 145 | void (*gp_barrier)(void); | 144 | void (*gp_barrier)(void); | 
| @@ -179,8 +178,7 @@ static struct rcu_perf_ops rcu_ops = { | |||
| 179 | .init = rcu_sync_perf_init, | 178 | .init = rcu_sync_perf_init, | 
| 180 | .readlock = rcu_perf_read_lock, | 179 | .readlock = rcu_perf_read_lock, | 
| 181 | .readunlock = rcu_perf_read_unlock, | 180 | .readunlock = rcu_perf_read_unlock, | 
| 182 | .started = rcu_batches_started, | 181 | .get_gp_seq = rcu_get_gp_seq, | 
| 183 | .completed = rcu_batches_completed, | ||
| 184 | .exp_completed = rcu_exp_batches_completed, | 182 | .exp_completed = rcu_exp_batches_completed, | 
| 185 | .async = call_rcu, | 183 | .async = call_rcu, | 
| 186 | .gp_barrier = rcu_barrier, | 184 | .gp_barrier = rcu_barrier, | 
| @@ -209,8 +207,7 @@ static struct rcu_perf_ops rcu_bh_ops = { | |||
| 209 | .init = rcu_sync_perf_init, | 207 | .init = rcu_sync_perf_init, | 
| 210 | .readlock = rcu_bh_perf_read_lock, | 208 | .readlock = rcu_bh_perf_read_lock, | 
| 211 | .readunlock = rcu_bh_perf_read_unlock, | 209 | .readunlock = rcu_bh_perf_read_unlock, | 
| 212 | .started = rcu_batches_started_bh, | 210 | .get_gp_seq = rcu_bh_get_gp_seq, | 
| 213 | .completed = rcu_batches_completed_bh, | ||
| 214 | .exp_completed = rcu_exp_batches_completed_sched, | 211 | .exp_completed = rcu_exp_batches_completed_sched, | 
| 215 | .async = call_rcu_bh, | 212 | .async = call_rcu_bh, | 
| 216 | .gp_barrier = rcu_barrier_bh, | 213 | .gp_barrier = rcu_barrier_bh, | 
| @@ -266,8 +263,7 @@ static struct rcu_perf_ops srcu_ops = { | |||
| 266 | .init = rcu_sync_perf_init, | 263 | .init = rcu_sync_perf_init, | 
| 267 | .readlock = srcu_perf_read_lock, | 264 | .readlock = srcu_perf_read_lock, | 
| 268 | .readunlock = srcu_perf_read_unlock, | 265 | .readunlock = srcu_perf_read_unlock, | 
| 269 | .started = NULL, | 266 | .get_gp_seq = srcu_perf_completed, | 
| 270 | .completed = srcu_perf_completed, | ||
| 271 | .exp_completed = srcu_perf_completed, | 267 | .exp_completed = srcu_perf_completed, | 
| 272 | .async = srcu_call_rcu, | 268 | .async = srcu_call_rcu, | 
| 273 | .gp_barrier = srcu_rcu_barrier, | 269 | .gp_barrier = srcu_rcu_barrier, | 
| @@ -295,8 +291,7 @@ static struct rcu_perf_ops srcud_ops = { | |||
| 295 | .cleanup = srcu_sync_perf_cleanup, | 291 | .cleanup = srcu_sync_perf_cleanup, | 
| 296 | .readlock = srcu_perf_read_lock, | 292 | .readlock = srcu_perf_read_lock, | 
| 297 | .readunlock = srcu_perf_read_unlock, | 293 | .readunlock = srcu_perf_read_unlock, | 
| 298 | .started = NULL, | 294 | .get_gp_seq = srcu_perf_completed, | 
| 299 | .completed = srcu_perf_completed, | ||
| 300 | .exp_completed = srcu_perf_completed, | 295 | .exp_completed = srcu_perf_completed, | 
| 301 | .async = srcu_call_rcu, | 296 | .async = srcu_call_rcu, | 
| 302 | .gp_barrier = srcu_rcu_barrier, | 297 | .gp_barrier = srcu_rcu_barrier, | 
| @@ -325,8 +320,7 @@ static struct rcu_perf_ops sched_ops = { | |||
| 325 | .init = rcu_sync_perf_init, | 320 | .init = rcu_sync_perf_init, | 
| 326 | .readlock = sched_perf_read_lock, | 321 | .readlock = sched_perf_read_lock, | 
| 327 | .readunlock = sched_perf_read_unlock, | 322 | .readunlock = sched_perf_read_unlock, | 
| 328 | .started = rcu_batches_started_sched, | 323 | .get_gp_seq = rcu_sched_get_gp_seq, | 
| 329 | .completed = rcu_batches_completed_sched, | ||
| 330 | .exp_completed = rcu_exp_batches_completed_sched, | 324 | .exp_completed = rcu_exp_batches_completed_sched, | 
| 331 | .async = call_rcu_sched, | 325 | .async = call_rcu_sched, | 
| 332 | .gp_barrier = rcu_barrier_sched, | 326 | .gp_barrier = rcu_barrier_sched, | 
| @@ -353,8 +347,7 @@ static struct rcu_perf_ops tasks_ops = { | |||
| 353 | .init = rcu_sync_perf_init, | 347 | .init = rcu_sync_perf_init, | 
| 354 | .readlock = tasks_perf_read_lock, | 348 | .readlock = tasks_perf_read_lock, | 
| 355 | .readunlock = tasks_perf_read_unlock, | 349 | .readunlock = tasks_perf_read_unlock, | 
| 356 | .started = rcu_no_completed, | 350 | .get_gp_seq = rcu_no_completed, | 
| 357 | .completed = rcu_no_completed, | ||
| 358 | .async = call_rcu_tasks, | 351 | .async = call_rcu_tasks, | 
| 359 | .gp_barrier = rcu_barrier_tasks, | 352 | .gp_barrier = rcu_barrier_tasks, | 
| 360 | .sync = synchronize_rcu_tasks, | 353 | .sync = synchronize_rcu_tasks, | 
| @@ -447,8 +440,7 @@ rcu_perf_writer(void *arg) | |||
| 447 | b_rcu_perf_writer_started = | 440 | b_rcu_perf_writer_started = | 
| 448 | cur_ops->exp_completed() / 2; | 441 | cur_ops->exp_completed() / 2; | 
| 449 | } else { | 442 | } else { | 
| 450 | b_rcu_perf_writer_started = | 443 | b_rcu_perf_writer_started = cur_ops->get_gp_seq(); | 
| 451 | cur_ops->completed(); | ||
| 452 | } | 444 | } | 
| 453 | } | 445 | } | 
| 454 | 446 | ||
| @@ -505,7 +497,7 @@ retry: | |||
| 505 | cur_ops->exp_completed() / 2; | 497 | cur_ops->exp_completed() / 2; | 
| 506 | } else { | 498 | } else { | 
| 507 | b_rcu_perf_writer_finished = | 499 | b_rcu_perf_writer_finished = | 
| 508 | cur_ops->completed(); | 500 | cur_ops->get_gp_seq(); | 
| 509 | } | 501 | } | 
| 510 | if (shutdown) { | 502 | if (shutdown) { | 
| 511 | smp_mb(); /* Assign before wake. */ | 503 | smp_mb(); /* Assign before wake. */ | 
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 5604bfac8df4..1f66597c7783 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c  | |||
| @@ -264,8 +264,7 @@ struct rcu_torture_ops { | |||
| 264 | int (*readlock)(void); | 264 | int (*readlock)(void); | 
| 265 | void (*read_delay)(struct torture_random_state *rrsp); | 265 | void (*read_delay)(struct torture_random_state *rrsp); | 
| 266 | void (*readunlock)(int idx); | 266 | void (*readunlock)(int idx); | 
| 267 | unsigned long (*started)(void); | 267 | unsigned long (*get_gp_seq)(void); | 
| 268 | unsigned long (*completed)(void); | ||
| 269 | void (*deferred_free)(struct rcu_torture *p); | 268 | void (*deferred_free)(struct rcu_torture *p); | 
| 270 | void (*sync)(void); | 269 | void (*sync)(void); | 
| 271 | void (*exp_sync)(void); | 270 | void (*exp_sync)(void); | 
| @@ -305,10 +304,10 @@ static void rcu_read_delay(struct torture_random_state *rrsp) | |||
| 305 | * force_quiescent_state. */ | 304 | * force_quiescent_state. */ | 
| 306 | 305 | ||
| 307 | if (!(torture_random(rrsp) % (nrealreaders * 2000 * longdelay_ms))) { | 306 | if (!(torture_random(rrsp) % (nrealreaders * 2000 * longdelay_ms))) { | 
| 308 | started = cur_ops->completed(); | 307 | started = cur_ops->get_gp_seq(); | 
| 309 | ts = rcu_trace_clock_local(); | 308 | ts = rcu_trace_clock_local(); | 
| 310 | mdelay(longdelay_ms); | 309 | mdelay(longdelay_ms); | 
| 311 | completed = cur_ops->completed(); | 310 | completed = cur_ops->get_gp_seq(); | 
| 312 | do_trace_rcu_torture_read(cur_ops->name, NULL, ts, | 311 | do_trace_rcu_torture_read(cur_ops->name, NULL, ts, | 
| 313 | started, completed); | 312 | started, completed); | 
| 314 | } | 313 | } | 
| @@ -400,8 +399,7 @@ static struct rcu_torture_ops rcu_ops = { | |||
| 400 | .readlock = rcu_torture_read_lock, | 399 | .readlock = rcu_torture_read_lock, | 
| 401 | .read_delay = rcu_read_delay, | 400 | .read_delay = rcu_read_delay, | 
| 402 | .readunlock = rcu_torture_read_unlock, | 401 | .readunlock = rcu_torture_read_unlock, | 
| 403 | .started = rcu_batches_started, | 402 | .get_gp_seq = rcu_get_gp_seq, | 
| 404 | .completed = rcu_batches_completed, | ||
| 405 | .deferred_free = rcu_torture_deferred_free, | 403 | .deferred_free = rcu_torture_deferred_free, | 
| 406 | .sync = synchronize_rcu, | 404 | .sync = synchronize_rcu, | 
| 407 | .exp_sync = synchronize_rcu_expedited, | 405 | .exp_sync = synchronize_rcu_expedited, | 
| @@ -442,8 +440,7 @@ static struct rcu_torture_ops rcu_bh_ops = { | |||
| 442 | .readlock = rcu_bh_torture_read_lock, | 440 | .readlock = rcu_bh_torture_read_lock, | 
| 443 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 441 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 
| 444 | .readunlock = rcu_bh_torture_read_unlock, | 442 | .readunlock = rcu_bh_torture_read_unlock, | 
| 445 | .started = rcu_batches_started_bh, | 443 | .get_gp_seq = rcu_bh_get_gp_seq, | 
| 446 | .completed = rcu_batches_completed_bh, | ||
| 447 | .deferred_free = rcu_bh_torture_deferred_free, | 444 | .deferred_free = rcu_bh_torture_deferred_free, | 
| 448 | .sync = synchronize_rcu_bh, | 445 | .sync = synchronize_rcu_bh, | 
| 449 | .exp_sync = synchronize_rcu_bh_expedited, | 446 | .exp_sync = synchronize_rcu_bh_expedited, | 
| @@ -486,8 +483,7 @@ static struct rcu_torture_ops rcu_busted_ops = { | |||
| 486 | .readlock = rcu_torture_read_lock, | 483 | .readlock = rcu_torture_read_lock, | 
| 487 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 484 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 
| 488 | .readunlock = rcu_torture_read_unlock, | 485 | .readunlock = rcu_torture_read_unlock, | 
| 489 | .started = rcu_no_completed, | 486 | .get_gp_seq = rcu_no_completed, | 
| 490 | .completed = rcu_no_completed, | ||
| 491 | .deferred_free = rcu_busted_torture_deferred_free, | 487 | .deferred_free = rcu_busted_torture_deferred_free, | 
| 492 | .sync = synchronize_rcu_busted, | 488 | .sync = synchronize_rcu_busted, | 
| 493 | .exp_sync = synchronize_rcu_busted, | 489 | .exp_sync = synchronize_rcu_busted, | 
| @@ -575,8 +571,7 @@ static struct rcu_torture_ops srcu_ops = { | |||
| 575 | .readlock = srcu_torture_read_lock, | 571 | .readlock = srcu_torture_read_lock, | 
| 576 | .read_delay = srcu_read_delay, | 572 | .read_delay = srcu_read_delay, | 
| 577 | .readunlock = srcu_torture_read_unlock, | 573 | .readunlock = srcu_torture_read_unlock, | 
| 578 | .started = NULL, | 574 | .get_gp_seq = srcu_torture_completed, | 
| 579 | .completed = srcu_torture_completed, | ||
| 580 | .deferred_free = srcu_torture_deferred_free, | 575 | .deferred_free = srcu_torture_deferred_free, | 
| 581 | .sync = srcu_torture_synchronize, | 576 | .sync = srcu_torture_synchronize, | 
| 582 | .exp_sync = srcu_torture_synchronize_expedited, | 577 | .exp_sync = srcu_torture_synchronize_expedited, | 
| @@ -613,8 +608,7 @@ static struct rcu_torture_ops srcud_ops = { | |||
| 613 | .readlock = srcu_torture_read_lock, | 608 | .readlock = srcu_torture_read_lock, | 
| 614 | .read_delay = srcu_read_delay, | 609 | .read_delay = srcu_read_delay, | 
| 615 | .readunlock = srcu_torture_read_unlock, | 610 | .readunlock = srcu_torture_read_unlock, | 
| 616 | .started = NULL, | 611 | .get_gp_seq = srcu_torture_completed, | 
| 617 | .completed = srcu_torture_completed, | ||
| 618 | .deferred_free = srcu_torture_deferred_free, | 612 | .deferred_free = srcu_torture_deferred_free, | 
| 619 | .sync = srcu_torture_synchronize, | 613 | .sync = srcu_torture_synchronize, | 
| 620 | .exp_sync = srcu_torture_synchronize_expedited, | 614 | .exp_sync = srcu_torture_synchronize_expedited, | 
| @@ -651,8 +645,7 @@ static struct rcu_torture_ops sched_ops = { | |||
| 651 | .readlock = sched_torture_read_lock, | 645 | .readlock = sched_torture_read_lock, | 
| 652 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 646 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 
| 653 | .readunlock = sched_torture_read_unlock, | 647 | .readunlock = sched_torture_read_unlock, | 
| 654 | .started = rcu_batches_started_sched, | 648 | .get_gp_seq = rcu_sched_get_gp_seq, | 
| 655 | .completed = rcu_batches_completed_sched, | ||
| 656 | .deferred_free = rcu_sched_torture_deferred_free, | 649 | .deferred_free = rcu_sched_torture_deferred_free, | 
| 657 | .sync = synchronize_sched, | 650 | .sync = synchronize_sched, | 
| 658 | .exp_sync = synchronize_sched_expedited, | 651 | .exp_sync = synchronize_sched_expedited, | 
| @@ -690,8 +683,7 @@ static struct rcu_torture_ops tasks_ops = { | |||
| 690 | .readlock = tasks_torture_read_lock, | 683 | .readlock = tasks_torture_read_lock, | 
| 691 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 684 | .read_delay = rcu_read_delay, /* just reuse rcu's version. */ | 
| 692 | .readunlock = tasks_torture_read_unlock, | 685 | .readunlock = tasks_torture_read_unlock, | 
| 693 | .started = rcu_no_completed, | 686 | .get_gp_seq = rcu_no_completed, | 
| 694 | .completed = rcu_no_completed, | ||
| 695 | .deferred_free = rcu_tasks_torture_deferred_free, | 687 | .deferred_free = rcu_tasks_torture_deferred_free, | 
| 696 | .sync = synchronize_rcu_tasks, | 688 | .sync = synchronize_rcu_tasks, | 
| 697 | .exp_sync = synchronize_rcu_tasks, | 689 | .exp_sync = synchronize_rcu_tasks, | 
| @@ -1104,10 +1096,7 @@ static void rcu_torture_timer(struct timer_list *unused) | |||
| 1104 | unsigned long long ts; | 1096 | unsigned long long ts; | 
| 1105 | 1097 | ||
| 1106 | idx = cur_ops->readlock(); | 1098 | idx = cur_ops->readlock(); | 
| 1107 | if (cur_ops->started) | 1099 | started = cur_ops->get_gp_seq(); | 
| 1108 | started = cur_ops->started(); | ||
| 1109 | else | ||
| 1110 | started = cur_ops->completed(); | ||
| 1111 | ts = rcu_trace_clock_local(); | 1100 | ts = rcu_trace_clock_local(); | 
| 1112 | p = rcu_dereference_check(rcu_torture_current, | 1101 | p = rcu_dereference_check(rcu_torture_current, | 
| 1113 | rcu_read_lock_bh_held() || | 1102 | rcu_read_lock_bh_held() || | 
| @@ -1131,7 +1120,7 @@ static void rcu_torture_timer(struct timer_list *unused) | |||
| 1131 | /* Should not happen, but... */ | 1120 | /* Should not happen, but... */ | 
| 1132 | pipe_count = RCU_TORTURE_PIPE_LEN; | 1121 | pipe_count = RCU_TORTURE_PIPE_LEN; | 
| 1133 | } | 1122 | } | 
| 1134 | completed = cur_ops->completed(); | 1123 | completed = cur_ops->get_gp_seq(); | 
| 1135 | if (pipe_count > 1) { | 1124 | if (pipe_count > 1) { | 
| 1136 | do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu, ts, | 1125 | do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu, ts, | 
| 1137 | started, completed); | 1126 | started, completed); | 
| @@ -1139,8 +1128,8 @@ static void rcu_torture_timer(struct timer_list *unused) | |||
| 1139 | } | 1128 | } | 
| 1140 | __this_cpu_inc(rcu_torture_count[pipe_count]); | 1129 | __this_cpu_inc(rcu_torture_count[pipe_count]); | 
| 1141 | completed = completed - started; | 1130 | completed = completed - started; | 
| 1142 | if (cur_ops->started) | 1131 | if (completed > ULONG_MAX >> 1) | 
| 1143 | completed++; | 1132 | completed = 0; /* Not all gp_seq have full range. */ | 
| 1144 | if (completed > RCU_TORTURE_PIPE_LEN) { | 1133 | if (completed > RCU_TORTURE_PIPE_LEN) { | 
| 1145 | /* Should not happen, but... */ | 1134 | /* Should not happen, but... */ | 
| 1146 | completed = RCU_TORTURE_PIPE_LEN; | 1135 | completed = RCU_TORTURE_PIPE_LEN; | 
| @@ -1187,10 +1176,7 @@ rcu_torture_reader(void *arg) | |||
| 1187 | mod_timer(&t, jiffies + 1); | 1176 | mod_timer(&t, jiffies + 1); | 
| 1188 | } | 1177 | } | 
| 1189 | idx = cur_ops->readlock(); | 1178 | idx = cur_ops->readlock(); | 
| 1190 | if (cur_ops->started) | 1179 | started = cur_ops->get_gp_seq(); | 
| 1191 | started = cur_ops->started(); | ||
| 1192 | else | ||
| 1193 | started = cur_ops->completed(); | ||
| 1194 | ts = rcu_trace_clock_local(); | 1180 | ts = rcu_trace_clock_local(); | 
| 1195 | p = rcu_dereference_check(rcu_torture_current, | 1181 | p = rcu_dereference_check(rcu_torture_current, | 
| 1196 | rcu_read_lock_bh_held() || | 1182 | rcu_read_lock_bh_held() || | 
| @@ -1212,7 +1198,7 @@ rcu_torture_reader(void *arg) | |||
| 1212 | /* Should not happen, but... */ | 1198 | /* Should not happen, but... */ | 
| 1213 | pipe_count = RCU_TORTURE_PIPE_LEN; | 1199 | pipe_count = RCU_TORTURE_PIPE_LEN; | 
| 1214 | } | 1200 | } | 
| 1215 | completed = cur_ops->completed(); | 1201 | completed = cur_ops->get_gp_seq(); | 
| 1216 | if (pipe_count > 1) { | 1202 | if (pipe_count > 1) { | 
| 1217 | do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu, | 1203 | do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu, | 
| 1218 | ts, started, completed); | 1204 | ts, started, completed); | 
| @@ -1220,8 +1206,8 @@ rcu_torture_reader(void *arg) | |||
| 1220 | } | 1206 | } | 
| 1221 | __this_cpu_inc(rcu_torture_count[pipe_count]); | 1207 | __this_cpu_inc(rcu_torture_count[pipe_count]); | 
| 1222 | completed = completed - started; | 1208 | completed = completed - started; | 
| 1223 | if (cur_ops->started) | 1209 | if (completed > ULONG_MAX >> 1) | 
| 1224 | completed++; | 1210 | completed = 0; /* Not all gp_seq have full range. */ | 
| 1225 | if (completed > RCU_TORTURE_PIPE_LEN) { | 1211 | if (completed > RCU_TORTURE_PIPE_LEN) { | 
| 1226 | /* Should not happen, but... */ | 1212 | /* Should not happen, but... */ | 
| 1227 | completed = RCU_TORTURE_PIPE_LEN; | 1213 | completed = RCU_TORTURE_PIPE_LEN; | 
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 3c3af7e2758f..547112bec26a 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c  | |||
| @@ -530,58 +530,31 @@ static void force_quiescent_state(struct rcu_state *rsp); | |||
| 530 | static int rcu_pending(void); | 530 | static int rcu_pending(void); | 
| 531 | 531 | ||
| 532 | /* | 532 | /* | 
| 533 | * Return the number of RCU batches started thus far for debug & stats. | 533 | * Return the number of RCU GPs completed thus far for debug & stats. | 
| 534 | */ | 534 | */ | 
| 535 | unsigned long rcu_batches_started(void) | 535 | unsigned long rcu_get_gp_seq(void) | 
| 536 | { | 536 | { | 
| 537 | return rcu_state_p->gpnum; | 537 | return rcu_seq_ctr(READ_ONCE(rcu_state_p->gp_seq)); | 
| 538 | } | 538 | } | 
| 539 | EXPORT_SYMBOL_GPL(rcu_batches_started); | 539 | EXPORT_SYMBOL_GPL(rcu_get_gp_seq); | 
| 540 | 540 | ||
| 541 | /* | 541 | /* | 
| 542 | * Return the number of RCU-sched batches started thus far for debug & stats. | 542 | * Return the number of RCU-sched GPs completed thus far for debug & stats. | 
| 543 | */ | 543 | */ | 
| 544 | unsigned long rcu_batches_started_sched(void) | 544 | unsigned long rcu_sched_get_gp_seq(void) | 
| 545 | { | 545 | { | 
| 546 | return rcu_sched_state.gpnum; | 546 | return rcu_seq_ctr(READ_ONCE(rcu_sched_state.gp_seq)); | 
| 547 | } | 547 | } | 
| 548 | EXPORT_SYMBOL_GPL(rcu_batches_started_sched); | 548 | EXPORT_SYMBOL_GPL(rcu_sched_get_gp_seq); | 
| 549 | 549 | ||
| 550 | /* | 550 | /* | 
| 551 | * Return the number of RCU BH batches started thus far for debug & stats. | 551 | * Return the number of RCU-bh GPs completed thus far for debug & stats. | 
| 552 | */ | 552 | */ | 
| 553 | unsigned long rcu_batches_started_bh(void) | 553 | unsigned long rcu_bh_get_gp_seq(void) | 
| 554 | { | 554 | { | 
| 555 | return rcu_bh_state.gpnum; | 555 | return rcu_seq_ctr(READ_ONCE(rcu_bh_state.gp_seq)); | 
| 556 | } | 556 | } | 
| 557 | EXPORT_SYMBOL_GPL(rcu_batches_started_bh); | 557 | EXPORT_SYMBOL_GPL(rcu_bh_get_gp_seq); | 
| 558 | |||
| 559 | /* | ||
| 560 | * Return the number of RCU batches completed thus far for debug & stats. | ||
| 561 | */ | ||
| 562 | unsigned long rcu_batches_completed(void) | ||
| 563 | { | ||
| 564 | return rcu_state_p->completed; | ||
| 565 | } | ||
| 566 | EXPORT_SYMBOL_GPL(rcu_batches_completed); | ||
| 567 | |||
| 568 | /* | ||
| 569 | * Return the number of RCU-sched batches completed thus far for debug & stats. | ||
| 570 | */ | ||
| 571 | unsigned long rcu_batches_completed_sched(void) | ||
| 572 | { | ||
| 573 | return rcu_sched_state.completed; | ||
| 574 | } | ||
| 575 | EXPORT_SYMBOL_GPL(rcu_batches_completed_sched); | ||
| 576 | |||
| 577 | /* | ||
| 578 | * Return the number of RCU BH batches completed thus far for debug & stats. | ||
| 579 | */ | ||
| 580 | unsigned long rcu_batches_completed_bh(void) | ||
| 581 | { | ||
| 582 | return rcu_bh_state.completed; | ||
| 583 | } | ||
| 584 | EXPORT_SYMBOL_GPL(rcu_batches_completed_bh); | ||
| 585 | 558 | ||
| 586 | /* | 559 | /* | 
| 587 | * Return the number of RCU expedited batches completed thus far for | 560 | * Return the number of RCU expedited batches completed thus far for | 
