Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

oprofile/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.
Since the online target runs always on the target CPU we can drop
smp_call_function_single(). The functions is invoked with interrupts off to
keep the old calling convention. If the maintainer things that this function
can be called with interrupts enabled then it can be removed :)

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Robert Richter <rric@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: oprofile-list@lists.sf.net
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160906170457.32393-10-bigeasy@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Sebastian Andrzej Siewior and committed by
Thomas Gleixner
a4e0591e 9a659f43

+23 -21
+23 -21
drivers/oprofile/timer_int.c
··· 74 74 put_online_cpus(); 75 75 } 76 76 77 - static int oprofile_cpu_notify(struct notifier_block *self, 78 - unsigned long action, void *hcpu) 77 + static int oprofile_timer_online(unsigned int cpu) 79 78 { 80 - long cpu = (long) hcpu; 81 - 82 - switch (action) { 83 - case CPU_ONLINE: 84 - case CPU_ONLINE_FROZEN: 85 - smp_call_function_single(cpu, __oprofile_hrtimer_start, 86 - NULL, 1); 87 - break; 88 - case CPU_DEAD: 89 - case CPU_DEAD_FROZEN: 90 - __oprofile_hrtimer_stop(cpu); 91 - break; 92 - } 93 - return NOTIFY_OK; 79 + local_irq_disable(); 80 + __oprofile_hrtimer_start(NULL); 81 + local_irq_enable(); 82 + return 0; 94 83 } 95 84 96 - static struct notifier_block __refdata oprofile_cpu_notifier = { 97 - .notifier_call = oprofile_cpu_notify, 98 - }; 85 + static int oprofile_timer_prep_down(unsigned int cpu) 86 + { 87 + __oprofile_hrtimer_stop(cpu); 88 + return 0; 89 + } 90 + 91 + static enum cpuhp_state hp_online; 99 92 100 93 static int oprofile_hrtimer_setup(void) 101 94 { 102 - return register_hotcpu_notifier(&oprofile_cpu_notifier); 95 + int ret; 96 + 97 + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, 98 + "oprofile/timer:online", 99 + oprofile_timer_online, 100 + oprofile_timer_prep_down); 101 + if (ret < 0) 102 + return ret; 103 + hp_online = ret; 104 + return 0; 103 105 } 104 106 105 107 static void oprofile_hrtimer_shutdown(void) 106 108 { 107 - unregister_hotcpu_notifier(&oprofile_cpu_notifier); 109 + cpuhp_remove_state_nocalls(hp_online); 108 110 } 109 111 110 112 int oprofile_timer_init(struct oprofile_operations *ops)