2 * sampler/swap_sampler_module.c
3 * @author Andreev S.V.: SWAP Sampler implementation
4 * @author Alexander Aksenov <a.aksenov@samsung.com>: SWAP sampler porting
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * Copyright (C) Samsung Electronics, 2013
26 * @section DESCRIPTION
28 * Timer-based sampling module.
31 #include <asm/ptrace.h>
32 #include <linux/jiffies.h>
33 #include <linux/sched.h>
34 #include <linux/notifier.h>
35 #include <linux/cpu.h>
36 #include <linux/module.h>
38 #include "swap_sampler_module.h"
39 #include "swap_sampler_errors.h"
40 #include "kernel_operations.h"
41 #include "sampler_timers.h"
44 static BLOCKING_NOTIFIER_HEAD(swap_sampler_notifier_list);
45 static swap_sample_cb_t sampler_cb;
47 static restart_ret swap_timer_restart(swap_timer *timer)
49 sampler_cb(task_pt_regs(current));
51 return sampler_timers_restart(timer);
54 static int swap_timer_start(void)
57 sampler_timers_set_run();
59 on_each_cpu(sampler_timers_start, swap_timer_restart, 1);
65 static void swap_timer_stop(void)
71 for_each_online_cpu(cpu)
72 sampler_timers_stop(cpu);
73 sampler_timers_set_stop();
77 static int __cpuinit swap_cpu_notify(struct notifier_block *self,
78 unsigned long action, void *hcpu)
80 long cpu = (long) hcpu;
84 case CPU_ONLINE_FROZEN:
85 smp_call_function_single(cpu, sampler_timers_start,
86 swap_timer_restart, 1);
90 sampler_timers_stop(cpu);
97 static struct notifier_block __refdata swap_cpu_notifier = {
98 .notifier_call = swap_cpu_notify,
101 static int do_swap_sampler_start(unsigned int timer_quantum)
103 if (timer_quantum <= 0)
106 sampler_timers_set_quantum(timer_quantum);
112 static void do_swap_sampler_stop(void)
117 static DEFINE_MUTEX(mutex_run);
118 static int sampler_run;
122 * @brief Starts sampling with specified timer quantum.
124 * @param timer_quantum Timer quantum for sampling.
125 * @return 0 on success, error code on error.
127 int swap_sampler_start(unsigned int timer_quantum, swap_sample_cb_t cb)
131 mutex_lock(&mutex_run);
133 printk(KERN_INFO "sampler profiling is already run!\n");
139 ret = do_swap_sampler_start(timer_quantum);
144 mutex_unlock(&mutex_run);
148 EXPORT_SYMBOL_GPL(swap_sampler_start);
152 * @brief Stops sampling.
154 * @return 0 on success, error code on error.
156 int swap_sampler_stop(void)
160 mutex_lock(&mutex_run);
161 if (sampler_run == 0) {
162 printk(KERN_INFO "energy profiling is not running!\n");
167 do_swap_sampler_stop();
171 mutex_unlock(&mutex_run);
175 EXPORT_SYMBOL_GPL(swap_sampler_stop);
177 static int __init sampler_init(void)
181 retval = register_hotcpu_notifier(&swap_cpu_notifier);
183 print_err("Error of register_hotcpu_notifier()\n");
187 print_msg("Sample ininitialization success\n");
192 static void __exit sampler_exit(void)
195 do_swap_sampler_stop();
197 unregister_hotcpu_notifier(&swap_cpu_notifier);
199 print_msg("Sampler uninitialized\n");
202 module_init(sampler_init);
203 module_exit(sampler_exit);
205 MODULE_LICENSE("GPL");
206 MODULE_DESCRIPTION("SWAP sampling module");
207 MODULE_AUTHOR("Andreev S.V., Aksenov A.S.");