diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2007-05-09 05:34:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 15:30:51 -0400 |
commit | e7407dcc69e077ac34a527842db916abfbc458df (patch) | |
tree | 138b24bceee828dc256bb81f2b592926be9f1515 /kernel/cpu.c | |
parent | 5be9361cdff17fc76fa0c3e262ead94158555f16 (diff) |
call cpu_chain with CPU_DOWN_FAILED if CPU_DOWN_PREPARE failed
This makes cpu hotplug symmetrical: if CPU_UP_PREPARE fails we get
CPU_UP_CANCELED, so we can undo what ever happened on PREPARE. The same
should happen for CPU_DOWN_PREPARE.
[akpm@linux-foundation.org: fix for reduce-size-of-task_struct-on-64-bit-machines]
Cc: Srivatsa Vaddagiri <vatsa@in.ibm.com>
Cc: Gautham Shenoy <ego@in.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r-- | kernel/cpu.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 48810498b355..1a823944e972 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -97,7 +97,7 @@ static inline void check_for_tasks(int cpu) | |||
97 | (!cputime_eq(p->utime, cputime_zero) || | 97 | (!cputime_eq(p->utime, cputime_zero) || |
98 | !cputime_eq(p->stime, cputime_zero))) | 98 | !cputime_eq(p->stime, cputime_zero))) |
99 | printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\ | 99 | printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\ |
100 | (state = %ld, flags = %lx) \n", | 100 | (state = %ld, flags = %x) \n", |
101 | p->comm, p->pid, cpu, p->state, p->flags); | 101 | p->comm, p->pid, cpu, p->state, p->flags); |
102 | } | 102 | } |
103 | write_unlock_irq(&tasklist_lock); | 103 | write_unlock_irq(&tasklist_lock); |
@@ -122,9 +122,10 @@ static int take_cpu_down(void *unused) | |||
122 | /* Requires cpu_add_remove_lock to be held */ | 122 | /* Requires cpu_add_remove_lock to be held */ |
123 | static int _cpu_down(unsigned int cpu) | 123 | static int _cpu_down(unsigned int cpu) |
124 | { | 124 | { |
125 | int err; | 125 | int err, nr_calls = 0; |
126 | struct task_struct *p; | 126 | struct task_struct *p; |
127 | cpumask_t old_allowed, tmp; | 127 | cpumask_t old_allowed, tmp; |
128 | void *hcpu = (void *)(long)cpu; | ||
128 | 129 | ||
129 | if (num_online_cpus() == 1) | 130 | if (num_online_cpus() == 1) |
130 | return -EBUSY; | 131 | return -EBUSY; |
@@ -132,11 +133,12 @@ static int _cpu_down(unsigned int cpu) | |||
132 | if (!cpu_online(cpu)) | 133 | if (!cpu_online(cpu)) |
133 | return -EINVAL; | 134 | return -EINVAL; |
134 | 135 | ||
135 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, | 136 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); |
136 | (void *)(long)cpu); | 137 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, |
137 | err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, | 138 | hcpu, -1, &nr_calls); |
138 | (void *)(long)cpu); | ||
139 | if (err == NOTIFY_BAD) { | 139 | if (err == NOTIFY_BAD) { |
140 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, hcpu, | ||
141 | nr_calls, NULL); | ||
140 | printk("%s: attempt to take down CPU %u failed\n", | 142 | printk("%s: attempt to take down CPU %u failed\n", |
141 | __FUNCTION__, cpu); | 143 | __FUNCTION__, cpu); |
142 | err = -EINVAL; | 144 | err = -EINVAL; |
@@ -156,7 +158,7 @@ static int _cpu_down(unsigned int cpu) | |||
156 | if (IS_ERR(p) || cpu_online(cpu)) { | 158 | if (IS_ERR(p) || cpu_online(cpu)) { |
157 | /* CPU didn't die: tell everyone. Can't complain. */ | 159 | /* CPU didn't die: tell everyone. Can't complain. */ |
158 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, | 160 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, |
159 | (void *)(long)cpu) == NOTIFY_BAD) | 161 | hcpu) == NOTIFY_BAD) |
160 | BUG(); | 162 | BUG(); |
161 | 163 | ||
162 | if (IS_ERR(p)) { | 164 | if (IS_ERR(p)) { |
@@ -178,8 +180,7 @@ static int _cpu_down(unsigned int cpu) | |||
178 | put_cpu(); | 180 | put_cpu(); |
179 | 181 | ||
180 | /* CPU is completely dead: tell everyone. Too late to complain. */ | 182 | /* CPU is completely dead: tell everyone. Too late to complain. */ |
181 | if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD, | 183 | if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu) == NOTIFY_BAD) |
182 | (void *)(long)cpu) == NOTIFY_BAD) | ||
183 | BUG(); | 184 | BUG(); |
184 | 185 | ||
185 | check_for_tasks(cpu); | 186 | check_for_tasks(cpu); |