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 <writer/swap_writer_module.h>
40 #include "swap_sampler_module.h"
41 #include "swap_sampler_errors.h"
42 #include "kernel_operations.h"
43 #include "sampler_timers.h"
46 static BLOCKING_NOTIFIER_HEAD(swap_sampler_notifier_list);
48 static restart_ret swap_timer_restart(swap_timer *timer)
51 sample_msg(task_pt_regs(current));
53 return sampler_timers_restart(timer);
56 static int swap_timer_start(void)
59 sampler_timers_set_run();
61 on_each_cpu(sampler_timers_start, swap_timer_restart, 1);
67 static void swap_timer_stop(void)
73 for_each_online_cpu(cpu)
74 sampler_timers_stop(cpu);
75 sampler_timers_set_stop();
79 static int __cpuinit swap_cpu_notify(struct notifier_block *self,
80 unsigned long action, void *hcpu)
82 long cpu = (long) hcpu;
86 case CPU_ONLINE_FROZEN:
87 smp_call_function_single(cpu, sampler_timers_start,
88 swap_timer_restart, 1);
92 sampler_timers_stop(cpu);
99 static struct notifier_block __refdata swap_cpu_notifier = {
100 .notifier_call = swap_cpu_notify,
103 static int do_swap_sampler_start(unsigned int timer_quantum)
105 if (timer_quantum <= 0)
108 sampler_timers_set_quantum(timer_quantum);
114 static void do_swap_sampler_stop(void)
119 static DEFINE_MUTEX(mutex_run);
120 static int sampler_run = 0;
124 * @brief Starts sampling with specified timer quantum.
126 * @param timer_quantum Timer quantum for sampling.
127 * @return 0 on success, error code on error.
129 int swap_sampler_start(unsigned int timer_quantum)
133 mutex_lock(&mutex_run);
135 printk("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("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.");