@@ -71,11 +71,21 @@ void __init register_cpu_notifier(struct notifier_block *nb)
spin_unlock(&cpu_add_remove_lock);
}
+static int cpu_notifier_call_chain(unsigned int cpu, unsigned long action,
+ struct notifier_block **nb, bool nofail)
+{
+ void *hcpu = (void *)(long)cpu;
+ int notifier_rc = notifier_call_chain(&cpu_chain, action, hcpu, nb);
+ int ret = (notifier_rc == NOTIFY_DONE) ? 0 : notifier_to_errno(notifier_rc);
+
+ BUG_ON(ret && nofail);
+
+ return ret;
+}
+
static void _take_cpu_down(void *unused)
{
- void *hcpu = (void *)(long)smp_processor_id();
- int notifier_rc = notifier_call_chain(&cpu_chain, CPU_DYING, hcpu, NULL);
- BUG_ON(notifier_rc != NOTIFY_DONE);
+ cpu_notifier_call_chain(smp_processor_id(), CPU_DYING, NULL, true);
__cpu_disable();
}
@@ -87,8 +97,7 @@ static int take_cpu_down(void *arg)
int cpu_down(unsigned int cpu)
{
- int err, notifier_rc;
- void *hcpu = (void *)(long)cpu;
+ int err;
struct notifier_block *nb = NULL;
if ( !cpu_hotplug_begin() )
@@ -100,12 +109,9 @@ int cpu_down(unsigned int cpu)
return -EINVAL;
}
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, hcpu, &nb);
- if ( notifier_rc != NOTIFY_DONE )
- {
- err = notifier_to_errno(notifier_rc);
+ err = cpu_notifier_call_chain(cpu, CPU_DOWN_PREPARE, &nb, false);
+ if ( err )
goto fail;
- }
if ( unlikely(system_state < SYS_STATE_active) )
on_selected_cpus(cpumask_of(cpu), _take_cpu_down, NULL, true);
@@ -113,26 +119,24 @@ int cpu_down(unsigned int cpu)
goto fail;
__cpu_die(cpu);
- BUG_ON(cpu_online(cpu));
+ err = cpu_online(cpu);
+ BUG_ON(err);
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu, NULL);
- BUG_ON(notifier_rc != NOTIFY_DONE);
+ cpu_notifier_call_chain(cpu, CPU_DEAD, NULL, true);
send_global_virq(VIRQ_PCPU_STATE);
cpu_hotplug_done();
return 0;
fail:
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, hcpu, &nb);
- BUG_ON(notifier_rc != NOTIFY_DONE);
+ cpu_notifier_call_chain(cpu, CPU_DOWN_FAILED, &nb, true);
cpu_hotplug_done();
return err;
}
int cpu_up(unsigned int cpu)
{
- int notifier_rc, err = 0;
- void *hcpu = (void *)(long)cpu;
+ int err;
struct notifier_block *nb = NULL;
if ( !cpu_hotplug_begin() )
@@ -144,19 +148,15 @@ int cpu_up(unsigned int cpu)
return -EINVAL;
}
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, &nb);
- if ( notifier_rc != NOTIFY_DONE )
- {
- err = notifier_to_errno(notifier_rc);
+ err = cpu_notifier_call_chain(cpu, CPU_UP_PREPARE, &nb, false);
+ if ( err )
goto fail;
- }
err = __cpu_up(cpu);
if ( err < 0 )
goto fail;
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu, NULL);
- BUG_ON(notifier_rc != NOTIFY_DONE);
+ cpu_notifier_call_chain(cpu, CPU_ONLINE, NULL, true);
send_global_virq(VIRQ_PCPU_STATE);
@@ -164,18 +164,14 @@ int cpu_up(unsigned int cpu)
return 0;
fail:
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu, &nb);
- BUG_ON(notifier_rc != NOTIFY_DONE);
+ cpu_notifier_call_chain(cpu, CPU_UP_CANCELED, &nb, true);
cpu_hotplug_done();
return err;
}
void notify_cpu_starting(unsigned int cpu)
{
- void *hcpu = (void *)(long)cpu;
- int notifier_rc = notifier_call_chain(
- &cpu_chain, CPU_STARTING, hcpu, NULL);
- BUG_ON(notifier_rc != NOTIFY_DONE);
+ cpu_notifier_call_chain(cpu, CPU_STARTING, NULL, true);
}
static cpumask_t frozen_cpus;