diff options
| -rw-r--r-- | include/linux/notifier.h | 3 | ||||
| -rw-r--r-- | kernel/cpu.c | 16 |
2 files changed, 17 insertions, 2 deletions
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 9431101bf876..576f2bb34cc8 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
| @@ -196,6 +196,8 @@ extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, | |||
| 196 | #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ | 196 | #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ |
| 197 | #define CPU_LOCK_ACQUIRE 0x0008 /* Acquire all hotcpu locks */ | 197 | #define CPU_LOCK_ACQUIRE 0x0008 /* Acquire all hotcpu locks */ |
| 198 | #define CPU_LOCK_RELEASE 0x0009 /* Release all hotcpu locks */ | 198 | #define CPU_LOCK_RELEASE 0x0009 /* Release all hotcpu locks */ |
| 199 | #define CPU_DYING 0x000A /* CPU (unsigned)v not running any task, | ||
| 200 | * not handling interrupts, soon dead */ | ||
| 199 | 201 | ||
| 200 | /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend | 202 | /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend |
| 201 | * operation in progress | 203 | * operation in progress |
| @@ -208,6 +210,7 @@ extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, | |||
| 208 | #define CPU_DOWN_PREPARE_FROZEN (CPU_DOWN_PREPARE | CPU_TASKS_FROZEN) | 210 | #define CPU_DOWN_PREPARE_FROZEN (CPU_DOWN_PREPARE | CPU_TASKS_FROZEN) |
| 209 | #define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN) | 211 | #define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN) |
| 210 | #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) | 212 | #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) |
| 213 | #define CPU_DYING_FROZEN (CPU_DYING | CPU_TASKS_FROZEN) | ||
| 211 | 214 | ||
| 212 | #endif /* __KERNEL__ */ | 215 | #endif /* __KERNEL__ */ |
| 213 | #endif /* _LINUX_NOTIFIER_H */ | 216 | #endif /* _LINUX_NOTIFIER_H */ |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 208cf3497c10..181ae7086029 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -103,11 +103,19 @@ static inline void check_for_tasks(int cpu) | |||
| 103 | write_unlock_irq(&tasklist_lock); | 103 | write_unlock_irq(&tasklist_lock); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | struct take_cpu_down_param { | ||
| 107 | unsigned long mod; | ||
| 108 | void *hcpu; | ||
| 109 | }; | ||
| 110 | |||
| 106 | /* Take this CPU down. */ | 111 | /* Take this CPU down. */ |
| 107 | static int take_cpu_down(void *unused) | 112 | static int take_cpu_down(void *_param) |
| 108 | { | 113 | { |
| 114 | struct take_cpu_down_param *param = _param; | ||
| 109 | int err; | 115 | int err; |
| 110 | 116 | ||
| 117 | raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod, | ||
| 118 | param->hcpu); | ||
| 111 | /* Ensure this CPU doesn't handle any more interrupts. */ | 119 | /* Ensure this CPU doesn't handle any more interrupts. */ |
| 112 | err = __cpu_disable(); | 120 | err = __cpu_disable(); |
| 113 | if (err < 0) | 121 | if (err < 0) |
| @@ -127,6 +135,10 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 127 | cpumask_t old_allowed, tmp; | 135 | cpumask_t old_allowed, tmp; |
| 128 | void *hcpu = (void *)(long)cpu; | 136 | void *hcpu = (void *)(long)cpu; |
| 129 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; | 137 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; |
| 138 | struct take_cpu_down_param tcd_param = { | ||
| 139 | .mod = mod, | ||
| 140 | .hcpu = hcpu, | ||
| 141 | }; | ||
| 130 | 142 | ||
| 131 | if (num_online_cpus() == 1) | 143 | if (num_online_cpus() == 1) |
| 132 | return -EBUSY; | 144 | return -EBUSY; |
| @@ -153,7 +165,7 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 153 | set_cpus_allowed(current, tmp); | 165 | set_cpus_allowed(current, tmp); |
| 154 | 166 | ||
| 155 | mutex_lock(&cpu_bitmask_lock); | 167 | mutex_lock(&cpu_bitmask_lock); |
| 156 | p = __stop_machine_run(take_cpu_down, NULL, cpu); | 168 | p = __stop_machine_run(take_cpu_down, &tcd_param, cpu); |
| 157 | mutex_unlock(&cpu_bitmask_lock); | 169 | mutex_unlock(&cpu_bitmask_lock); |
| 158 | 170 | ||
| 159 | if (IS_ERR(p) || cpu_online(cpu)) { | 171 | if (IS_ERR(p) || cpu_online(cpu)) { |
