Commit b272f732 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'smp-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull SMP hotplug notifier removal from Thomas Gleixner:
 "This is the final cleanup of the hotplug notifier infrastructure. The
  series has been reintgrated in the last two days because there came a
  new driver using the old infrastructure via the SCSI tree.

  Summary:

   - convert the last leftover drivers utilizing notifiers

   - fixup for a completely broken hotplug user

   - prevent setup of already used states

   - removal of the notifiers

   - treewide cleanup of hotplug state names

   - consolidation of state space

  There is a sphinx based documentation pending, but that needs review
  from the documentation folks"

* 'smp-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  irqchip/armada-xp: Consolidate hotplug state space
  irqchip/gic: Consolidate hotplug state space
  coresight/etm3/4x: Consolidate hotplug state space
  cpu/hotplug: Cleanup state names
  cpu/hotplug: Remove obsolete cpu hotplug register/unregister functions
  staging/lustre/libcfs: Convert to hotplug state machine
  scsi/bnx2i: Convert to hotplug state machine
  scsi/bnx2fc: Convert to hotplug state machine
  cpu/hotplug: Prevent overwriting of callbacks
  x86/msr: Remove bogus cleanup from the error path
  bus: arm-ccn: Prevent hotplug callback leak
  perf/x86/intel/cstate: Prevent hotplug callback leak
  ARM/imx/mmcd: Fix broken cpu hotplug handling
  scsi: qedi: Convert to hotplug state machine
