summaryrefslogtreecommitdiffstats
path: root/drivers/oprofile
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-11-26 18:13:33 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-12-01 18:52:34 -0500
commit14660b7ea3ca628410bb999d53926ca77973892b (patch)
treeb90ee3b6578ef63ce61a0283ec3d607f71cff028 /drivers/oprofile
parent9c6bafab03dec222237b6eb8b5adf5c18ec76264 (diff)
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>
Diffstat (limited to 'drivers/oprofile')
-rw-r--r--drivers/oprofile/nmi_timer_int.c58
1 files changed, 19 insertions, 39 deletions
diff --git a/drivers/oprofile/nmi_timer_int.c b/drivers/oprofile/nmi_timer_int.c
index 9559829fb234..e65a576e4032 100644
--- a/drivers/oprofile/nmi_timer_int.c
+++ b/drivers/oprofile/nmi_timer_int.c
@@ -59,25 +59,16 @@ static void nmi_timer_stop_cpu(int cpu)
59 perf_event_disable(event); 59 perf_event_disable(event);
60} 60}
61 61
62static int nmi_timer_cpu_notifier(struct notifier_block *b, unsigned long action, 62static int nmi_timer_cpu_online(unsigned int cpu)
63 void *data)
64{ 63{
65 int cpu = (unsigned long)data; 64 nmi_timer_start_cpu(cpu);
66 switch (action) { 65 return 0;
67 case CPU_DOWN_FAILED: 66}
68 case CPU_ONLINE: 67static int nmi_timer_cpu_predown(unsigned int cpu)
69 nmi_timer_start_cpu(cpu); 68{
70 break; 69 nmi_timer_stop_cpu(cpu);
71 case CPU_DOWN_PREPARE: 70 return 0;
72 nmi_timer_stop_cpu(cpu);
73 break;
74 }
75 return NOTIFY_DONE;
76} 71}
77
78static struct notifier_block nmi_timer_cpu_nb = {
79 .notifier_call = nmi_timer_cpu_notifier
80};
81 72
82static int nmi_timer_start(void) 73static int nmi_timer_start(void)
83{ 74{
@@ -103,13 +94,14 @@ static void nmi_timer_stop(void)
103 put_online_cpus(); 94 put_online_cpus();
104} 95}
105 96
97static enum cpuhp_state hp_online;
98
106static void nmi_timer_shutdown(void) 99static void nmi_timer_shutdown(void)
107{ 100{
108 struct perf_event *event; 101 struct perf_event *event;
109 int cpu; 102 int cpu;
110 103
111 cpu_notifier_register_begin(); 104 cpuhp_remove_state(hp_online);
112 __unregister_cpu_notifier(&nmi_timer_cpu_nb);
113 for_each_possible_cpu(cpu) { 105 for_each_possible_cpu(cpu) {
114 event = per_cpu(nmi_timer_events, cpu); 106 event = per_cpu(nmi_timer_events, cpu);
115 if (!event) 107 if (!event)
@@ -118,13 +110,11 @@ static void nmi_timer_shutdown(void)
118 per_cpu(nmi_timer_events, cpu) = NULL; 110 per_cpu(nmi_timer_events, cpu) = NULL;
119 perf_event_release_kernel(event); 111 perf_event_release_kernel(event);
120 } 112 }
121
122 cpu_notifier_register_done();
123} 113}
124 114
125static int nmi_timer_setup(void) 115static int nmi_timer_setup(void)
126{ 116{
127 int cpu, err; 117 int err;
128 u64 period; 118 u64 period;
129 119
130 /* clock cycles per tick: */ 120 /* clock cycles per tick: */
@@ -132,24 +122,14 @@ static int nmi_timer_setup(void)
132 do_div(period, HZ); 122 do_div(period, HZ);
133 nmi_timer_attr.sample_period = period; 123 nmi_timer_attr.sample_period = period;
134 124
135 cpu_notifier_register_begin(); 125 err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "oprofile/nmi:online",
136 err = __register_cpu_notifier(&nmi_timer_cpu_nb); 126 nmi_timer_cpu_online, nmi_timer_cpu_predown);
137 if (err) 127 if (err < 0) {
138 goto out; 128 nmi_timer_shutdown();
139 129 return err;
140 /* can't attach events to offline cpus: */
141 for_each_online_cpu(cpu) {
142 err = nmi_timer_start_cpu(cpu);
143 if (err) {
144 cpu_notifier_register_done();
145 nmi_timer_shutdown();
146 return err;
147 }
148 } 130 }
149 131 hp_online = err;
150out: 132 return 0;
151 cpu_notifier_register_done();
152 return err;
153} 133}
154 134
155int __init op_nmi_timer_init(struct oprofile_operations *ops) 135int __init op_nmi_timer_init(struct oprofile_operations *ops)