aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree_plugin.h
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcutree_plugin.h')
-rw-r--r--kernel/rcutree_plugin.h10
1 files changed, 9 insertions, 1 deletions
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index ed241fc478f0..464ad2cdee00 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -986,6 +986,7 @@ static void rcu_needs_cpu_flush(void)
986 986
987#define RCU_NEEDS_CPU_FLUSHES 5 987#define RCU_NEEDS_CPU_FLUSHES 5
988static DEFINE_PER_CPU(int, rcu_dyntick_drain); 988static DEFINE_PER_CPU(int, rcu_dyntick_drain);
989static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff);
989 990
990/* 991/*
991 * Check to see if any future RCU-related work will need to be done 992 * Check to see if any future RCU-related work will need to be done
@@ -1013,6 +1014,7 @@ int rcu_needs_cpu(int cpu)
1013 for_each_cpu_not(thatcpu, nohz_cpu_mask) 1014 for_each_cpu_not(thatcpu, nohz_cpu_mask)
1014 if (thatcpu != cpu) { 1015 if (thatcpu != cpu) {
1015 per_cpu(rcu_dyntick_drain, cpu) = 0; 1016 per_cpu(rcu_dyntick_drain, cpu) = 0;
1017 per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1;
1016 return rcu_needs_cpu_quick_check(cpu); 1018 return rcu_needs_cpu_quick_check(cpu);
1017 } 1019 }
1018 1020
@@ -1022,6 +1024,7 @@ int rcu_needs_cpu(int cpu)
1022 per_cpu(rcu_dyntick_drain, cpu) = RCU_NEEDS_CPU_FLUSHES; 1024 per_cpu(rcu_dyntick_drain, cpu) = RCU_NEEDS_CPU_FLUSHES;
1023 } else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) { 1025 } else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) {
1024 /* We have hit the limit, so time to give up. */ 1026 /* We have hit the limit, so time to give up. */
1027 per_cpu(rcu_dyntick_holdoff, cpu) = jiffies;
1025 return rcu_needs_cpu_quick_check(cpu); 1028 return rcu_needs_cpu_quick_check(cpu);
1026 } 1029 }
1027 1030
@@ -1038,8 +1041,10 @@ int rcu_needs_cpu(int cpu)
1038 } 1041 }
1039 1042
1040 /* If RCU callbacks are still pending, RCU still needs this CPU. */ 1043 /* If RCU callbacks are still pending, RCU still needs this CPU. */
1041 if (c) 1044 if (c) {
1042 raise_softirq(RCU_SOFTIRQ); 1045 raise_softirq(RCU_SOFTIRQ);
1046 per_cpu(rcu_dyntick_holdoff, cpu) = jiffies;
1047 }
1043 return c; 1048 return c;
1044} 1049}
1045 1050
@@ -1050,10 +1055,13 @@ int rcu_needs_cpu(int cpu)
1050static void rcu_needs_cpu_flush(void) 1055static void rcu_needs_cpu_flush(void)
1051{ 1056{
1052 int cpu = smp_processor_id(); 1057 int cpu = smp_processor_id();
1058 unsigned long flags;
1053 1059
1054 if (per_cpu(rcu_dyntick_drain, cpu) <= 0) 1060 if (per_cpu(rcu_dyntick_drain, cpu) <= 0)
1055 return; 1061 return;
1062 local_irq_save(flags);
1056 (void)rcu_needs_cpu(cpu); 1063 (void)rcu_needs_cpu(cpu);
1064 local_irq_restore(flags);
1057} 1065}
1058 1066
1059#endif /* #else #if !defined(CONFIG_RCU_FAST_NO_HZ) */ 1067#endif /* #else #if !defined(CONFIG_RCU_FAST_NO_HZ) */