oprofile/nmi timer: Convert to hotplug state machine

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>
Cc: oprofile-list@lists.sf.net
Cc: Robert Richter <rric@kernel.org>
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20161126231350.10321-6-bigeasy@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Sebastian Andrzej Siewior 2016-11-27 00:13:33 +01:00 committed by Thomas Gleixner
parent 9c6bafab03
commit 14660b7ea3
1 changed files with 19 additions and 39 deletions

View File

@ -59,25 +59,16 @@ static void nmi_timer_stop_cpu(int cpu)
perf_event_disable(event);
}
static int nmi_timer_cpu_notifier(struct notifier_block *b, unsigned long action,
void *data)
static int nmi_timer_cpu_online(unsigned int cpu)
{
int cpu = (unsigned long)data;
switch (action) {
case CPU_DOWN_FAILED:
case CPU_ONLINE:
nmi_timer_start_cpu(cpu);
break;
case CPU_DOWN_PREPARE:
nmi_timer_stop_cpu(cpu);
break;
}
return NOTIFY_DONE;
nmi_timer_start_cpu(cpu);
return 0;
}
static int nmi_timer_cpu_predown(unsigned int cpu)
{
nmi_timer_stop_cpu(cpu);
return 0;
}
static struct notifier_block nmi_timer_cpu_nb = {
.notifier_call = nmi_timer_cpu_notifier
};
static int nmi_timer_start(void)
{
@ -103,13 +94,14 @@ static void nmi_timer_stop(void)
put_online_cpus();
}
static enum cpuhp_state hp_online;
static void nmi_timer_shutdown(void)
{
struct perf_event *event;
int cpu;
cpu_notifier_register_begin();
__unregister_cpu_notifier(&nmi_timer_cpu_nb);
cpuhp_remove_state(hp_online);
for_each_possible_cpu(cpu) {
event = per_cpu(nmi_timer_events, cpu);
if (!event)
@ -118,13 +110,11 @@ static void nmi_timer_shutdown(void)
per_cpu(nmi_timer_events, cpu) = NULL;
perf_event_release_kernel(event);
}
cpu_notifier_register_done();
}
static int nmi_timer_setup(void)
{
int cpu, err;
int err;
u64 period;
/* clock cycles per tick: */
@ -132,24 +122,14 @@ static int nmi_timer_setup(void)
do_div(period, HZ);
nmi_timer_attr.sample_period = period;
cpu_notifier_register_begin();
err = __register_cpu_notifier(&nmi_timer_cpu_nb);
if (err)
goto out;
/* can't attach events to offline cpus: */
for_each_online_cpu(cpu) {
err = nmi_timer_start_cpu(cpu);
if (err) {
cpu_notifier_register_done();
nmi_timer_shutdown();
return err;
}
err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "oprofile/nmi:online",
nmi_timer_cpu_online, nmi_timer_cpu_predown);
if (err < 0) {
nmi_timer_shutdown();
return err;
}
out:
cpu_notifier_register_done();
return err;
hp_online = err;
return 0;
}
int __init op_nmi_timer_init(struct oprofile_operations *ops)