diff options
-rw-r--r-- | kernel/smp.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/kernel/smp.c b/kernel/smp.c index 06d574e42c72..306f8180b0d5 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
@@ -185,14 +185,26 @@ void generic_smp_call_function_single_interrupt(void) | |||
185 | { | 185 | { |
186 | struct llist_node *entry; | 186 | struct llist_node *entry; |
187 | struct call_single_data *csd, *csd_next; | 187 | struct call_single_data *csd, *csd_next; |
188 | static bool warned; | ||
189 | |||
190 | entry = llist_del_all(&__get_cpu_var(call_single_queue)); | ||
191 | entry = llist_reverse_order(entry); | ||
188 | 192 | ||
189 | /* | 193 | /* |
190 | * Shouldn't receive this interrupt on a cpu that is not yet online. | 194 | * Shouldn't receive this interrupt on a cpu that is not yet online. |
191 | */ | 195 | */ |
192 | WARN_ON_ONCE(!cpu_online(smp_processor_id())); | 196 | if (unlikely(!cpu_online(smp_processor_id()) && !warned)) { |
197 | warned = true; | ||
198 | WARN(1, "IPI on offline CPU %d\n", smp_processor_id()); | ||
193 | 199 | ||
194 | entry = llist_del_all(&__get_cpu_var(call_single_queue)); | 200 | /* |
195 | entry = llist_reverse_order(entry); | 201 | * We don't have to use the _safe() variant here |
202 | * because we are not invoking the IPI handlers yet. | ||
203 | */ | ||
204 | llist_for_each_entry(csd, entry, llist) | ||
205 | pr_warn("IPI callback %pS sent to offline CPU\n", | ||
206 | csd->func); | ||
207 | } | ||
196 | 208 | ||
197 | llist_for_each_entry_safe(csd, csd_next, entry, llist) { | 209 | llist_for_each_entry_safe(csd, csd_next, entry, llist) { |
198 | csd->func(csd->info); | 210 | csd->func(csd->info); |