diff options
| -rw-r--r-- | kernel/cpu.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 90a3d017b90c..5d220234b3ca 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -86,6 +86,16 @@ static struct { | |||
| 86 | #define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map) | 86 | #define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map) |
| 87 | #define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map) | 87 | #define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map) |
| 88 | 88 | ||
| 89 | static void apply_puts_pending(int max) | ||
| 90 | { | ||
| 91 | int delta; | ||
| 92 | |||
| 93 | if (atomic_read(&cpu_hotplug.puts_pending) >= max) { | ||
| 94 | delta = atomic_xchg(&cpu_hotplug.puts_pending, 0); | ||
| 95 | cpu_hotplug.refcount -= delta; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 89 | void get_online_cpus(void) | 99 | void get_online_cpus(void) |
| 90 | { | 100 | { |
| 91 | might_sleep(); | 101 | might_sleep(); |
| @@ -93,6 +103,7 @@ void get_online_cpus(void) | |||
| 93 | return; | 103 | return; |
| 94 | cpuhp_lock_acquire_read(); | 104 | cpuhp_lock_acquire_read(); |
| 95 | mutex_lock(&cpu_hotplug.lock); | 105 | mutex_lock(&cpu_hotplug.lock); |
| 106 | apply_puts_pending(65536); | ||
| 96 | cpu_hotplug.refcount++; | 107 | cpu_hotplug.refcount++; |
| 97 | mutex_unlock(&cpu_hotplug.lock); | 108 | mutex_unlock(&cpu_hotplug.lock); |
| 98 | } | 109 | } |
| @@ -105,6 +116,7 @@ bool try_get_online_cpus(void) | |||
| 105 | if (!mutex_trylock(&cpu_hotplug.lock)) | 116 | if (!mutex_trylock(&cpu_hotplug.lock)) |
| 106 | return false; | 117 | return false; |
| 107 | cpuhp_lock_acquire_tryread(); | 118 | cpuhp_lock_acquire_tryread(); |
| 119 | apply_puts_pending(65536); | ||
| 108 | cpu_hotplug.refcount++; | 120 | cpu_hotplug.refcount++; |
| 109 | mutex_unlock(&cpu_hotplug.lock); | 121 | mutex_unlock(&cpu_hotplug.lock); |
| 110 | return true; | 122 | return true; |
| @@ -161,12 +173,7 @@ void cpu_hotplug_begin(void) | |||
| 161 | cpuhp_lock_acquire(); | 173 | cpuhp_lock_acquire(); |
| 162 | for (;;) { | 174 | for (;;) { |
| 163 | mutex_lock(&cpu_hotplug.lock); | 175 | mutex_lock(&cpu_hotplug.lock); |
| 164 | if (atomic_read(&cpu_hotplug.puts_pending)) { | 176 | apply_puts_pending(1); |
| 165 | int delta; | ||
| 166 | |||
| 167 | delta = atomic_xchg(&cpu_hotplug.puts_pending, 0); | ||
| 168 | cpu_hotplug.refcount -= delta; | ||
| 169 | } | ||
| 170 | if (likely(!cpu_hotplug.refcount)) | 177 | if (likely(!cpu_hotplug.refcount)) |
| 171 | break; | 178 | break; |
| 172 | __set_current_state(TASK_UNINTERRUPTIBLE); | 179 | __set_current_state(TASK_UNINTERRUPTIBLE); |
