diff options
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r-- | kernel/cpu.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 0097acec1c71..be4859f07153 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -315,6 +315,16 @@ void lockdep_assert_cpus_held(void) | |||
315 | percpu_rwsem_assert_held(&cpu_hotplug_lock); | 315 | percpu_rwsem_assert_held(&cpu_hotplug_lock); |
316 | } | 316 | } |
317 | 317 | ||
318 | static void lockdep_acquire_cpus_lock(void) | ||
319 | { | ||
320 | rwsem_acquire(&cpu_hotplug_lock.rw_sem.dep_map, 0, 0, _THIS_IP_); | ||
321 | } | ||
322 | |||
323 | static void lockdep_release_cpus_lock(void) | ||
324 | { | ||
325 | rwsem_release(&cpu_hotplug_lock.rw_sem.dep_map, 1, _THIS_IP_); | ||
326 | } | ||
327 | |||
318 | /* | 328 | /* |
319 | * Wait for currently running CPU hotplug operations to complete (if any) and | 329 | * Wait for currently running CPU hotplug operations to complete (if any) and |
320 | * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects | 330 | * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects |
@@ -344,6 +354,17 @@ void cpu_hotplug_enable(void) | |||
344 | cpu_maps_update_done(); | 354 | cpu_maps_update_done(); |
345 | } | 355 | } |
346 | EXPORT_SYMBOL_GPL(cpu_hotplug_enable); | 356 | EXPORT_SYMBOL_GPL(cpu_hotplug_enable); |
357 | |||
358 | #else | ||
359 | |||
360 | static void lockdep_acquire_cpus_lock(void) | ||
361 | { | ||
362 | } | ||
363 | |||
364 | static void lockdep_release_cpus_lock(void) | ||
365 | { | ||
366 | } | ||
367 | |||
347 | #endif /* CONFIG_HOTPLUG_CPU */ | 368 | #endif /* CONFIG_HOTPLUG_CPU */ |
348 | 369 | ||
349 | #ifdef CONFIG_HOTPLUG_SMT | 370 | #ifdef CONFIG_HOTPLUG_SMT |
@@ -616,6 +637,12 @@ static void cpuhp_thread_fun(unsigned int cpu) | |||
616 | */ | 637 | */ |
617 | smp_mb(); | 638 | smp_mb(); |
618 | 639 | ||
640 | /* | ||
641 | * The BP holds the hotplug lock, but we're now running on the AP, | ||
642 | * ensure that anybody asserting the lock is held, will actually find | ||
643 | * it so. | ||
644 | */ | ||
645 | lockdep_acquire_cpus_lock(); | ||
619 | cpuhp_lock_acquire(bringup); | 646 | cpuhp_lock_acquire(bringup); |
620 | 647 | ||
621 | if (st->single) { | 648 | if (st->single) { |
@@ -661,6 +688,7 @@ static void cpuhp_thread_fun(unsigned int cpu) | |||
661 | } | 688 | } |
662 | 689 | ||
663 | cpuhp_lock_release(bringup); | 690 | cpuhp_lock_release(bringup); |
691 | lockdep_release_cpus_lock(); | ||
664 | 692 | ||
665 | if (!st->should_run) | 693 | if (!st->should_run) |
666 | complete_ap_thread(st, bringup); | 694 | complete_ap_thread(st, bringup); |