diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
-rw-r--r-- | include/linux/rcupdate.h | 7 | ||||
-rw-r--r-- | include/linux/tick.h | 2 | ||||
-rw-r--r-- | init/main.c | 1 | ||||
-rw-r--r-- | kernel/rcutree.c | 6 | ||||
-rw-r--r-- | kernel/rcutree.h | 1 | ||||
-rw-r--r-- | kernel/rcutree_plugin.h | 13 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 22 |
8 files changed, 35 insertions, 19 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 887b29708447..4865e9bfd08d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1918,6 +1918,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1918 | the specified list of CPUs whose tick will be stopped | 1918 | the specified list of CPUs whose tick will be stopped |
1919 | whenever possible. The boot CPU will be forced outside | 1919 | whenever possible. The boot CPU will be forced outside |
1920 | the range to maintain the timekeeping. | 1920 | the range to maintain the timekeeping. |
1921 | The CPUs in this range must also be included in the | ||
1922 | rcu_nocbs= set. | ||
1921 | 1923 | ||
1922 | noiotrap [SH] Disables trapped I/O port accesses. | 1924 | noiotrap [SH] Disables trapped I/O port accesses. |
1923 | 1925 | ||
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index b758ce17b309..8e0948c872fc 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -999,4 +999,11 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
999 | #define kfree_rcu(ptr, rcu_head) \ | 999 | #define kfree_rcu(ptr, rcu_head) \ |
1000 | __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head)) | 1000 | __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head)) |
1001 | 1001 | ||
1002 | #ifdef CONFIG_RCU_NOCB_CPU | ||
1003 | extern bool rcu_is_nocb_cpu(int cpu); | ||
1004 | #else | ||
1005 | static inline bool rcu_is_nocb_cpu(int cpu) { return false; } | ||
1006 | #endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */ | ||
1007 | |||
1008 | |||
1002 | #endif /* __LINUX_RCUPDATE_H */ | 1009 | #endif /* __LINUX_RCUPDATE_H */ |
diff --git a/include/linux/tick.h b/include/linux/tick.h index b4e3b0c9639e..0b6873cbf512 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
@@ -158,8 +158,10 @@ static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; } | |||
158 | # endif /* !CONFIG_NO_HZ_COMMON */ | 158 | # endif /* !CONFIG_NO_HZ_COMMON */ |
159 | 159 | ||
160 | #ifdef CONFIG_NO_HZ_FULL | 160 | #ifdef CONFIG_NO_HZ_FULL |
161 | extern void tick_nohz_init(void); | ||
161 | extern int tick_nohz_full_cpu(int cpu); | 162 | extern int tick_nohz_full_cpu(int cpu); |
162 | #else | 163 | #else |
164 | static inline void tick_nohz_init(void) { } | ||
163 | static inline int tick_nohz_full_cpu(int cpu) { return 0; } | 165 | static inline int tick_nohz_full_cpu(int cpu) { return 0; } |
164 | #endif | 166 | #endif |
165 | 167 | ||
diff --git a/init/main.c b/init/main.c index 63534a141b4e..2acb5bbde99b 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -547,6 +547,7 @@ asmlinkage void __init start_kernel(void) | |||
547 | idr_init_cache(); | 547 | idr_init_cache(); |
548 | perf_event_init(); | 548 | perf_event_init(); |
549 | rcu_init(); | 549 | rcu_init(); |
550 | tick_nohz_init(); | ||
550 | radix_tree_init(); | 551 | radix_tree_init(); |
551 | /* init some links before init_ISA_irqs() */ | 552 | /* init some links before init_ISA_irqs() */ |
552 | early_irq_init(); | 553 | early_irq_init(); |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index f5ab50235cba..1d4ceff793a4 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -1695,7 +1695,7 @@ rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, | |||
1695 | struct rcu_node *rnp, struct rcu_data *rdp) | 1695 | struct rcu_node *rnp, struct rcu_data *rdp) |
1696 | { | 1696 | { |
1697 | /* No-CBs CPUs do not have orphanable callbacks. */ | 1697 | /* No-CBs CPUs do not have orphanable callbacks. */ |
1698 | if (is_nocb_cpu(rdp->cpu)) | 1698 | if (rcu_is_nocb_cpu(rdp->cpu)) |
1699 | return; | 1699 | return; |
1700 | 1700 | ||
1701 | /* | 1701 | /* |
@@ -2757,10 +2757,10 @@ static void _rcu_barrier(struct rcu_state *rsp) | |||
2757 | * corresponding CPU's preceding callbacks have been invoked. | 2757 | * corresponding CPU's preceding callbacks have been invoked. |
2758 | */ | 2758 | */ |
2759 | for_each_possible_cpu(cpu) { | 2759 | for_each_possible_cpu(cpu) { |
2760 | if (!cpu_online(cpu) && !is_nocb_cpu(cpu)) | 2760 | if (!cpu_online(cpu) && !rcu_is_nocb_cpu(cpu)) |
2761 | continue; | 2761 | continue; |
2762 | rdp = per_cpu_ptr(rsp->rda, cpu); | 2762 | rdp = per_cpu_ptr(rsp->rda, cpu); |
2763 | if (is_nocb_cpu(cpu)) { | 2763 | if (rcu_is_nocb_cpu(cpu)) { |
2764 | _rcu_barrier_trace(rsp, "OnlineNoCB", cpu, | 2764 | _rcu_barrier_trace(rsp, "OnlineNoCB", cpu, |
2765 | rsp->n_barrier_done); | 2765 | rsp->n_barrier_done); |
2766 | atomic_inc(&rsp->barrier_cpu_count); | 2766 | atomic_inc(&rsp->barrier_cpu_count); |
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index f993c0ac47db..38acc49da2c6 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -529,7 +529,6 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu); | |||
529 | static void print_cpu_stall_info_end(void); | 529 | static void print_cpu_stall_info_end(void); |
530 | static void zero_cpu_stall_ticks(struct rcu_data *rdp); | 530 | static void zero_cpu_stall_ticks(struct rcu_data *rdp); |
531 | static void increment_cpu_stall_ticks(void); | 531 | static void increment_cpu_stall_ticks(void); |
532 | static bool is_nocb_cpu(int cpu); | ||
533 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, | 532 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, |
534 | bool lazy); | 533 | bool lazy); |
535 | static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, | 534 | static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index a5745e9b5d5a..0cd91cc18db4 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -2167,7 +2167,7 @@ static int __init parse_rcu_nocb_poll(char *arg) | |||
2167 | early_param("rcu_nocb_poll", parse_rcu_nocb_poll); | 2167 | early_param("rcu_nocb_poll", parse_rcu_nocb_poll); |
2168 | 2168 | ||
2169 | /* Is the specified CPU a no-CPUs CPU? */ | 2169 | /* Is the specified CPU a no-CPUs CPU? */ |
2170 | static bool is_nocb_cpu(int cpu) | 2170 | bool rcu_is_nocb_cpu(int cpu) |
2171 | { | 2171 | { |
2172 | if (have_rcu_nocb_mask) | 2172 | if (have_rcu_nocb_mask) |
2173 | return cpumask_test_cpu(cpu, rcu_nocb_mask); | 2173 | return cpumask_test_cpu(cpu, rcu_nocb_mask); |
@@ -2225,7 +2225,7 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, | |||
2225 | bool lazy) | 2225 | bool lazy) |
2226 | { | 2226 | { |
2227 | 2227 | ||
2228 | if (!is_nocb_cpu(rdp->cpu)) | 2228 | if (!rcu_is_nocb_cpu(rdp->cpu)) |
2229 | return 0; | 2229 | return 0; |
2230 | __call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy); | 2230 | __call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy); |
2231 | return 1; | 2231 | return 1; |
@@ -2242,7 +2242,7 @@ static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, | |||
2242 | long qll = rsp->qlen_lazy; | 2242 | long qll = rsp->qlen_lazy; |
2243 | 2243 | ||
2244 | /* If this is not a no-CBs CPU, tell the caller to do it the old way. */ | 2244 | /* If this is not a no-CBs CPU, tell the caller to do it the old way. */ |
2245 | if (!is_nocb_cpu(smp_processor_id())) | 2245 | if (!rcu_is_nocb_cpu(smp_processor_id())) |
2246 | return 0; | 2246 | return 0; |
2247 | rsp->qlen = 0; | 2247 | rsp->qlen = 0; |
2248 | rsp->qlen_lazy = 0; | 2248 | rsp->qlen_lazy = 0; |
@@ -2282,7 +2282,7 @@ static bool nocb_cpu_expendable(int cpu) | |||
2282 | * If there are no no-CB CPUs or if this CPU is not a no-CB CPU, | 2282 | * If there are no no-CB CPUs or if this CPU is not a no-CB CPU, |
2283 | * then offlining this CPU is harmless. Let it happen. | 2283 | * then offlining this CPU is harmless. Let it happen. |
2284 | */ | 2284 | */ |
2285 | if (!have_rcu_nocb_mask || is_nocb_cpu(cpu)) | 2285 | if (!have_rcu_nocb_mask || rcu_is_nocb_cpu(cpu)) |
2286 | return 1; | 2286 | return 1; |
2287 | 2287 | ||
2288 | /* If no memory, play it safe and keep the CPU around. */ | 2288 | /* If no memory, play it safe and keep the CPU around. */ |
@@ -2464,11 +2464,6 @@ static void __init rcu_init_nocb(void) | |||
2464 | 2464 | ||
2465 | #else /* #ifdef CONFIG_RCU_NOCB_CPU */ | 2465 | #else /* #ifdef CONFIG_RCU_NOCB_CPU */ |
2466 | 2466 | ||
2467 | static bool is_nocb_cpu(int cpu) | ||
2468 | { | ||
2469 | return false; | ||
2470 | } | ||
2471 | |||
2472 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, | 2467 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, |
2473 | bool lazy) | 2468 | bool lazy) |
2474 | { | 2469 | { |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 2bac5ea2c9af..d71a5f2bd7b2 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -203,17 +203,27 @@ static int __cpuinit tick_nohz_cpu_down_callback(struct notifier_block *nfb, | |||
203 | */ | 203 | */ |
204 | static char __initdata nohz_full_buf[NR_CPUS + 1]; | 204 | static char __initdata nohz_full_buf[NR_CPUS + 1]; |
205 | 205 | ||
206 | static int __init init_tick_nohz_full(void) | 206 | void __init tick_nohz_init(void) |
207 | { | 207 | { |
208 | if (have_nohz_full_mask) | 208 | int cpu; |
209 | cpu_notifier(tick_nohz_cpu_down_callback, 0); | 209 | |
210 | if (!have_nohz_full_mask) | ||
211 | return; | ||
212 | |||
213 | cpu_notifier(tick_nohz_cpu_down_callback, 0); | ||
214 | |||
215 | /* Make sure full dynticks CPU are also RCU nocbs */ | ||
216 | for_each_cpu(cpu, nohz_full_mask) { | ||
217 | if (!rcu_is_nocb_cpu(cpu)) { | ||
218 | pr_warning("NO_HZ: CPU %d is not RCU nocb: " | ||
219 | "cleared from nohz_full range", cpu); | ||
220 | cpumask_clear_cpu(cpu, nohz_full_mask); | ||
221 | } | ||
222 | } | ||
210 | 223 | ||
211 | cpulist_scnprintf(nohz_full_buf, sizeof(nohz_full_buf), nohz_full_mask); | 224 | cpulist_scnprintf(nohz_full_buf, sizeof(nohz_full_buf), nohz_full_mask); |
212 | pr_info("NO_HZ: Full dynticks CPUs: %s.\n", nohz_full_buf); | 225 | pr_info("NO_HZ: Full dynticks CPUs: %s.\n", nohz_full_buf); |
213 | |||
214 | return 0; | ||
215 | } | 226 | } |
216 | core_initcall(init_tick_nohz_full); | ||
217 | #else | 227 | #else |
218 | #define have_nohz_full_mask (0) | 228 | #define have_nohz_full_mask (0) |
219 | #endif | 229 | #endif |