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)) { |