Skip to content

Commit

Permalink
x86/hpet: Convert to hotplug state machine
Browse files Browse the repository at this point in the history
Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160713153335.279718463@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Sebastian Andrzej Siewior authored and Ingo Molnar committed Jul 14, 2016
1 parent 7ee681b commit 48d7f6c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 35 deletions.
69 changes: 34 additions & 35 deletions arch/x86/kernel/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,31 +710,29 @@ static void hpet_work(struct work_struct *w)
complete(&hpet_work->complete);
}

static int hpet_cpuhp_notify(struct notifier_block *n,
unsigned long action, void *hcpu)
static int hpet_cpuhp_online(unsigned int cpu)
{
unsigned long cpu = (unsigned long)hcpu;
struct hpet_work_struct work;

INIT_DELAYED_WORK_ONSTACK(&work.work, hpet_work);
init_completion(&work.complete);
/* FIXME: add schedule_work_on() */
schedule_delayed_work_on(cpu, &work.work, 0);
wait_for_completion(&work.complete);
destroy_delayed_work_on_stack(&work.work);
return 0;
}

static int hpet_cpuhp_dead(unsigned int cpu)
{
struct hpet_dev *hdev = per_cpu(cpu_hpet_dev, cpu);

switch (action & ~CPU_TASKS_FROZEN) {
case CPU_ONLINE:
INIT_DELAYED_WORK_ONSTACK(&work.work, hpet_work);
init_completion(&work.complete);
/* FIXME: add schedule_work_on() */
schedule_delayed_work_on(cpu, &work.work, 0);
wait_for_completion(&work.complete);
destroy_delayed_work_on_stack(&work.work);
break;
case CPU_DEAD:
if (hdev) {
free_irq(hdev->irq, hdev);
hdev->flags &= ~HPET_DEV_USED;
per_cpu(cpu_hpet_dev, cpu) = NULL;
}
break;
}
return NOTIFY_OK;
if (!hdev)
return 0;
free_irq(hdev->irq, hdev);
hdev->flags &= ~HPET_DEV_USED;
per_cpu(cpu_hpet_dev, cpu) = NULL;
return 0;
}
#else

Expand All @@ -750,11 +748,8 @@ static void hpet_reserve_msi_timers(struct hpet_data *hd)
}
#endif

static int hpet_cpuhp_notify(struct notifier_block *n,
unsigned long action, void *hcpu)
{
return NOTIFY_OK;
}
#define hpet_cpuhp_online NULL
#define hpet_cpuhp_dead NULL

#endif

Expand Down Expand Up @@ -931,7 +926,7 @@ int __init hpet_enable(void)
*/
static __init int hpet_late_init(void)
{
int cpu;
int ret;

if (boot_hpet_disable)
return -ENODEV;
Expand Down Expand Up @@ -961,16 +956,20 @@ static __init int hpet_late_init(void)
if (boot_cpu_has(X86_FEATURE_ARAT))
return 0;

cpu_notifier_register_begin();
for_each_online_cpu(cpu) {
hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
}

/* This notifier should be called after workqueue is ready */
__hotcpu_notifier(hpet_cpuhp_notify, -20);
cpu_notifier_register_done();

ret = cpuhp_setup_state(CPUHP_AP_X86_HPET_ONLINE, "AP_X86_HPET_ONLINE",
hpet_cpuhp_online, NULL);
if (ret)
return ret;
ret = cpuhp_setup_state(CPUHP_X86_HPET_DEAD, "X86_HPET_DEAD", NULL,
hpet_cpuhp_dead);
if (ret)
goto err_cpuhp;
return 0;

err_cpuhp:
cpuhp_remove_state(CPUHP_AP_X86_HPET_ONLINE);
return ret;
}
fs_initcall(hpet_late_init);

Expand Down
2 changes: 2 additions & 0 deletions include/linux/cpuhotplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum cpuhp_state {
CPUHP_PERF_BFIN,
CPUHP_PERF_POWER,
CPUHP_PERF_SUPERH,
CPUHP_X86_HPET_DEAD,
CPUHP_WORKQUEUE_PREP,
CPUHP_NOTIFY_PREPARE,
CPUHP_BRINGUP_CPU,
Expand Down Expand Up @@ -54,6 +55,7 @@ enum cpuhp_state {
CPUHP_AP_NOTIFY_ONLINE,
CPUHP_AP_ONLINE_DYN,
CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30,
CPUHP_AP_X86_HPET_ONLINE,
CPUHP_AP_ACTIVE,
CPUHP_ONLINE,
};
Expand Down

0 comments on commit 48d7f6c

Please sign in to comment.