diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2011-10-31 18:01:54 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-12-11 13:31:42 -0500 |
commit | 4145fa7fbee3ec1e61c52825b146192885d9759f (patch) | |
tree | 58e0767a59bf110acb99da3fb5c1f0f0b5170be8 /kernel/rcutree.c | |
parent | 9ceae0e248fb553c702d51d5275167d462f4efd2 (diff) |
rcu: Deconfuse dynticks entry-exit tracing
The trace_rcu_dyntick() trace event did not print both the old and
the new value of the nesting level, and furthermore printed only
the low-order 32 bits of it. This could result in some confusion
when interpreting trace-event dumps, so this commit prints both
the old and the new value, prints the full 64 bits, and also selects
the process-entry/exit increment to print nicely in hexadecimal.
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r-- | kernel/rcutree.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 489b62a67d35..06e40dd53b23 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -196,7 +196,7 @@ void rcu_note_context_switch(int cpu) | |||
196 | EXPORT_SYMBOL_GPL(rcu_note_context_switch); | 196 | EXPORT_SYMBOL_GPL(rcu_note_context_switch); |
197 | 197 | ||
198 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { | 198 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { |
199 | .dynticks_nesting = LLONG_MAX / 2, | 199 | .dynticks_nesting = DYNTICK_TASK_NESTING, |
200 | .dynticks = ATOMIC_INIT(1), | 200 | .dynticks = ATOMIC_INIT(1), |
201 | }; | 201 | }; |
202 | 202 | ||
@@ -348,17 +348,17 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp) | |||
348 | * we really have entered idle, and must do the appropriate accounting. | 348 | * we really have entered idle, and must do the appropriate accounting. |
349 | * The caller must have disabled interrupts. | 349 | * The caller must have disabled interrupts. |
350 | */ | 350 | */ |
351 | static void rcu_idle_enter_common(struct rcu_dynticks *rdtp) | 351 | static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval) |
352 | { | 352 | { |
353 | if (rdtp->dynticks_nesting) { | 353 | if (rdtp->dynticks_nesting) { |
354 | trace_rcu_dyntick("--=", rdtp->dynticks_nesting); | 354 | trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting); |
355 | return; | 355 | return; |
356 | } | 356 | } |
357 | trace_rcu_dyntick("Start", rdtp->dynticks_nesting); | 357 | trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting); |
358 | if (!idle_cpu(smp_processor_id())) { | 358 | if (!idle_cpu(smp_processor_id())) { |
359 | WARN_ON_ONCE(1); /* must be idle task! */ | 359 | WARN_ON_ONCE(1); /* must be idle task! */ |
360 | trace_rcu_dyntick("Error on entry: not idle task", | 360 | trace_rcu_dyntick("Error on entry: not idle task", |
361 | rdtp->dynticks_nesting); | 361 | oldval, rdtp->dynticks_nesting); |
362 | ftrace_dump(DUMP_ALL); | 362 | ftrace_dump(DUMP_ALL); |
363 | } | 363 | } |
364 | /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ | 364 | /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ |
@@ -383,12 +383,14 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp) | |||
383 | void rcu_idle_enter(void) | 383 | void rcu_idle_enter(void) |
384 | { | 384 | { |
385 | unsigned long flags; | 385 | unsigned long flags; |
386 | long long oldval; | ||
386 | struct rcu_dynticks *rdtp; | 387 | struct rcu_dynticks *rdtp; |
387 | 388 | ||
388 | local_irq_save(flags); | 389 | local_irq_save(flags); |
389 | rdtp = &__get_cpu_var(rcu_dynticks); | 390 | rdtp = &__get_cpu_var(rcu_dynticks); |
391 | oldval = rdtp->dynticks_nesting; | ||
390 | rdtp->dynticks_nesting = 0; | 392 | rdtp->dynticks_nesting = 0; |
391 | rcu_idle_enter_common(rdtp); | 393 | rcu_idle_enter_common(rdtp, oldval); |
392 | local_irq_restore(flags); | 394 | local_irq_restore(flags); |
393 | } | 395 | } |
394 | 396 | ||
@@ -411,13 +413,15 @@ void rcu_idle_enter(void) | |||
411 | void rcu_irq_exit(void) | 413 | void rcu_irq_exit(void) |
412 | { | 414 | { |
413 | unsigned long flags; | 415 | unsigned long flags; |
416 | long long oldval; | ||
414 | struct rcu_dynticks *rdtp; | 417 | struct rcu_dynticks *rdtp; |
415 | 418 | ||
416 | local_irq_save(flags); | 419 | local_irq_save(flags); |
417 | rdtp = &__get_cpu_var(rcu_dynticks); | 420 | rdtp = &__get_cpu_var(rcu_dynticks); |
421 | oldval = rdtp->dynticks_nesting; | ||
418 | rdtp->dynticks_nesting--; | 422 | rdtp->dynticks_nesting--; |
419 | WARN_ON_ONCE(rdtp->dynticks_nesting < 0); | 423 | WARN_ON_ONCE(rdtp->dynticks_nesting < 0); |
420 | rcu_idle_enter_common(rdtp); | 424 | rcu_idle_enter_common(rdtp, oldval); |
421 | local_irq_restore(flags); | 425 | local_irq_restore(flags); |
422 | } | 426 | } |
423 | 427 | ||
@@ -431,7 +435,7 @@ void rcu_irq_exit(void) | |||
431 | static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval) | 435 | static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval) |
432 | { | 436 | { |
433 | if (oldval) { | 437 | if (oldval) { |
434 | trace_rcu_dyntick("++=", rdtp->dynticks_nesting); | 438 | trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting); |
435 | return; | 439 | return; |
436 | } | 440 | } |
437 | smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */ | 441 | smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */ |
@@ -439,10 +443,11 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval) | |||
439 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ | 443 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ |
440 | smp_mb__after_atomic_inc(); /* See above. */ | 444 | smp_mb__after_atomic_inc(); /* See above. */ |
441 | WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); | 445 | WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); |
442 | trace_rcu_dyntick("End", oldval); | 446 | trace_rcu_dyntick("End", oldval, rdtp->dynticks_nesting); |
443 | if (!idle_cpu(smp_processor_id())) { | 447 | if (!idle_cpu(smp_processor_id())) { |
444 | WARN_ON_ONCE(1); /* must be idle task! */ | 448 | WARN_ON_ONCE(1); /* must be idle task! */ |
445 | trace_rcu_dyntick("Error on exit: not idle task", oldval); | 449 | trace_rcu_dyntick("Error on exit: not idle task", |
450 | oldval, rdtp->dynticks_nesting); | ||
446 | ftrace_dump(DUMP_ALL); | 451 | ftrace_dump(DUMP_ALL); |
447 | } | 452 | } |
448 | } | 453 | } |
@@ -453,8 +458,8 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval) | |||
453 | * Exit idle mode, in other words, -enter- the mode in which RCU | 458 | * Exit idle mode, in other words, -enter- the mode in which RCU |
454 | * read-side critical sections can occur. | 459 | * read-side critical sections can occur. |
455 | * | 460 | * |
456 | * We crowbar the ->dynticks_nesting field to LLONG_MAX/2 to allow for | 461 | * We crowbar the ->dynticks_nesting field to DYNTICK_TASK_NESTING to |
457 | * the possibility of usermode upcalls messing up our count | 462 | * allow for the possibility of usermode upcalls messing up our count |
458 | * of interrupt nesting level during the busy period that is just | 463 | * of interrupt nesting level during the busy period that is just |
459 | * now starting. | 464 | * now starting. |
460 | */ | 465 | */ |
@@ -468,7 +473,7 @@ void rcu_idle_exit(void) | |||
468 | rdtp = &__get_cpu_var(rcu_dynticks); | 473 | rdtp = &__get_cpu_var(rcu_dynticks); |
469 | oldval = rdtp->dynticks_nesting; | 474 | oldval = rdtp->dynticks_nesting; |
470 | WARN_ON_ONCE(oldval != 0); | 475 | WARN_ON_ONCE(oldval != 0); |
471 | rdtp->dynticks_nesting = LLONG_MAX / 2; | 476 | rdtp->dynticks_nesting = DYNTICK_TASK_NESTING; |
472 | rcu_idle_exit_common(rdtp, oldval); | 477 | rcu_idle_exit_common(rdtp, oldval); |
473 | local_irq_restore(flags); | 478 | local_irq_restore(flags); |
474 | } | 479 | } |
@@ -2012,7 +2017,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp) | |||
2012 | rdp->nxttail[i] = &rdp->nxtlist; | 2017 | rdp->nxttail[i] = &rdp->nxtlist; |
2013 | rdp->qlen = 0; | 2018 | rdp->qlen = 0; |
2014 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); | 2019 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); |
2015 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != LLONG_MAX / 2); | 2020 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_NESTING); |
2016 | WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1); | 2021 | WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1); |
2017 | rdp->cpu = cpu; | 2022 | rdp->cpu = cpu; |
2018 | rdp->rsp = rsp; | 2023 | rdp->rsp = rsp; |
@@ -2040,7 +2045,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible) | |||
2040 | rdp->qlen_last_fqs_check = 0; | 2045 | rdp->qlen_last_fqs_check = 0; |
2041 | rdp->n_force_qs_snap = rsp->n_force_qs; | 2046 | rdp->n_force_qs_snap = rsp->n_force_qs; |
2042 | rdp->blimit = blimit; | 2047 | rdp->blimit = blimit; |
2043 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != LLONG_MAX / 2); | 2048 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_NESTING); |
2044 | WARN_ON_ONCE((atomic_read(&rdp->dynticks->dynticks) & 0x1) != 1); | 2049 | WARN_ON_ONCE((atomic_read(&rdp->dynticks->dynticks) & 0x1) != 1); |
2045 | raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */ | 2050 | raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */ |
2046 | 2051 | ||