| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Generic helpers for smp ipi calls |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 13 | 14 | #include <linux/export.h> |
|---|
| 14 | 15 | #include <linux/percpu.h> |
|---|
| 15 | 16 | #include <linux/init.h> |
|---|
| 17 | +#include <linux/interrupt.h> |
|---|
| 16 | 18 | #include <linux/gfp.h> |
|---|
| 17 | 19 | #include <linux/smp.h> |
|---|
| 18 | 20 | #include <linux/cpu.h> |
|---|
| 19 | 21 | #include <linux/sched.h> |
|---|
| 20 | 22 | #include <linux/sched/idle.h> |
|---|
| 21 | 23 | #include <linux/hypervisor.h> |
|---|
| 24 | +#include <linux/sched/clock.h> |
|---|
| 25 | +#include <linux/nmi.h> |
|---|
| 26 | +#include <linux/sched/debug.h> |
|---|
| 27 | +#include <linux/suspend.h> |
|---|
| 22 | 28 | |
|---|
| 23 | 29 | #include "smpboot.h" |
|---|
| 30 | +#include "sched/smp.h" |
|---|
| 24 | 31 | |
|---|
| 25 | | -enum { |
|---|
| 26 | | - CSD_FLAG_LOCK = 0x01, |
|---|
| 27 | | - CSD_FLAG_SYNCHRONOUS = 0x02, |
|---|
| 28 | | -}; |
|---|
| 32 | +#define CSD_TYPE(_csd) ((_csd)->flags & CSD_FLAG_TYPE_MASK) |
|---|
| 29 | 33 | |
|---|
| 30 | 34 | struct call_function_data { |
|---|
| 31 | 35 | call_single_data_t __percpu *csd; |
|---|
| .. | .. |
|---|
| 33 | 37 | cpumask_var_t cpumask_ipi; |
|---|
| 34 | 38 | }; |
|---|
| 35 | 39 | |
|---|
| 36 | | -static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data); |
|---|
| 40 | +static DEFINE_PER_CPU_ALIGNED(struct call_function_data, cfd_data); |
|---|
| 37 | 41 | |
|---|
| 38 | 42 | static DEFINE_PER_CPU_SHARED_ALIGNED(struct llist_head, call_single_queue); |
|---|
| 39 | 43 | |
|---|
| .. | .. |
|---|
| 83 | 87 | * still pending. |
|---|
| 84 | 88 | */ |
|---|
| 85 | 89 | flush_smp_call_function_queue(false); |
|---|
| 90 | + irq_work_run(); |
|---|
| 86 | 91 | return 0; |
|---|
| 87 | 92 | } |
|---|
| 88 | 93 | |
|---|
| .. | .. |
|---|
| 96 | 101 | smpcfd_prepare_cpu(smp_processor_id()); |
|---|
| 97 | 102 | } |
|---|
| 98 | 103 | |
|---|
| 104 | +#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG |
|---|
| 105 | + |
|---|
| 106 | +static DEFINE_PER_CPU(call_single_data_t *, cur_csd); |
|---|
| 107 | +static DEFINE_PER_CPU(smp_call_func_t, cur_csd_func); |
|---|
| 108 | +static DEFINE_PER_CPU(void *, cur_csd_info); |
|---|
| 109 | + |
|---|
| 110 | +#define CSD_LOCK_TIMEOUT (5ULL * NSEC_PER_SEC) |
|---|
| 111 | +static atomic_t csd_bug_count = ATOMIC_INIT(0); |
|---|
| 112 | + |
|---|
| 113 | +/* Record current CSD work for current CPU, NULL to erase. */ |
|---|
| 114 | +static void csd_lock_record(struct __call_single_data *csd) |
|---|
| 115 | +{ |
|---|
| 116 | + if (!csd) { |
|---|
| 117 | + smp_mb(); /* NULL cur_csd after unlock. */ |
|---|
| 118 | + __this_cpu_write(cur_csd, NULL); |
|---|
| 119 | + return; |
|---|
| 120 | + } |
|---|
| 121 | + __this_cpu_write(cur_csd_func, csd->func); |
|---|
| 122 | + __this_cpu_write(cur_csd_info, csd->info); |
|---|
| 123 | + smp_wmb(); /* func and info before csd. */ |
|---|
| 124 | + __this_cpu_write(cur_csd, csd); |
|---|
| 125 | + smp_mb(); /* Update cur_csd before function call. */ |
|---|
| 126 | + /* Or before unlock, as the case may be. */ |
|---|
| 127 | +} |
|---|
| 128 | + |
|---|
| 129 | +static __always_inline int csd_lock_wait_getcpu(struct __call_single_data *csd) |
|---|
| 130 | +{ |
|---|
| 131 | + unsigned int csd_type; |
|---|
| 132 | + |
|---|
| 133 | + csd_type = CSD_TYPE(csd); |
|---|
| 134 | + if (csd_type == CSD_TYPE_ASYNC || csd_type == CSD_TYPE_SYNC) |
|---|
| 135 | + return csd->dst; /* Other CSD_TYPE_ values might not have ->dst. */ |
|---|
| 136 | + return -1; |
|---|
| 137 | +} |
|---|
| 138 | + |
|---|
| 139 | +/* |
|---|
| 140 | + * Complain if too much time spent waiting. Note that only |
|---|
| 141 | + * the CSD_TYPE_SYNC/ASYNC types provide the destination CPU, |
|---|
| 142 | + * so waiting on other types gets much less information. |
|---|
| 143 | + */ |
|---|
| 144 | +static __always_inline bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 *ts1, int *bug_id) |
|---|
| 145 | +{ |
|---|
| 146 | + int cpu = -1; |
|---|
| 147 | + int cpux; |
|---|
| 148 | + bool firsttime; |
|---|
| 149 | + u64 ts2, ts_delta; |
|---|
| 150 | + call_single_data_t *cpu_cur_csd; |
|---|
| 151 | + unsigned int flags = READ_ONCE(csd->flags); |
|---|
| 152 | + |
|---|
| 153 | + if (!(flags & CSD_FLAG_LOCK)) { |
|---|
| 154 | + if (!unlikely(*bug_id)) |
|---|
| 155 | + return true; |
|---|
| 156 | + cpu = csd_lock_wait_getcpu(csd); |
|---|
| 157 | + pr_alert("csd: CSD lock (#%d) got unstuck on CPU#%02d, CPU#%02d released the lock.\n", |
|---|
| 158 | + *bug_id, raw_smp_processor_id(), cpu); |
|---|
| 159 | + return true; |
|---|
| 160 | + } |
|---|
| 161 | + |
|---|
| 162 | + ts2 = sched_clock(); |
|---|
| 163 | + ts_delta = ts2 - *ts1; |
|---|
| 164 | + if (likely(ts_delta <= CSD_LOCK_TIMEOUT)) |
|---|
| 165 | + return false; |
|---|
| 166 | + |
|---|
| 167 | + firsttime = !*bug_id; |
|---|
| 168 | + if (firsttime) |
|---|
| 169 | + *bug_id = atomic_inc_return(&csd_bug_count); |
|---|
| 170 | + cpu = csd_lock_wait_getcpu(csd); |
|---|
| 171 | + if (WARN_ONCE(cpu < 0 || cpu >= nr_cpu_ids, "%s: cpu = %d\n", __func__, cpu)) |
|---|
| 172 | + cpux = 0; |
|---|
| 173 | + else |
|---|
| 174 | + cpux = cpu; |
|---|
| 175 | + cpu_cur_csd = smp_load_acquire(&per_cpu(cur_csd, cpux)); /* Before func and info. */ |
|---|
| 176 | + pr_alert("csd: %s non-responsive CSD lock (#%d) on CPU#%d, waiting %llu ns for CPU#%02d %pS(%ps).\n", |
|---|
| 177 | + firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), ts2 - ts0, |
|---|
| 178 | + cpu, csd->func, csd->info); |
|---|
| 179 | + if (cpu_cur_csd && csd != cpu_cur_csd) { |
|---|
| 180 | + pr_alert("\tcsd: CSD lock (#%d) handling prior %pS(%ps) request.\n", |
|---|
| 181 | + *bug_id, READ_ONCE(per_cpu(cur_csd_func, cpux)), |
|---|
| 182 | + READ_ONCE(per_cpu(cur_csd_info, cpux))); |
|---|
| 183 | + } else { |
|---|
| 184 | + pr_alert("\tcsd: CSD lock (#%d) %s.\n", |
|---|
| 185 | + *bug_id, !cpu_cur_csd ? "unresponsive" : "handling this request"); |
|---|
| 186 | + } |
|---|
| 187 | + if (cpu >= 0) { |
|---|
| 188 | + if (!trigger_single_cpu_backtrace(cpu)) |
|---|
| 189 | + dump_cpu_task(cpu); |
|---|
| 190 | + if (!cpu_cur_csd) { |
|---|
| 191 | + pr_alert("csd: Re-sending CSD lock (#%d) IPI from CPU#%02d to CPU#%02d\n", *bug_id, raw_smp_processor_id(), cpu); |
|---|
| 192 | + arch_send_call_function_single_ipi(cpu); |
|---|
| 193 | + } |
|---|
| 194 | + } |
|---|
| 195 | + dump_stack(); |
|---|
| 196 | + *ts1 = ts2; |
|---|
| 197 | + |
|---|
| 198 | + return false; |
|---|
| 199 | +} |
|---|
| 200 | + |
|---|
| 99 | 201 | /* |
|---|
| 100 | 202 | * csd_lock/csd_unlock used to serialize access to per-cpu csd resources |
|---|
| 101 | 203 | * |
|---|
| .. | .. |
|---|
| 105 | 207 | */ |
|---|
| 106 | 208 | static __always_inline void csd_lock_wait(struct __call_single_data *csd) |
|---|
| 107 | 209 | { |
|---|
| 210 | + int bug_id = 0; |
|---|
| 211 | + u64 ts0, ts1; |
|---|
| 212 | + |
|---|
| 213 | + ts1 = ts0 = sched_clock(); |
|---|
| 214 | + for (;;) { |
|---|
| 215 | + if (csd_lock_wait_toolong(csd, ts0, &ts1, &bug_id)) |
|---|
| 216 | + break; |
|---|
| 217 | + cpu_relax(); |
|---|
| 218 | + } |
|---|
| 219 | + smp_acquire__after_ctrl_dep(); |
|---|
| 220 | +} |
|---|
| 221 | + |
|---|
| 222 | +#else |
|---|
| 223 | +static void csd_lock_record(struct __call_single_data *csd) |
|---|
| 224 | +{ |
|---|
| 225 | +} |
|---|
| 226 | + |
|---|
| 227 | +static __always_inline void csd_lock_wait(struct __call_single_data *csd) |
|---|
| 228 | +{ |
|---|
| 108 | 229 | smp_cond_load_acquire(&csd->flags, !(VAL & CSD_FLAG_LOCK)); |
|---|
| 109 | 230 | } |
|---|
| 231 | +#endif |
|---|
| 110 | 232 | |
|---|
| 111 | 233 | static __always_inline void csd_lock(struct __call_single_data *csd) |
|---|
| 112 | 234 | { |
|---|
| .. | .. |
|---|
| 133 | 255 | |
|---|
| 134 | 256 | static DEFINE_PER_CPU_SHARED_ALIGNED(call_single_data_t, csd_data); |
|---|
| 135 | 257 | |
|---|
| 136 | | -/* |
|---|
| 137 | | - * Insert a previously allocated call_single_data_t element |
|---|
| 138 | | - * for execution on the given CPU. data must already have |
|---|
| 139 | | - * ->func, ->info, and ->flags set. |
|---|
| 140 | | - */ |
|---|
| 141 | | -static int generic_exec_single(int cpu, struct __call_single_data *csd, |
|---|
| 142 | | - smp_call_func_t func, void *info) |
|---|
| 258 | +void __smp_call_single_queue(int cpu, struct llist_node *node) |
|---|
| 143 | 259 | { |
|---|
| 144 | | - if (cpu == smp_processor_id()) { |
|---|
| 145 | | - unsigned long flags; |
|---|
| 146 | | - |
|---|
| 147 | | - /* |
|---|
| 148 | | - * We can unlock early even for the synchronous on-stack case, |
|---|
| 149 | | - * since we're doing this from the same CPU.. |
|---|
| 150 | | - */ |
|---|
| 151 | | - csd_unlock(csd); |
|---|
| 152 | | - local_irq_save(flags); |
|---|
| 153 | | - func(info); |
|---|
| 154 | | - local_irq_restore(flags); |
|---|
| 155 | | - return 0; |
|---|
| 156 | | - } |
|---|
| 157 | | - |
|---|
| 158 | | - |
|---|
| 159 | | - if ((unsigned)cpu >= nr_cpu_ids || !cpu_online(cpu)) { |
|---|
| 160 | | - csd_unlock(csd); |
|---|
| 161 | | - return -ENXIO; |
|---|
| 162 | | - } |
|---|
| 163 | | - |
|---|
| 164 | | - csd->func = func; |
|---|
| 165 | | - csd->info = info; |
|---|
| 166 | | - |
|---|
| 167 | 260 | /* |
|---|
| 168 | 261 | * The list addition should be visible before sending the IPI |
|---|
| 169 | 262 | * handler locks the list to pull the entry off it because of |
|---|
| .. | .. |
|---|
| 175 | 268 | * locking and barrier primitives. Generic code isn't really |
|---|
| 176 | 269 | * equipped to do the right thing... |
|---|
| 177 | 270 | */ |
|---|
| 178 | | - if (llist_add(&csd->llist, &per_cpu(call_single_queue, cpu))) |
|---|
| 179 | | - arch_send_call_function_single_ipi(cpu); |
|---|
| 271 | + if (llist_add(node, &per_cpu(call_single_queue, cpu))) |
|---|
| 272 | + send_call_function_single_ipi(cpu); |
|---|
| 273 | +} |
|---|
| 274 | + |
|---|
| 275 | +/* |
|---|
| 276 | + * Insert a previously allocated call_single_data_t element |
|---|
| 277 | + * for execution on the given CPU. data must already have |
|---|
| 278 | + * ->func, ->info, and ->flags set. |
|---|
| 279 | + */ |
|---|
| 280 | +static int generic_exec_single(int cpu, struct __call_single_data *csd) |
|---|
| 281 | +{ |
|---|
| 282 | + if (cpu == smp_processor_id()) { |
|---|
| 283 | + smp_call_func_t func = csd->func; |
|---|
| 284 | + void *info = csd->info; |
|---|
| 285 | + unsigned long flags; |
|---|
| 286 | + |
|---|
| 287 | + /* |
|---|
| 288 | + * We can unlock early even for the synchronous on-stack case, |
|---|
| 289 | + * since we're doing this from the same CPU.. |
|---|
| 290 | + */ |
|---|
| 291 | + csd_lock_record(csd); |
|---|
| 292 | + csd_unlock(csd); |
|---|
| 293 | + local_irq_save(flags); |
|---|
| 294 | + func(info); |
|---|
| 295 | + csd_lock_record(NULL); |
|---|
| 296 | + local_irq_restore(flags); |
|---|
| 297 | + return 0; |
|---|
| 298 | + } |
|---|
| 299 | + |
|---|
| 300 | + if ((unsigned)cpu >= nr_cpu_ids || !cpu_online(cpu)) { |
|---|
| 301 | + csd_unlock(csd); |
|---|
| 302 | + return -ENXIO; |
|---|
| 303 | + } |
|---|
| 304 | + |
|---|
| 305 | + __smp_call_single_queue(cpu, &csd->llist); |
|---|
| 180 | 306 | |
|---|
| 181 | 307 | return 0; |
|---|
| 182 | 308 | } |
|---|
| .. | .. |
|---|
| 208 | 334 | */ |
|---|
| 209 | 335 | static void flush_smp_call_function_queue(bool warn_cpu_offline) |
|---|
| 210 | 336 | { |
|---|
| 211 | | - struct llist_head *head; |
|---|
| 212 | | - struct llist_node *entry; |
|---|
| 213 | 337 | call_single_data_t *csd, *csd_next; |
|---|
| 338 | + struct llist_node *entry, *prev; |
|---|
| 339 | + struct llist_head *head; |
|---|
| 214 | 340 | static bool warned; |
|---|
| 215 | 341 | |
|---|
| 216 | 342 | lockdep_assert_irqs_disabled(); |
|---|
| .. | .. |
|---|
| 221 | 347 | |
|---|
| 222 | 348 | /* There shouldn't be any pending callbacks on an offline CPU. */ |
|---|
| 223 | 349 | if (unlikely(warn_cpu_offline && !cpu_online(smp_processor_id()) && |
|---|
| 224 | | - !warned && !llist_empty(head))) { |
|---|
| 350 | + !warned && entry != NULL)) { |
|---|
| 225 | 351 | warned = true; |
|---|
| 226 | 352 | WARN(1, "IPI on offline CPU %d\n", smp_processor_id()); |
|---|
| 227 | 353 | |
|---|
| .. | .. |
|---|
| 229 | 355 | * We don't have to use the _safe() variant here |
|---|
| 230 | 356 | * because we are not invoking the IPI handlers yet. |
|---|
| 231 | 357 | */ |
|---|
| 232 | | - llist_for_each_entry(csd, entry, llist) |
|---|
| 233 | | - pr_warn("IPI callback %pS sent to offline CPU\n", |
|---|
| 234 | | - csd->func); |
|---|
| 235 | | - } |
|---|
| 358 | + llist_for_each_entry(csd, entry, llist) { |
|---|
| 359 | + switch (CSD_TYPE(csd)) { |
|---|
| 360 | + case CSD_TYPE_ASYNC: |
|---|
| 361 | + case CSD_TYPE_SYNC: |
|---|
| 362 | + case CSD_TYPE_IRQ_WORK: |
|---|
| 363 | + pr_warn("IPI callback %pS sent to offline CPU\n", |
|---|
| 364 | + csd->func); |
|---|
| 365 | + break; |
|---|
| 236 | 366 | |
|---|
| 237 | | - llist_for_each_entry_safe(csd, csd_next, entry, llist) { |
|---|
| 238 | | - smp_call_func_t func = csd->func; |
|---|
| 239 | | - void *info = csd->info; |
|---|
| 367 | + case CSD_TYPE_TTWU: |
|---|
| 368 | + pr_warn("IPI task-wakeup sent to offline CPU\n"); |
|---|
| 369 | + break; |
|---|
| 240 | 370 | |
|---|
| 241 | | - /* Do we wait until *after* callback? */ |
|---|
| 242 | | - if (csd->flags & CSD_FLAG_SYNCHRONOUS) { |
|---|
| 243 | | - func(info); |
|---|
| 244 | | - csd_unlock(csd); |
|---|
| 245 | | - } else { |
|---|
| 246 | | - csd_unlock(csd); |
|---|
| 247 | | - func(info); |
|---|
| 371 | + default: |
|---|
| 372 | + pr_warn("IPI callback, unknown type %d, sent to offline CPU\n", |
|---|
| 373 | + CSD_TYPE(csd)); |
|---|
| 374 | + break; |
|---|
| 375 | + } |
|---|
| 248 | 376 | } |
|---|
| 249 | 377 | } |
|---|
| 250 | 378 | |
|---|
| 251 | 379 | /* |
|---|
| 252 | | - * Handle irq works queued remotely by irq_work_queue_on(). |
|---|
| 253 | | - * Smp functions above are typically synchronous so they |
|---|
| 254 | | - * better run first since some other CPUs may be busy waiting |
|---|
| 255 | | - * for them. |
|---|
| 380 | + * First; run all SYNC callbacks, people are waiting for us. |
|---|
| 256 | 381 | */ |
|---|
| 257 | | - irq_work_run(); |
|---|
| 382 | + prev = NULL; |
|---|
| 383 | + llist_for_each_entry_safe(csd, csd_next, entry, llist) { |
|---|
| 384 | + /* Do we wait until *after* callback? */ |
|---|
| 385 | + if (CSD_TYPE(csd) == CSD_TYPE_SYNC) { |
|---|
| 386 | + smp_call_func_t func = csd->func; |
|---|
| 387 | + void *info = csd->info; |
|---|
| 388 | + |
|---|
| 389 | + if (prev) { |
|---|
| 390 | + prev->next = &csd_next->llist; |
|---|
| 391 | + } else { |
|---|
| 392 | + entry = &csd_next->llist; |
|---|
| 393 | + } |
|---|
| 394 | + |
|---|
| 395 | + csd_lock_record(csd); |
|---|
| 396 | + func(info); |
|---|
| 397 | + csd_unlock(csd); |
|---|
| 398 | + csd_lock_record(NULL); |
|---|
| 399 | + } else { |
|---|
| 400 | + prev = &csd->llist; |
|---|
| 401 | + } |
|---|
| 402 | + } |
|---|
| 403 | + |
|---|
| 404 | + if (!entry) |
|---|
| 405 | + return; |
|---|
| 406 | + |
|---|
| 407 | + /* |
|---|
| 408 | + * Second; run all !SYNC callbacks. |
|---|
| 409 | + */ |
|---|
| 410 | + prev = NULL; |
|---|
| 411 | + llist_for_each_entry_safe(csd, csd_next, entry, llist) { |
|---|
| 412 | + int type = CSD_TYPE(csd); |
|---|
| 413 | + |
|---|
| 414 | + if (type != CSD_TYPE_TTWU) { |
|---|
| 415 | + if (prev) { |
|---|
| 416 | + prev->next = &csd_next->llist; |
|---|
| 417 | + } else { |
|---|
| 418 | + entry = &csd_next->llist; |
|---|
| 419 | + } |
|---|
| 420 | + |
|---|
| 421 | + if (type == CSD_TYPE_ASYNC) { |
|---|
| 422 | + smp_call_func_t func = csd->func; |
|---|
| 423 | + void *info = csd->info; |
|---|
| 424 | + |
|---|
| 425 | + csd_lock_record(csd); |
|---|
| 426 | + csd_unlock(csd); |
|---|
| 427 | + func(info); |
|---|
| 428 | + csd_lock_record(NULL); |
|---|
| 429 | + } else if (type == CSD_TYPE_IRQ_WORK) { |
|---|
| 430 | + irq_work_single(csd); |
|---|
| 431 | + } |
|---|
| 432 | + |
|---|
| 433 | + } else { |
|---|
| 434 | + prev = &csd->llist; |
|---|
| 435 | + } |
|---|
| 436 | + } |
|---|
| 437 | + |
|---|
| 438 | + /* |
|---|
| 439 | + * Third; only CSD_TYPE_TTWU is left, issue those. |
|---|
| 440 | + */ |
|---|
| 441 | + if (entry) |
|---|
| 442 | + sched_ttwu_pending(entry); |
|---|
| 443 | +} |
|---|
| 444 | + |
|---|
| 445 | +void flush_smp_call_function_from_idle(void) |
|---|
| 446 | +{ |
|---|
| 447 | + unsigned long flags; |
|---|
| 448 | + |
|---|
| 449 | + if (llist_empty(this_cpu_ptr(&call_single_queue))) |
|---|
| 450 | + return; |
|---|
| 451 | + |
|---|
| 452 | + local_irq_save(flags); |
|---|
| 453 | + flush_smp_call_function_queue(true); |
|---|
| 454 | + if (local_softirq_pending()) |
|---|
| 455 | + do_softirq(); |
|---|
| 456 | + |
|---|
| 457 | + local_irq_restore(flags); |
|---|
| 258 | 458 | } |
|---|
| 259 | 459 | |
|---|
| 260 | 460 | /* |
|---|
| .. | .. |
|---|
| 270 | 470 | { |
|---|
| 271 | 471 | call_single_data_t *csd; |
|---|
| 272 | 472 | call_single_data_t csd_stack = { |
|---|
| 273 | | - .flags = CSD_FLAG_LOCK | CSD_FLAG_SYNCHRONOUS, |
|---|
| 473 | + .flags = CSD_FLAG_LOCK | CSD_TYPE_SYNC, |
|---|
| 274 | 474 | }; |
|---|
| 275 | 475 | int this_cpu; |
|---|
| 276 | 476 | int err; |
|---|
| .. | .. |
|---|
| 290 | 490 | WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() |
|---|
| 291 | 491 | && !oops_in_progress); |
|---|
| 292 | 492 | |
|---|
| 493 | + /* |
|---|
| 494 | + * When @wait we can deadlock when we interrupt between llist_add() and |
|---|
| 495 | + * arch_send_call_function_ipi*(); when !@wait we can deadlock due to |
|---|
| 496 | + * csd_lock() on because the interrupt context uses the same csd |
|---|
| 497 | + * storage. |
|---|
| 498 | + */ |
|---|
| 499 | + WARN_ON_ONCE(!in_task()); |
|---|
| 500 | + |
|---|
| 293 | 501 | csd = &csd_stack; |
|---|
| 294 | 502 | if (!wait) { |
|---|
| 295 | 503 | csd = this_cpu_ptr(&csd_data); |
|---|
| 296 | 504 | csd_lock(csd); |
|---|
| 297 | 505 | } |
|---|
| 298 | 506 | |
|---|
| 299 | | - err = generic_exec_single(cpu, csd, func, info); |
|---|
| 507 | + csd->func = func; |
|---|
| 508 | + csd->info = info; |
|---|
| 509 | +#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG |
|---|
| 510 | + csd->src = smp_processor_id(); |
|---|
| 511 | + csd->dst = cpu; |
|---|
| 512 | +#endif |
|---|
| 513 | + |
|---|
| 514 | + err = generic_exec_single(cpu, csd); |
|---|
| 300 | 515 | |
|---|
| 301 | 516 | if (wait) |
|---|
| 302 | 517 | csd_lock_wait(csd); |
|---|
| .. | .. |
|---|
| 320 | 535 | * (ie: embedded in an object) and is responsible for synchronizing it |
|---|
| 321 | 536 | * such that the IPIs performed on the @csd are strictly serialized. |
|---|
| 322 | 537 | * |
|---|
| 538 | + * If the function is called with one csd which has not yet been |
|---|
| 539 | + * processed by previous call to smp_call_function_single_async(), the |
|---|
| 540 | + * function will return immediately with -EBUSY showing that the csd |
|---|
| 541 | + * object is still in progress. |
|---|
| 542 | + * |
|---|
| 323 | 543 | * NOTE: Be careful, there is unfortunately no current debugging facility to |
|---|
| 324 | 544 | * validate the correctness of this serialization. |
|---|
| 325 | 545 | */ |
|---|
| .. | .. |
|---|
| 329 | 549 | |
|---|
| 330 | 550 | preempt_disable(); |
|---|
| 331 | 551 | |
|---|
| 332 | | - /* We could deadlock if we have to wait here with interrupts disabled! */ |
|---|
| 333 | | - if (WARN_ON_ONCE(csd->flags & CSD_FLAG_LOCK)) |
|---|
| 334 | | - csd_lock_wait(csd); |
|---|
| 552 | + if (csd->flags & CSD_FLAG_LOCK) { |
|---|
| 553 | + err = -EBUSY; |
|---|
| 554 | + goto out; |
|---|
| 555 | + } |
|---|
| 335 | 556 | |
|---|
| 336 | 557 | csd->flags = CSD_FLAG_LOCK; |
|---|
| 337 | 558 | smp_wmb(); |
|---|
| 338 | 559 | |
|---|
| 339 | | - err = generic_exec_single(cpu, csd, csd->func, csd->info); |
|---|
| 560 | + err = generic_exec_single(cpu, csd); |
|---|
| 561 | + |
|---|
| 562 | +out: |
|---|
| 340 | 563 | preempt_enable(); |
|---|
| 341 | 564 | |
|---|
| 342 | 565 | return err; |
|---|
| .. | .. |
|---|
| 386 | 609 | } |
|---|
| 387 | 610 | EXPORT_SYMBOL_GPL(smp_call_function_any); |
|---|
| 388 | 611 | |
|---|
| 389 | | -/** |
|---|
| 390 | | - * smp_call_function_many(): Run a function on a set of other CPUs. |
|---|
| 391 | | - * @mask: The set of cpus to run on (only runs on online subset). |
|---|
| 392 | | - * @func: The function to run. This must be fast and non-blocking. |
|---|
| 393 | | - * @info: An arbitrary pointer to pass to the function. |
|---|
| 394 | | - * @wait: If true, wait (atomically) until function has completed |
|---|
| 395 | | - * on other CPUs. |
|---|
| 396 | | - * |
|---|
| 397 | | - * If @wait is true, then returns once @func has returned. |
|---|
| 398 | | - * |
|---|
| 399 | | - * You must not call this function with disabled interrupts or from a |
|---|
| 400 | | - * hardware interrupt handler or from a bottom half handler. Preemption |
|---|
| 401 | | - * must be disabled when calling this function. |
|---|
| 402 | | - */ |
|---|
| 403 | | -void smp_call_function_many(const struct cpumask *mask, |
|---|
| 404 | | - smp_call_func_t func, void *info, bool wait) |
|---|
| 612 | +static void smp_call_function_many_cond(const struct cpumask *mask, |
|---|
| 613 | + smp_call_func_t func, void *info, |
|---|
| 614 | + bool wait, smp_cond_func_t cond_func) |
|---|
| 405 | 615 | { |
|---|
| 406 | 616 | struct call_function_data *cfd; |
|---|
| 407 | 617 | int cpu, next_cpu, this_cpu = smp_processor_id(); |
|---|
| .. | .. |
|---|
| 414 | 624 | */ |
|---|
| 415 | 625 | WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() |
|---|
| 416 | 626 | && !oops_in_progress && !early_boot_irqs_disabled); |
|---|
| 627 | + |
|---|
| 628 | + /* |
|---|
| 629 | + * When @wait we can deadlock when we interrupt between llist_add() and |
|---|
| 630 | + * arch_send_call_function_ipi*(); when !@wait we can deadlock due to |
|---|
| 631 | + * csd_lock() on because the interrupt context uses the same csd |
|---|
| 632 | + * storage. |
|---|
| 633 | + */ |
|---|
| 634 | + WARN_ON_ONCE(!in_task()); |
|---|
| 417 | 635 | |
|---|
| 418 | 636 | /* Try to fastpath. So, what's a CPU they want? Ignoring this one. */ |
|---|
| 419 | 637 | cpu = cpumask_first_and(mask, cpu_online_mask); |
|---|
| .. | .. |
|---|
| 431 | 649 | |
|---|
| 432 | 650 | /* Fastpath: do that cpu by itself. */ |
|---|
| 433 | 651 | if (next_cpu >= nr_cpu_ids) { |
|---|
| 434 | | - smp_call_function_single(cpu, func, info, wait); |
|---|
| 652 | + if (!cond_func || cond_func(cpu, info)) |
|---|
| 653 | + smp_call_function_single(cpu, func, info, wait); |
|---|
| 435 | 654 | return; |
|---|
| 436 | 655 | } |
|---|
| 437 | 656 | |
|---|
| .. | .. |
|---|
| 448 | 667 | for_each_cpu(cpu, cfd->cpumask) { |
|---|
| 449 | 668 | call_single_data_t *csd = per_cpu_ptr(cfd->csd, cpu); |
|---|
| 450 | 669 | |
|---|
| 670 | + if (cond_func && !cond_func(cpu, info)) |
|---|
| 671 | + continue; |
|---|
| 672 | + |
|---|
| 451 | 673 | csd_lock(csd); |
|---|
| 452 | 674 | if (wait) |
|---|
| 453 | | - csd->flags |= CSD_FLAG_SYNCHRONOUS; |
|---|
| 675 | + csd->flags |= CSD_TYPE_SYNC; |
|---|
| 454 | 676 | csd->func = func; |
|---|
| 455 | 677 | csd->info = info; |
|---|
| 678 | +#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG |
|---|
| 679 | + csd->src = smp_processor_id(); |
|---|
| 680 | + csd->dst = cpu; |
|---|
| 681 | +#endif |
|---|
| 456 | 682 | if (llist_add(&csd->llist, &per_cpu(call_single_queue, cpu))) |
|---|
| 457 | 683 | __cpumask_set_cpu(cpu, cfd->cpumask_ipi); |
|---|
| 458 | 684 | } |
|---|
| .. | .. |
|---|
| 468 | 694 | csd_lock_wait(csd); |
|---|
| 469 | 695 | } |
|---|
| 470 | 696 | } |
|---|
| 697 | +} |
|---|
| 698 | + |
|---|
| 699 | +/** |
|---|
| 700 | + * smp_call_function_many(): Run a function on a set of other CPUs. |
|---|
| 701 | + * @mask: The set of cpus to run on (only runs on online subset). |
|---|
| 702 | + * @func: The function to run. This must be fast and non-blocking. |
|---|
| 703 | + * @info: An arbitrary pointer to pass to the function. |
|---|
| 704 | + * @wait: If true, wait (atomically) until function has completed |
|---|
| 705 | + * on other CPUs. |
|---|
| 706 | + * |
|---|
| 707 | + * If @wait is true, then returns once @func has returned. |
|---|
| 708 | + * |
|---|
| 709 | + * You must not call this function with disabled interrupts or from a |
|---|
| 710 | + * hardware interrupt handler or from a bottom half handler. Preemption |
|---|
| 711 | + * must be disabled when calling this function. |
|---|
| 712 | + */ |
|---|
| 713 | +void smp_call_function_many(const struct cpumask *mask, |
|---|
| 714 | + smp_call_func_t func, void *info, bool wait) |
|---|
| 715 | +{ |
|---|
| 716 | + smp_call_function_many_cond(mask, func, info, wait, NULL); |
|---|
| 471 | 717 | } |
|---|
| 472 | 718 | EXPORT_SYMBOL(smp_call_function_many); |
|---|
| 473 | 719 | |
|---|
| .. | .. |
|---|
| 486 | 732 | * You must not call this function with disabled interrupts or from a |
|---|
| 487 | 733 | * hardware interrupt handler or from a bottom half handler. |
|---|
| 488 | 734 | */ |
|---|
| 489 | | -int smp_call_function(smp_call_func_t func, void *info, int wait) |
|---|
| 735 | +void smp_call_function(smp_call_func_t func, void *info, int wait) |
|---|
| 490 | 736 | { |
|---|
| 491 | 737 | preempt_disable(); |
|---|
| 492 | 738 | smp_call_function_many(cpu_online_mask, func, info, wait); |
|---|
| 493 | 739 | preempt_enable(); |
|---|
| 494 | | - |
|---|
| 495 | | - return 0; |
|---|
| 496 | 740 | } |
|---|
| 497 | 741 | EXPORT_SYMBOL(smp_call_function); |
|---|
| 498 | 742 | |
|---|
| .. | .. |
|---|
| 529 | 773 | { |
|---|
| 530 | 774 | int nr_cpus; |
|---|
| 531 | 775 | |
|---|
| 532 | | - get_option(&str, &nr_cpus); |
|---|
| 533 | | - if (nr_cpus > 0 && nr_cpus < nr_cpu_ids) |
|---|
| 776 | + if (get_option(&str, &nr_cpus) && nr_cpus > 0 && nr_cpus < nr_cpu_ids) |
|---|
| 534 | 777 | nr_cpu_ids = nr_cpus; |
|---|
| 535 | 778 | |
|---|
| 536 | 779 | return 0; |
|---|
| .. | .. |
|---|
| 563 | 806 | void __init smp_init(void) |
|---|
| 564 | 807 | { |
|---|
| 565 | 808 | int num_nodes, num_cpus; |
|---|
| 566 | | - unsigned int cpu; |
|---|
| 567 | 809 | |
|---|
| 568 | 810 | idle_threads_init(); |
|---|
| 569 | 811 | cpuhp_threads_init(); |
|---|
| 570 | 812 | |
|---|
| 571 | 813 | pr_info("Bringing up secondary CPUs ...\n"); |
|---|
| 572 | 814 | |
|---|
| 573 | | - /* FIXME: This should be done in userspace --RR */ |
|---|
| 574 | | - for_each_present_cpu(cpu) { |
|---|
| 575 | | - if (num_online_cpus() >= setup_max_cpus) |
|---|
| 576 | | - break; |
|---|
| 577 | | - if (!cpu_online(cpu)) |
|---|
| 578 | | - cpu_up(cpu); |
|---|
| 579 | | - } |
|---|
| 815 | + bringup_nonboot_cpus(setup_max_cpus); |
|---|
| 580 | 816 | |
|---|
| 581 | 817 | num_nodes = num_online_nodes(); |
|---|
| 582 | 818 | num_cpus = num_online_cpus(); |
|---|
| .. | .. |
|---|
| 593 | 829 | * early_boot_irqs_disabled is set. Use local_irq_save/restore() instead |
|---|
| 594 | 830 | * of local_irq_disable/enable(). |
|---|
| 595 | 831 | */ |
|---|
| 596 | | -int on_each_cpu(void (*func) (void *info), void *info, int wait) |
|---|
| 832 | +void on_each_cpu(smp_call_func_t func, void *info, int wait) |
|---|
| 597 | 833 | { |
|---|
| 598 | 834 | unsigned long flags; |
|---|
| 599 | | - int ret = 0; |
|---|
| 600 | 835 | |
|---|
| 601 | 836 | preempt_disable(); |
|---|
| 602 | | - ret = smp_call_function(func, info, wait); |
|---|
| 837 | + smp_call_function(func, info, wait); |
|---|
| 603 | 838 | local_irq_save(flags); |
|---|
| 604 | 839 | func(info); |
|---|
| 605 | 840 | local_irq_restore(flags); |
|---|
| 606 | 841 | preempt_enable(); |
|---|
| 607 | | - return ret; |
|---|
| 608 | 842 | } |
|---|
| 609 | 843 | EXPORT_SYMBOL(on_each_cpu); |
|---|
| 610 | 844 | |
|---|
| .. | .. |
|---|
| 646 | 880 | * for all the required CPUs to finish. This may include the local |
|---|
| 647 | 881 | * processor. |
|---|
| 648 | 882 | * @cond_func: A callback function that is passed a cpu id and |
|---|
| 649 | | - * the the info parameter. The function is called |
|---|
| 883 | + * the info parameter. The function is called |
|---|
| 650 | 884 | * with preemption disabled. The function should |
|---|
| 651 | 885 | * return a blooean value indicating whether to IPI |
|---|
| 652 | 886 | * the specified CPU. |
|---|
| .. | .. |
|---|
| 655 | 889 | * @info: An arbitrary pointer to pass to both functions. |
|---|
| 656 | 890 | * @wait: If true, wait (atomically) until function has |
|---|
| 657 | 891 | * completed on other CPUs. |
|---|
| 658 | | - * @gfp_flags: GFP flags to use when allocating the cpumask |
|---|
| 659 | | - * used internally by the function. |
|---|
| 660 | | - * |
|---|
| 661 | | - * The function might sleep if the GFP flags indicates a non |
|---|
| 662 | | - * atomic allocation is allowed. |
|---|
| 663 | 892 | * |
|---|
| 664 | 893 | * Preemption is disabled to protect against CPUs going offline but not online. |
|---|
| 665 | 894 | * CPUs going online during the call will not be seen or sent an IPI. |
|---|
| .. | .. |
|---|
| 667 | 896 | * You must not call this function with disabled interrupts or |
|---|
| 668 | 897 | * from a hardware interrupt handler or from a bottom half handler. |
|---|
| 669 | 898 | */ |
|---|
| 670 | | -void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), |
|---|
| 671 | | - smp_call_func_t func, void *info, bool wait, |
|---|
| 672 | | - gfp_t gfp_flags) |
|---|
| 899 | +void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func, |
|---|
| 900 | + void *info, bool wait, const struct cpumask *mask) |
|---|
| 673 | 901 | { |
|---|
| 674 | | - cpumask_var_t cpus; |
|---|
| 675 | | - int cpu, ret; |
|---|
| 902 | + int cpu = get_cpu(); |
|---|
| 676 | 903 | |
|---|
| 677 | | - might_sleep_if(gfpflags_allow_blocking(gfp_flags)); |
|---|
| 904 | + smp_call_function_many_cond(mask, func, info, wait, cond_func); |
|---|
| 905 | + if (cpumask_test_cpu(cpu, mask) && cond_func(cpu, info)) { |
|---|
| 906 | + unsigned long flags; |
|---|
| 678 | 907 | |
|---|
| 679 | | - if (likely(zalloc_cpumask_var(&cpus, (gfp_flags|__GFP_NOWARN)))) { |
|---|
| 680 | | - preempt_disable(); |
|---|
| 681 | | - for_each_online_cpu(cpu) |
|---|
| 682 | | - if (cond_func(cpu, info)) |
|---|
| 683 | | - cpumask_set_cpu(cpu, cpus); |
|---|
| 684 | | - on_each_cpu_mask(cpus, func, info, wait); |
|---|
| 685 | | - preempt_enable(); |
|---|
| 686 | | - free_cpumask_var(cpus); |
|---|
| 687 | | - } else { |
|---|
| 688 | | - /* |
|---|
| 689 | | - * No free cpumask, bother. No matter, we'll |
|---|
| 690 | | - * just have to IPI them one by one. |
|---|
| 691 | | - */ |
|---|
| 692 | | - preempt_disable(); |
|---|
| 693 | | - for_each_online_cpu(cpu) |
|---|
| 694 | | - if (cond_func(cpu, info)) { |
|---|
| 695 | | - ret = smp_call_function_single(cpu, func, |
|---|
| 696 | | - info, wait); |
|---|
| 697 | | - WARN_ON_ONCE(ret); |
|---|
| 698 | | - } |
|---|
| 699 | | - preempt_enable(); |
|---|
| 908 | + local_irq_save(flags); |
|---|
| 909 | + func(info); |
|---|
| 910 | + local_irq_restore(flags); |
|---|
| 700 | 911 | } |
|---|
| 912 | + put_cpu(); |
|---|
| 913 | +} |
|---|
| 914 | +EXPORT_SYMBOL(on_each_cpu_cond_mask); |
|---|
| 915 | + |
|---|
| 916 | +void on_each_cpu_cond(smp_cond_func_t cond_func, smp_call_func_t func, |
|---|
| 917 | + void *info, bool wait) |
|---|
| 918 | +{ |
|---|
| 919 | + on_each_cpu_cond_mask(cond_func, func, info, wait, cpu_online_mask); |
|---|
| 701 | 920 | } |
|---|
| 702 | 921 | EXPORT_SYMBOL(on_each_cpu_cond); |
|---|
| 703 | 922 | |
|---|
| .. | .. |
|---|
| 739 | 958 | if (cpu == smp_processor_id()) |
|---|
| 740 | 959 | continue; |
|---|
| 741 | 960 | |
|---|
| 742 | | - wake_up_if_idle(cpu); |
|---|
| 961 | +#if IS_ENABLED(CONFIG_SUSPEND) |
|---|
| 962 | + if (s2idle_state == S2IDLE_STATE_ENTER || cpu_active(cpu)) |
|---|
| 963 | +#endif |
|---|
| 964 | + wake_up_if_idle(cpu); |
|---|
| 743 | 965 | } |
|---|
| 744 | 966 | preempt_enable(); |
|---|
| 745 | 967 | } |
|---|
| 746 | 968 | EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus); |
|---|
| 747 | 969 | |
|---|
| 748 | 970 | /** |
|---|
| 971 | + * wake_up_all_online_idle_cpus - break all online cpus out of idle |
|---|
| 972 | + * wake_up_all_online_idle_cpus try to break all online cpus which is in idle |
|---|
| 973 | + * state even including idle polling cpus, for non-idle cpus, we will do nothing |
|---|
| 974 | + * for them. |
|---|
| 975 | + */ |
|---|
| 976 | +void wake_up_all_online_idle_cpus(void) |
|---|
| 977 | +{ |
|---|
| 978 | + int cpu; |
|---|
| 979 | + |
|---|
| 980 | + preempt_disable(); |
|---|
| 981 | + for_each_online_cpu(cpu) { |
|---|
| 982 | + if (cpu == smp_processor_id()) |
|---|
| 983 | + continue; |
|---|
| 984 | + |
|---|
| 985 | + wake_up_if_idle(cpu); |
|---|
| 986 | + } |
|---|
| 987 | + preempt_enable(); |
|---|
| 988 | +} |
|---|
| 989 | +EXPORT_SYMBOL_GPL(wake_up_all_online_idle_cpus); |
|---|
| 990 | + |
|---|
| 991 | +/** |
|---|
| 749 | 992 | * smp_call_on_cpu - Call a function on a specific cpu |
|---|
| 750 | 993 | * |
|---|
| 751 | 994 | * Used to call a function on a specific cpu and wait for it to return. |
|---|