Commit 14660b7e authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Thomas Gleixner

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: default avatarSebastian 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.deSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 9c6bafab
...@@ -59,26 +59,17 @@ static void nmi_timer_stop_cpu(int cpu) ...@@ -59,26 +59,17 @@ static void nmi_timer_stop_cpu(int cpu)
perf_event_disable(event); perf_event_disable(event);
} }
static int nmi_timer_cpu_notifier(struct notifier_block *b, unsigned long action, static int nmi_timer_cpu_online(unsigned int cpu)
void *data)
{ {
int cpu = (unsigned long)data;
switch (action) {
case CPU_DOWN_FAILED:
case CPU_ONLINE:
nmi_timer_start_cpu(cpu); nmi_timer_start_cpu(cpu);
break; return 0;
case CPU_DOWN_PREPARE: }
static int nmi_timer_cpu_predown(unsigned int cpu)
{
nmi_timer_stop_cpu(cpu); nmi_timer_stop_cpu(cpu);
break; return 0;
}
return NOTIFY_DONE;
} }
static struct notifier_block nmi_timer_cpu_nb = {
.notifier_call = nmi_timer_cpu_notifier
};
static int nmi_timer_start(void) static int nmi_timer_start(void)
{ {
int cpu; int cpu;
...@@ -103,13 +94,14 @@ static void nmi_timer_stop(void) ...@@ -103,13 +94,14 @@ static void nmi_timer_stop(void)
put_online_cpus(); put_online_cpus();
} }
static enum cpuhp_state hp_online;
static void nmi_timer_shutdown(void) static void nmi_timer_shutdown(void)
{ {
struct perf_event *event; struct perf_event *event;
int cpu; int cpu;
cpu_notifier_register_begin(); cpuhp_remove_state(hp_online);
__unregister_cpu_notifier(&nmi_timer_cpu_nb);
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
event = per_cpu(nmi_timer_events, cpu); event = per_cpu(nmi_timer_events, cpu);
if (!event) if (!event)
...@@ -118,13 +110,11 @@ static void nmi_timer_shutdown(void) ...@@ -118,13 +110,11 @@ static void nmi_timer_shutdown(void)
per_cpu(nmi_timer_events, cpu) = NULL; per_cpu(nmi_timer_events, cpu) = NULL;
perf_event_release_kernel(event); perf_event_release_kernel(event);
} }
cpu_notifier_register_done();
} }
static int nmi_timer_setup(void) static int nmi_timer_setup(void)
{ {
int cpu, err; int err;
u64 period; u64 period;
/* clock cycles per tick: */ /* clock cycles per tick: */
...@@ -132,24 +122,14 @@ static int nmi_timer_setup(void) ...@@ -132,24 +122,14 @@ static int nmi_timer_setup(void)
do_div(period, HZ); do_div(period, HZ);
nmi_timer_attr.sample_period = period; nmi_timer_attr.sample_period = period;
cpu_notifier_register_begin(); err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "oprofile/nmi:online",
err = __register_cpu_notifier(&nmi_timer_cpu_nb); nmi_timer_cpu_online, nmi_timer_cpu_predown);
if (err) if (err < 0) {
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(); nmi_timer_shutdown();
return err; return err;
} }
} hp_online = err;
return 0;
out:
cpu_notifier_register_done();
return err;
} }
int __init op_nmi_timer_init(struct oprofile_operations *ops) int __init op_nmi_timer_init(struct oprofile_operations *ops)
......
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