parents 10bbe759 008b69e4
......@@ -34,7 +34,7 @@ static int dummy_timer_starting_cpu(unsigned int cpu)
static int __init dummy_timer_register(void)
{
return cpuhp_setup_state(CPUHP_AP_DUMMY_TIMER_STARTING,
"AP_DUMMY_TIMER_STARTING",
"clockevents/dummy_timer:starting",
dummy_timer_starting_cpu, NULL);
}
early_initcall(dummy_timer_register);
......@@ -552,7 +552,7 @@ static int __init exynos4_timer_resources(struct device_node *np, void __iomem *
/* Install hotplug callbacks which configure the timer on this CPU */
err = cpuhp_setup_state(CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
"AP_EXYNOS4_MCT_TIMER_STARTING",
"clockevents/exynos4/mct_timer:starting",
exynos4_mct_starting_cpu,
exynos4_mct_dying_cpu);
if (err)
......
......@@ -240,7 +240,7 @@ static int __init jcore_pit_init(struct device_node *node)
}
cpuhp_setup_state(CPUHP_AP_JCORE_TIMER_STARTING,
"AP_JCORE_TIMER_STARTING",
"clockevents/jcore:starting",
jcore_pit_local_init, NULL);
return 0;
......
......@@ -154,6 +154,6 @@ int __init metag_generic_timer_init(void)
/* Hook cpu boot to configure the CPU's timers */
return cpuhp_setup_state(CPUHP_AP_METAG_TIMER_STARTING,
"AP_METAG_TIMER_STARTING",
"clockevents/metag:starting",
arch_timer_starting_cpu, NULL);
}
......@@ -120,8 +120,8 @@ static int gic_clockevent_init(void)
}
cpuhp_setup_state(CPUHP_AP_MIPS_GIC_TIMER_STARTING,
"AP_MIPS_GIC_TIMER_STARTING", gic_starting_cpu,
gic_dying_cpu);
"clockevents/mips/gic/timer:starting",
gic_starting_cpu, gic_dying_cpu);
return 0;
}
......
......@@ -182,7 +182,7 @@ static int __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
} else {
/* Install and invoke hotplug callbacks */
res = cpuhp_setup_state(CPUHP_AP_QCOM_TIMER_STARTING,
"AP_QCOM_TIMER_STARTING",
"clockevents/qcom/timer:starting",
msm_local_timer_starting_cpu,
msm_local_timer_dying_cpu);
if (res) {
......
......@@ -320,7 +320,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np)
}
res = cpuhp_setup_state(CPUHP_AP_ARMADA_TIMER_STARTING,
"AP_ARMADA_TIMER_STARTING",
"clockevents/armada:starting",
armada_370_xp_timer_starting_cpu,
armada_370_xp_timer_dying_cpu);
if (res) {
......
......@@ -221,7 +221,7 @@ static int __init sirfsoc_clockevent_init(void)
/* Install and invoke hotplug callbacks */
return cpuhp_setup_state(CPUHP_AP_MARCO_TIMER_STARTING,
"AP_MARCO_TIMER_STARTING",
"clockevents/marco:starting",
sirfsoc_local_timer_starting_cpu,
sirfsoc_local_timer_dying_cpu);
}
......
......@@ -804,10 +804,10 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
if (!etm_count++) {
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING,
"AP_ARM_CORESIGHT_STARTING",
"arm/coresight:starting",
etm_starting_cpu, etm_dying_cpu);
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
"AP_ARM_CORESIGHT_ONLINE",
"arm/coresight:online",
etm_online_cpu, NULL);
if (ret < 0)
goto err_arch_supported;
......
......@@ -986,11 +986,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
dev_err(dev, "ETM arch init failed\n");
if (!etm4_count++) {
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT4_STARTING,
"AP_ARM_CORESIGHT4_STARTING",
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING,
"arm/coresight4:starting",
etm4_starting_cpu, etm4_dying_cpu);
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
"AP_ARM_CORESIGHT4_ONLINE",
"arm/coresight4:online",
etm4_online_cpu, NULL);
if (ret < 0)
goto err_arch_supported;
......@@ -1037,7 +1037,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
err_arch_supported:
if (--etm4_count == 0) {
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT4_STARTING);
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
if (hp_online)
cpuhp_remove_state_nocalls(hp_online);
}
......
......@@ -578,13 +578,13 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
#ifdef CONFIG_SMP
set_smp_cross_call(armada_mpic_send_doorbell);
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_ARMADA_XP_STARTING,
"AP_IRQ_ARMADA_XP_STARTING",
"irqchip/armada/ipi:starting",
armada_xp_mpic_starting_cpu, NULL);
#endif
} else {
#ifdef CONFIG_SMP
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_ARMADA_CASC_STARTING,
"AP_IRQ_ARMADA_CASC_STARTING",
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_ARMADA_XP_STARTING,
"irqchip/armada/cascade:starting",
mpic_cascaded_starting_cpu, NULL);
#endif
irq_set_chained_handler(parent_irq,
......
......@@ -245,7 +245,7 @@ bcm2836_arm_irqchip_smp_init(void)
#ifdef CONFIG_SMP
/* Unmask IPIs to the boot CPU. */
cpuhp_setup_state(CPUHP_AP_IRQ_BCM2836_STARTING,
"AP_IRQ_BCM2836_STARTING", bcm2836_cpu_starting,
"irqchip/bcm2836:starting", bcm2836_cpu_starting,
bcm2836_cpu_dying);
set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
......
......@@ -632,9 +632,9 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
static void gic_smp_init(void)
{
set_smp_cross_call(gic_raise_softirq);
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GICV3_STARTING,
"AP_IRQ_GICV3_STARTING", gic_starting_cpu,
NULL);
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
"irqchip/arm/gicv3:starting",
gic_starting_cpu, NULL);
}
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
......
......@@ -1191,7 +1191,7 @@ static int __init __gic_init_bases(struct gic_chip_data *gic,
set_smp_cross_call(gic_raise_softirq);
#endif
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
"AP_IRQ_GIC_STARTING",
"irqchip/arm/gic:starting",
gic_starting_cpu, NULL);
set_handle_irq(gic_handle_irq);
if (static_key_true(&supports_deactivate))
......
......@@ -407,7 +407,7 @@ hip04_of_init(struct device_node *node, struct device_node *parent)
set_handle_irq(hip04_handle_irq);
hip04_irq_dist_init(&hip04_data);
cpuhp_setup_state(CPUHP_AP_IRQ_HIP04_STARTING, "AP_IRQ_HIP04_STARTING",
cpuhp_setup_state(CPUHP_AP_IRQ_HIP04_STARTING, "irqchip/hip04:starting",
hip04_irq_starting_cpu, NULL);
return 0;
}
......
......@@ -127,7 +127,7 @@ static int __init ledtrig_cpu_init(void)
register_syscore_ops(&ledtrig_cpu_syscore_ops);
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "AP_LEDTRIG_STARTING",
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "leds/trigger:starting",
ledtrig_online_cpu, ledtrig_prepare_down_cpu);
if (ret < 0)
pr_err("CPU hotplug notifier for ledtrig-cpu could not be registered: %d\n",
......
......@@ -2484,13 +2484,13 @@ static __init int virtio_net_driver_init(void)
{
int ret;
ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "AP_VIRT_NET_ONLINE",
ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "virtio/net:online",
virtnet_cpu_online,
virtnet_cpu_down_prep);
if (ret < 0)
goto out;
virtionet_online = ret;
ret = cpuhp_setup_state_multi(CPUHP_VIRT_NET_DEAD, "VIRT_NET_DEAD",
ret = cpuhp_setup_state_multi(CPUHP_VIRT_NET_DEAD, "virtio/net:dead",
NULL, virtnet_cpu_dead);
if (ret)
goto err_dead;
......
......@@ -1084,7 +1084,7 @@ static int arm_pmu_hp_init(void)
int ret;
ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_STARTING,
"AP_PERF_ARM_STARTING",
"perf/arm/pmu:starting",
arm_perf_starting_cpu, NULL);
if (ret)
pr_err("CPU hotplug notifier for ARM PMU could not be registered: %d\n",
......
......@@ -127,13 +127,6 @@ module_param_named(log_fka, bnx2fc_log_fka, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(log_fka, " Print message to kernel log when fcoe is "
"initiating a FIP keep alive when debug logging is enabled.");
static int bnx2fc_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu);
/* notification function for CPU hotplug events */
static struct notifier_block bnx2fc_cpu_notifier = {
.notifier_call = bnx2fc_cpu_callback,
};
static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport)
{
return ((struct bnx2fc_interface *)
......@@ -2622,37 +2615,19 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu)
kthread_stop(thread);
}
/**
* bnx2fc_cpu_callback - Handler for CPU hotplug events
*
* @nfb: The callback data block
* @action: The event triggering the callback
* @hcpu: The index of the CPU that the event is for
*
* This creates or destroys per-CPU data for fcoe
*
* Returns NOTIFY_OK always.
*/
static int bnx2fc_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
static int bnx2fc_cpu_online(unsigned int cpu)
{
unsigned cpu = (unsigned long)hcpu;
printk(PFX "CPU %x online: Create Rx thread\n", cpu);
bnx2fc_percpu_thread_create(cpu);
return 0;
}
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
printk(PFX "CPU %x online: Create Rx thread\n", cpu);
bnx2fc_percpu_thread_create(cpu);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
printk(PFX "CPU %x offline: Remove Rx thread\n", cpu);
bnx2fc_percpu_thread_destroy(cpu);
break;
default:
break;
}
return NOTIFY_OK;
static int bnx2fc_cpu_dead(unsigned int cpu)
{
printk(PFX "CPU %x offline: Remove Rx thread\n", cpu);
bnx2fc_percpu_thread_destroy(cpu);
return 0;
}
static int bnx2fc_slave_configure(struct scsi_device *sdev)
......@@ -2664,6 +2639,8 @@ static int bnx2fc_slave_configure(struct scsi_device *sdev)
return 0;
}
static enum cpuhp_state bnx2fc_online_state;
/**
* bnx2fc_mod_init - module init entry point
*
......@@ -2724,21 +2701,31 @@ static int __init bnx2fc_mod_init(void)
spin_lock_init(&p->fp_work_lock);
}
cpu_notifier_register_begin();
get_online_cpus();
for_each_online_cpu(cpu) {
for_each_online_cpu(cpu)
bnx2fc_percpu_thread_create(cpu);
}
/* Initialize per CPU interrupt thread */
__register_hotcpu_notifier(&bnx2fc_cpu_notifier);
rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
"scsi/bnx2fc:online",
bnx2fc_cpu_online, NULL);
if (rc < 0)
goto stop_threads;
bnx2fc_online_state = rc;
cpu_notifier_register_done();
cpuhp_setup_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD, "scsi/bnx2fc:dead",
NULL, bnx2fc_cpu_dead);
put_online_cpus();
cnic_register_driver(CNIC_ULP_FCOE, &bnx2fc_cnic_cb);
return 0;
stop_threads:
for_each_online_cpu(cpu)
bnx2fc_percpu_thread_destroy(cpu);
put_online_cpus();
kthread_stop(l2_thread);
free_wq:
destroy_workqueue(bnx2fc_wq);
release_bt:
......@@ -2797,16 +2784,16 @@ static void __exit bnx2fc_mod_exit(void)
if (l2_thread)
kthread_stop(l2_thread);
cpu_notifier_register_begin();
get_online_cpus();
/* Destroy per cpu threads */
for_each_online_cpu(cpu) {
bnx2fc_percpu_thread_destroy(cpu);
}
__unregister_hotcpu_notifier(&bnx2fc_cpu_notifier);
cpuhp_remove_state_nocalls(bnx2fc_online_state);
cpuhp_remove_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD);
cpu_notifier_register_done();
put_online_cpus();
destroy_workqueue(bnx2fc_wq);
/*
......
......@@ -70,14 +70,6 @@ u64 iscsi_error_mask = 0x00;
DEFINE_PER_CPU(struct bnx2i_percpu_s, bnx2i_percpu);
static int bnx2i_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu);
/* notification function for CPU hotplug events */
static struct notifier_block bnx2i_cpu_notifier = {
.notifier_call = bnx2i_cpu_callback,
};
/**
* bnx2i_identify_device - identifies NetXtreme II device type
* @hba: Adapter structure pointer
......@@ -461,41 +453,21 @@ static void bnx2i_percpu_thread_destroy(unsigned int cpu)
kthread_stop(thread);
}
/**
* bnx2i_cpu_callback - Handler for CPU hotplug events
*
* @nfb: The callback data block
* @action: The event triggering the callback
* @hcpu: The index of the CPU that the event is for
*
* This creates or destroys per-CPU data for iSCSI
*
* Returns NOTIFY_OK always.
*/
static int bnx2i_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
static int bnx2i_cpu_online(unsigned int cpu)
{
unsigned cpu = (unsigned long)hcpu;
pr_info("bnx2i: CPU %x online: Create Rx thread\n", cpu);
bnx2i_percpu_thread_create(cpu);
return 0;
}
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
printk(KERN_INFO "bnx2i: CPU %x online: Create Rx thread\n",
cpu);
bnx2i_percpu_thread_create(cpu);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
printk(KERN_INFO "CPU %x offline: Remove Rx thread\n", cpu);
bnx2i_percpu_thread_destroy(cpu);
break;
default:
break;
}
return NOTIFY_OK;
static int bnx2i_cpu_dead(unsigned int cpu)
{
pr_info("CPU %x offline: Remove Rx thread\n", cpu);
bnx2i_percpu_thread_destroy(cpu);
return 0;
}
static enum cpuhp_state bnx2i_online_state;
/**
* bnx2i_mod_init - module init entry point
......@@ -539,18 +511,28 @@ static int __init bnx2i_mod_init(void)
p->iothread = NULL;
}
cpu_notifier_register_begin();
get_online_cpus();
for_each_online_cpu(cpu)
bnx2i_percpu_thread_create(cpu);
/* Initialize per CPU interrupt thread */
__register_hotcpu_notifier(&bnx2i_cpu_notifier);
cpu_notifier_register_done();
err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
"scsi/bnx2i:online",
bnx2i_cpu_online, NULL);
if (err < 0)
goto remove_threads;
bnx2i_online_state = err;
cpuhp_setup_state_nocalls(CPUHP_SCSI_BNX2I_DEAD, "scsi/bnx2i:dead",
NULL, bnx2i_cpu_dead);
put_online_cpus();
return 0;
remove_threads:
for_each_online_cpu(cpu)
bnx2i_percpu_thread_destroy(cpu);
put_online_cpus();
cnic_unregister_driver(CNIC_ULP_ISCSI);
unreg_xport:
iscsi_unregister_transport(&bnx2i_iscsi_transport);
out:
......@@ -587,14 +569,14 @@ static void __exit bnx2i_mod_exit(void)
}
mutex_unlock(&bnx2i_dev_lock);
cpu_notifier_register_begin();
get_online_cpus();
for_each_online_cpu(cpu)
bnx2i_percpu_thread_destroy(cpu);
__unregister_hotcpu_notifier(&bnx2i_cpu_notifier);
cpu_notifier_register_done();
cpuhp_remove_state_nocalls(bnx2i_online_state);
cpuhp_remove_state_nocalls(CPUHP_SCSI_BNX2I_DEAD);
put_online_cpus();
iscsi_unregister_transport(&bnx2i_iscsi_transport);
cnic_unregister_driver(CNIC_ULP_ISCSI);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment