mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 16:53:54 +08:00
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);
|
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;
|
nmi_timer_start_cpu(cpu);
|
||||||
switch (action) {
|
return 0;
|
||||||
case CPU_DOWN_FAILED:
|
}
|
||||||
case CPU_ONLINE:
|
static int nmi_timer_cpu_predown(unsigned int cpu)
|
||||||
nmi_timer_start_cpu(cpu);
|
{
|
||||||
break;
|
nmi_timer_stop_cpu(cpu);
|
||||||
case CPU_DOWN_PREPARE:
|
return 0;
|
||||||
nmi_timer_stop_cpu(cpu);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -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)
|
|||||||
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)
|
|||||||
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;
|
nmi_timer_shutdown();
|
||||||
|
return err;
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
hp_online = err;
|
||||||
out:
|
return 0;
|
||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user