diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2012-02-23 20:13:19 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2012-04-24 23:55:19 -0400 |
commit | 2ee3dc80660ac8285a37e662fd91b2e45c46f06a (patch) | |
tree | d6fcd186eabf672b7bc54bd2f04f1f7956f8afe1 /kernel/rcutree_plugin.h | |
parent | 2fdbb31b662787f78bb78b3e4e18f1a072058ffc (diff) |
rcu: Make RCU_FAST_NO_HZ use timer rather than hrtimer
The RCU_FAST_NO_HZ facility uses an hrtimer to wake up a CPU when
it is allowed to go into dyntick-idle mode, which is almost always
cancelled soon after. This is not what hrtimers are good at, so
this commit switches to the timer wheel.
Reported-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcutree_plugin.h')
-rw-r--r-- | kernel/rcutree_plugin.h | 40 |
1 files changed, 12 insertions, 28 deletions
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 1e561ab952a3..0f007b363dba 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -1980,9 +1980,7 @@ static void rcu_prepare_for_idle(int cpu) | |||
1980 | 1980 | ||
1981 | static DEFINE_PER_CPU(int, rcu_dyntick_drain); | 1981 | static DEFINE_PER_CPU(int, rcu_dyntick_drain); |
1982 | static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff); | 1982 | static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff); |
1983 | static DEFINE_PER_CPU(struct hrtimer, rcu_idle_gp_timer); | 1983 | static DEFINE_PER_CPU(struct timer_list, rcu_idle_gp_timer); |
1984 | static ktime_t rcu_idle_gp_wait; /* If some non-lazy callbacks. */ | ||
1985 | static ktime_t rcu_idle_lazy_gp_wait; /* If only lazy callbacks. */ | ||
1986 | 1984 | ||
1987 | /* | 1985 | /* |
1988 | * Allow the CPU to enter dyntick-idle mode if either: (1) There are no | 1986 | * Allow the CPU to enter dyntick-idle mode if either: (1) There are no |
@@ -2051,10 +2049,9 @@ static bool rcu_cpu_has_nonlazy_callbacks(int cpu) | |||
2051 | * real work is done upon re-entry to idle, or by the next scheduling-clock | 2049 | * real work is done upon re-entry to idle, or by the next scheduling-clock |
2052 | * interrupt should idle not be re-entered. | 2050 | * interrupt should idle not be re-entered. |
2053 | */ | 2051 | */ |
2054 | static enum hrtimer_restart rcu_idle_gp_timer_func(struct hrtimer *hrtp) | 2052 | static void rcu_idle_gp_timer_func(unsigned long unused) |
2055 | { | 2053 | { |
2056 | trace_rcu_prep_idle("Timer"); | 2054 | trace_rcu_prep_idle("Timer"); |
2057 | return HRTIMER_NORESTART; | ||
2058 | } | 2055 | } |
2059 | 2056 | ||
2060 | /* | 2057 | /* |
@@ -2062,19 +2059,8 @@ static enum hrtimer_restart rcu_idle_gp_timer_func(struct hrtimer *hrtp) | |||
2062 | */ | 2059 | */ |
2063 | static void rcu_prepare_for_idle_init(int cpu) | 2060 | static void rcu_prepare_for_idle_init(int cpu) |
2064 | { | 2061 | { |
2065 | static int firsttime = 1; | 2062 | setup_timer(&per_cpu(rcu_idle_gp_timer, cpu), |
2066 | struct hrtimer *hrtp = &per_cpu(rcu_idle_gp_timer, cpu); | 2063 | rcu_idle_gp_timer_func, 0); |
2067 | |||
2068 | hrtimer_init(hrtp, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
2069 | hrtp->function = rcu_idle_gp_timer_func; | ||
2070 | if (firsttime) { | ||
2071 | unsigned int upj = jiffies_to_usecs(RCU_IDLE_GP_DELAY); | ||
2072 | |||
2073 | rcu_idle_gp_wait = ns_to_ktime(upj * (u64)1000); | ||
2074 | upj = jiffies_to_usecs(RCU_IDLE_LAZY_GP_DELAY); | ||
2075 | rcu_idle_lazy_gp_wait = ns_to_ktime(upj * (u64)1000); | ||
2076 | firsttime = 0; | ||
2077 | } | ||
2078 | } | 2064 | } |
2079 | 2065 | ||
2080 | /* | 2066 | /* |
@@ -2084,7 +2070,7 @@ static void rcu_prepare_for_idle_init(int cpu) | |||
2084 | */ | 2070 | */ |
2085 | static void rcu_cleanup_after_idle(int cpu) | 2071 | static void rcu_cleanup_after_idle(int cpu) |
2086 | { | 2072 | { |
2087 | hrtimer_cancel(&per_cpu(rcu_idle_gp_timer, cpu)); | 2073 | del_timer(&per_cpu(rcu_idle_gp_timer, cpu)); |
2088 | trace_rcu_prep_idle("Cleanup after idle"); | 2074 | trace_rcu_prep_idle("Cleanup after idle"); |
2089 | } | 2075 | } |
2090 | 2076 | ||
@@ -2141,11 +2127,11 @@ static void rcu_prepare_for_idle(int cpu) | |||
2141 | per_cpu(rcu_dyntick_drain, cpu) = 0; | 2127 | per_cpu(rcu_dyntick_drain, cpu) = 0; |
2142 | per_cpu(rcu_dyntick_holdoff, cpu) = jiffies; | 2128 | per_cpu(rcu_dyntick_holdoff, cpu) = jiffies; |
2143 | if (rcu_cpu_has_nonlazy_callbacks(cpu)) | 2129 | if (rcu_cpu_has_nonlazy_callbacks(cpu)) |
2144 | hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu), | 2130 | mod_timer(&per_cpu(rcu_idle_gp_timer, cpu), |
2145 | rcu_idle_gp_wait, HRTIMER_MODE_REL); | 2131 | jiffies + RCU_IDLE_GP_DELAY); |
2146 | else | 2132 | else |
2147 | hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu), | 2133 | mod_timer(&per_cpu(rcu_idle_gp_timer, cpu), |
2148 | rcu_idle_lazy_gp_wait, HRTIMER_MODE_REL); | 2134 | jiffies + RCU_IDLE_LAZY_GP_DELAY); |
2149 | return; /* Nothing more to do immediately. */ | 2135 | return; /* Nothing more to do immediately. */ |
2150 | } else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) { | 2136 | } else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) { |
2151 | /* We have hit the limit, so time to give up. */ | 2137 | /* We have hit the limit, so time to give up. */ |
@@ -2193,14 +2179,12 @@ static void rcu_prepare_for_idle(int cpu) | |||
2193 | 2179 | ||
2194 | static void print_cpu_stall_fast_no_hz(char *cp, int cpu) | 2180 | static void print_cpu_stall_fast_no_hz(char *cp, int cpu) |
2195 | { | 2181 | { |
2196 | struct hrtimer *hrtp = &per_cpu(rcu_idle_gp_timer, cpu); | 2182 | struct timer_list *tltp = &per_cpu(rcu_idle_gp_timer, cpu); |
2197 | 2183 | ||
2198 | sprintf(cp, "drain=%d %c timer=%lld", | 2184 | sprintf(cp, "drain=%d %c timer=%lu", |
2199 | per_cpu(rcu_dyntick_drain, cpu), | 2185 | per_cpu(rcu_dyntick_drain, cpu), |
2200 | per_cpu(rcu_dyntick_holdoff, cpu) == jiffies ? 'H' : '.', | 2186 | per_cpu(rcu_dyntick_holdoff, cpu) == jiffies ? 'H' : '.', |
2201 | hrtimer_active(hrtp) | 2187 | timer_pending(tltp) ? tltp->expires - jiffies : -1); |
2202 | ? ktime_to_us(hrtimer_get_remaining(hrtp)) | ||
2203 | : -1); | ||
2204 | } | 2188 | } |
2205 | 2189 | ||
2206 | #else /* #ifdef CONFIG_RCU_FAST_NO_HZ */ | 2190 | #else /* #ifdef CONFIG_RCU_FAST_NO_HZ */ |