diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-05-06 02:04:22 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2015-05-27 15:59:07 -0400 |
commit | 1ce46ee597bc36fde6984e91aecc2d662a754199 (patch) | |
tree | e8168043f8921ac78f74c88144918b1b4d4509fb | |
parent | e72aeafc66060d3fc6b4d2120db00058572b3186 (diff) |
rcu: Conditionally compile RCU's eqs warnings
This commit applies some warning-omission micro-optimizations to RCU's
various extended-quiescent-state functions, which are on the kernel/user
hotpath for CONFIG_NO_HZ_FULL=y.
Reported-by: Rik van Riel <riel@redhat.com>
Reported by: Mike Galbraith <umgwanakikbuti@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r-- | kernel/rcu/tree.c | 23 | ||||
-rw-r--r-- | lib/Kconfig.debug | 11 |
2 files changed, 26 insertions, 8 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 0e9ce1272971..991fa5c5dc5e 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
@@ -620,7 +620,8 @@ static void rcu_eqs_enter_common(long long oldval, bool user) | |||
620 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); | 620 | struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); |
621 | 621 | ||
622 | trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting); | 622 | trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting); |
623 | if (!user && !is_idle_task(current)) { | 623 | if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
624 | !user && !is_idle_task(current)) { | ||
624 | struct task_struct *idle __maybe_unused = | 625 | struct task_struct *idle __maybe_unused = |
625 | idle_task(smp_processor_id()); | 626 | idle_task(smp_processor_id()); |
626 | 627 | ||
@@ -639,7 +640,8 @@ static void rcu_eqs_enter_common(long long oldval, bool user) | |||
639 | smp_mb__before_atomic(); /* See above. */ | 640 | smp_mb__before_atomic(); /* See above. */ |
640 | atomic_inc(&rdtp->dynticks); | 641 | atomic_inc(&rdtp->dynticks); |
641 | smp_mb__after_atomic(); /* Force ordering with next sojourn. */ | 642 | smp_mb__after_atomic(); /* Force ordering with next sojourn. */ |
642 | WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1); | 643 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
644 | atomic_read(&rdtp->dynticks) & 0x1); | ||
643 | rcu_dynticks_task_enter(); | 645 | rcu_dynticks_task_enter(); |
644 | 646 | ||
645 | /* | 647 | /* |
@@ -665,7 +667,8 @@ static void rcu_eqs_enter(bool user) | |||
665 | 667 | ||
666 | rdtp = this_cpu_ptr(&rcu_dynticks); | 668 | rdtp = this_cpu_ptr(&rcu_dynticks); |
667 | oldval = rdtp->dynticks_nesting; | 669 | oldval = rdtp->dynticks_nesting; |
668 | WARN_ON_ONCE((oldval & DYNTICK_TASK_NEST_MASK) == 0); | 670 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
671 | (oldval & DYNTICK_TASK_NEST_MASK) == 0); | ||
669 | if ((oldval & DYNTICK_TASK_NEST_MASK) == DYNTICK_TASK_NEST_VALUE) { | 672 | if ((oldval & DYNTICK_TASK_NEST_MASK) == DYNTICK_TASK_NEST_VALUE) { |
670 | rdtp->dynticks_nesting = 0; | 673 | rdtp->dynticks_nesting = 0; |
671 | rcu_eqs_enter_common(oldval, user); | 674 | rcu_eqs_enter_common(oldval, user); |
@@ -738,7 +741,8 @@ void rcu_irq_exit(void) | |||
738 | rdtp = this_cpu_ptr(&rcu_dynticks); | 741 | rdtp = this_cpu_ptr(&rcu_dynticks); |
739 | oldval = rdtp->dynticks_nesting; | 742 | oldval = rdtp->dynticks_nesting; |
740 | rdtp->dynticks_nesting--; | 743 | rdtp->dynticks_nesting--; |
741 | WARN_ON_ONCE(rdtp->dynticks_nesting < 0); | 744 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
745 | rdtp->dynticks_nesting < 0); | ||
742 | if (rdtp->dynticks_nesting) | 746 | if (rdtp->dynticks_nesting) |
743 | trace_rcu_dyntick(TPS("--="), oldval, rdtp->dynticks_nesting); | 747 | trace_rcu_dyntick(TPS("--="), oldval, rdtp->dynticks_nesting); |
744 | else | 748 | else |
@@ -763,10 +767,12 @@ static void rcu_eqs_exit_common(long long oldval, int user) | |||
763 | atomic_inc(&rdtp->dynticks); | 767 | atomic_inc(&rdtp->dynticks); |
764 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ | 768 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ |
765 | smp_mb__after_atomic(); /* See above. */ | 769 | smp_mb__after_atomic(); /* See above. */ |
766 | WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); | 770 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
771 | !(atomic_read(&rdtp->dynticks) & 0x1)); | ||
767 | rcu_cleanup_after_idle(); | 772 | rcu_cleanup_after_idle(); |
768 | trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting); | 773 | trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting); |
769 | if (!user && !is_idle_task(current)) { | 774 | if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
775 | !user && !is_idle_task(current)) { | ||
770 | struct task_struct *idle __maybe_unused = | 776 | struct task_struct *idle __maybe_unused = |
771 | idle_task(smp_processor_id()); | 777 | idle_task(smp_processor_id()); |
772 | 778 | ||
@@ -790,7 +796,7 @@ static void rcu_eqs_exit(bool user) | |||
790 | 796 | ||
791 | rdtp = this_cpu_ptr(&rcu_dynticks); | 797 | rdtp = this_cpu_ptr(&rcu_dynticks); |
792 | oldval = rdtp->dynticks_nesting; | 798 | oldval = rdtp->dynticks_nesting; |
793 | WARN_ON_ONCE(oldval < 0); | 799 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0); |
794 | if (oldval & DYNTICK_TASK_NEST_MASK) { | 800 | if (oldval & DYNTICK_TASK_NEST_MASK) { |
795 | rdtp->dynticks_nesting += DYNTICK_TASK_NEST_VALUE; | 801 | rdtp->dynticks_nesting += DYNTICK_TASK_NEST_VALUE; |
796 | } else { | 802 | } else { |
@@ -863,7 +869,8 @@ void rcu_irq_enter(void) | |||
863 | rdtp = this_cpu_ptr(&rcu_dynticks); | 869 | rdtp = this_cpu_ptr(&rcu_dynticks); |
864 | oldval = rdtp->dynticks_nesting; | 870 | oldval = rdtp->dynticks_nesting; |
865 | rdtp->dynticks_nesting++; | 871 | rdtp->dynticks_nesting++; |
866 | WARN_ON_ONCE(rdtp->dynticks_nesting == 0); | 872 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && |
873 | rdtp->dynticks_nesting == 0); | ||
867 | if (oldval) | 874 | if (oldval) |
868 | trace_rcu_dyntick(TPS("++="), oldval, rdtp->dynticks_nesting); | 875 | trace_rcu_dyntick(TPS("++="), oldval, rdtp->dynticks_nesting); |
869 | else | 876 | else |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c4e1cf04cf57..b908048f8d6a 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -1373,6 +1373,17 @@ config RCU_TRACE | |||
1373 | Say Y here if you want to enable RCU tracing | 1373 | Say Y here if you want to enable RCU tracing |
1374 | Say N if you are unsure. | 1374 | Say N if you are unsure. |
1375 | 1375 | ||
1376 | config RCU_EQS_DEBUG | ||
1377 | bool "Use this when adding any sort of NO_HZ support to your arch" | ||
1378 | depends on DEBUG_KERNEL | ||
1379 | help | ||
1380 | This option provides consistency checks in RCU's handling of | ||
1381 | NO_HZ. These checks have proven quite helpful in detecting | ||
1382 | bugs in arch-specific NO_HZ code. | ||
1383 | |||
1384 | Say N here if you need ultimate kernel/user switch latencies | ||
1385 | Say Y if you are unsure | ||
1386 | |||
1376 | endmenu # "RCU Debugging" | 1387 | endmenu # "RCU Debugging" |
1377 | 1388 | ||
1378 | config DEBUG_BLOCK_EXT_DEVT | 1389 | config DEBUG_BLOCK_EXT_DEVT |