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:
parent
9c6bafab03
commit
14660b7ea3
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue